/*
 *	aegis - project change supervisor
 *	Copyright (C) 1991-1997, 1999, 2001-2006, 2008 Peter Miller
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 3 of the License, or
 *	(at your option) any later version.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program. If not, see
 *	<http://www.gnu.org/licenses/>.
 *
 * if you cange this file, don't forget to change
 *	man5/aecstate.5
 *
 * If you change this file, remmeber to make top-level enums
 * hide_if_default whenever possible, or you will break older versions of
 * aedist for receive.
 */

#include <libaegis/cattr.def>

state =
(
    /*
     * The change has been created,
     * but has yet to be worked on.
     */
    awaiting_development,

    /*
     * The change is being developed.
     */
    being_developed,

    /*
     * The change has been developed,
     * and is waiting to be reviewed.
     * (Optional, controlled by pattr::develop_end_action field)
     */
    awaiting_review,

    /*
     * The change has been developed,
     * and is being reviewed.
     * (Optional, controlled by pattr::develop_end_action field)
     */
    being_reviewed,

    /*
     * The change has passed review,
     * and is queued ready for integration.
     */
    awaiting_integration,

    /*
     * The change is being integrated.
     */
    being_integrated,

    /*
     * The change has been completed and is now
     * part of the baseline.
     * Changes in this state can not be reversed.
     */
    completed
);

/*
 * This field is the value of test_exemption (see libaegis/cattr.def)
 * when the change was created.
 */
given_test_exemption = boolean hide_if_default;

/*
 * This field is the value of regression_test_exemption (see
 * libaegis/cattr.def) when the change was created.
 */
given_regression_test_exemption = boolean hide_if_default;

/*
 * This field records the delta number for this change.
 * It is only present if the change is in one of
 * the 'being_integrated' or 'completed' states.
 */
delta_number = integer;

/*
 * This field records a universally unique identifier for this
 * configuration.  It is supplements the delta_number field in that
 * it is unique across all replicas of the project, whereas the delta
 * number is ambiguous across replicas.  It is only present in the
 * 'being_integrated' and 'completed' states.
 */
delta_uuid = string;

/*
 * This field records whether the change was placed into the
 * 'being_integrated'  state using the -minimum option (or that option was
 * implicitly set due to a file being removed).  It is
 * only present if the change is in the 'being_integrated' state.
 */
minimum_integration = boolean hide_if_default;

/*
 * This field records the last change integrated into the project.
 * If it disagrees with the project, a 'project_file_command' (from pconf)
 * needs to be executed at the next build.
 */
project_file_command_sync = integer;

/*
 * This field records the time the last successful
 * 'aegis -Build' command was run for all architectures.
 * It is only present in the 'being_developed' and 'being_integrated' states.
 */
build_time = time;

/*
 * This field records the time the last successful
 * 'aegis -Test' command was run for all architectures.
 * It is only present in the 'being_developed' and 'being_integrated' states.
 */
test_time = time;

/*
 * This field records the time the last successful
 * 'aegis -Test -BaseLine' command was run for all architectures.
 * It is only present in the 'being_developed' and 'being_integrated' states.
 */
test_baseline_time = time;

/*
 * This field records the time the last successful
 * 'aegis -Test -Regression' command was run for all architectures.
 * It is only present in the 'being_developed' and 'being_integrated' states.
 */
regression_test_time = time;

/*
 * This field records the time of various operations for each variant named
 * in the "architecture" field.
 * It is only present in the 'being_developed' and 'being_integrated' states.
 */
architecture_times =
[
    {
	/*
	 * This field is one of the patterns named in
	 * the outer "architecture" field.
	 */
	variant = string;

	/*
	 * This field is the computer on which the command was run
	 * which last changed this structure.
	 */
	node = string;

	/*
	 * This field records the last time the last
	 * successful 'aegis -Build' command
	 * was run for this specific architecture variant.
	 */
	build_time = time;

	/*
	 * This field records the last time the last
	 * successful 'aegis -Test' command
	 * was run for this specific architecture variant.
	 */
	test_time = time;

	/*
	 * This field records the last time the last
	 * successful 'aegis -Test -BaseLine' command
	 * was run for this specific architecture variant.
	 */
	test_baseline_time = time;

	/*
	 * This field records the last time the last
	 * successful 'aegis -Test -REGression' command
	 * was run for this specific architecture variant.
	 */
	regression_test_time = time;
    }
];

/*
 * This field is the absolute path of the change's development directory.
 * It is only present of the change is in a state
 * between 'being_developed' and 'being_integrated' inclusive.
 *
 * However, branches are treated slightly differently to changes.
 * The directory is relative to the root of the project tree, in order to
 * facilitate moving the project without rewriting any of the database.
 */
development_directory = string;

/*
 * This field is the absolute path of the change's integration directory.
 * It is only present of the change is in the 'being_integrated' state.
 */
integration_directory = string;

/*
 * This field records the history of the change,
 * in the form of state transitions.
 */
history =
[
    {
	/*
	 * This field records the time the state transition occured.
	 */
	when = time;

	/*
	 * This field records what happened.
	 * Valid value names echo the various aegis functions.
	 */
	what =
	(
		new_change,

		/*
                 * The change is advanced from awaiting_development to
                 * being_developed.
		 */
		develop_begin,

		/*
                 * The change is un-advanced from being_developed to
                 * awaiting_development.
		 */
		develop_begin_undo,

		/*
                 * The change is advanced from being_developed
                 * to being_reviewed.  The project is in
                 * goto_being_reviewed (the default).  The absence of
                 * the "_2br" suffix is an historical accident.
		 */
		develop_end,

		/*
                 * The change is advanced from being_developed
                 * to awaiting_review.  The project is in
                 * goto_awaiting_review.
		 */
		develop_end_2ar,

		/*
                 * The change is advanced from being_developed
                 * to awaiting_integration.  The project is in
                 * goto_awaiting_integration.
		 */
		develop_end_2ai,

		/*
                 * The change is un-advanced from one of
                 * { awating_review, being_reviewed or
                 * awaiting_integration } to being_developed.
		 */
		develop_end_undo,

		/*
                 * The change is advanced from awaiting_review
                 * to being_reviewed.  The project was in
                 * goto_awaiting_review.
		 */
		review_begin,

		/*
                 * The change is un-advanced from being_reviewed
                 * to awaiting_review.  The project was in
                 * goto_awaiting_review.
		 */
		review_begin_undo,

		/*
                 * The change advanced from being_reviewed
                 * to being_integrated.  The project is in
                 * goto_being_reviewed or goto_awaiting_review.
		 */
		review_pass,

		/*
                 * The change DID NOT advance from being_reviewed to being_
                 * integrated.  The project is in goto_awaiting_review.
                 *
                 * This will only happen if the review_policy command
                 * returns a non-zero exit status.
		 */
		review_pass_2ar,

		/*
                 * The change DID NOT advance from being_reviewed to being_
                 * integrated.  The project is in goto_being_reviewed.
                 *
                 * This will only happen if the review_policy command
                 * returns a non-zero exit status.
		 */
		review_pass_2br,

		/*
                 * The change un-advanced from awaiting_integration
                 * to being_reviewed.  The project is in
                 * goto_being_reviewed.  (The absence of the "_2br"
                 * suffix is an historical accident.)
		 */
		review_pass_undo,

		/*
                 * The change un-advanced from awaiting_integration
                 * to awaiting_review.  The project is in
                 * goto_awaiting_review.
		 */
		review_pass_undo_2ar,

		/*
                 * The change is un-advanced from being_reviewed to
                 * being_developed.
		 */
		review_fail,

		/*
                 * The change is advanced from awaiting_integration to
                 * being_integrated.
		 */
		integrate_begin,

		/*
                 * The change is un-advanced from being_integrated to
                 * awaiting_intergation.
		 */
		integrate_begin_undo,

		/*
                 * The change is advanced from being_integrated to
                 * completed.
		 */
		integrate_pass,

		/*
                 * The change is un-advanced from being_integrated to
                 * being_developed.
		 */
		integrate_fail
	);

	/*
	 * This field records the user name of the user who
	 * caused the state transition.
	 */
	who = string; /* the user name */

	/*
	 * This field is optional.
	 * It is a comment of some sort.
	 * In the cause of review_file and integrate_fail,
	 * this field will contain why the change failed.
	 */
	why = string;
    }
];

/*
 * This field provides a globally unique identifier for the change set,
 * even when geographically distributed development is happening.
 */
uuid = string;

/*
 * This field is only present in branch changes (long transactions).
 */
branch =
{
    /*
     * File permission mode mask.  See umask(2) for more
     * information.  This value will always be OR'ed with 022,
     * because aegis is paranoid.
     */
    umask = integer;

    /*
     * If this field is true, then a developer may review her own
     * change.  This is probably only a good idea for projects of
     * less than 3 people.  The idea is for as many people as
     * possible to critically examine a change.
     */
    developer_may_review = boolean;

    /*
     * If this field is true, then a developer may integrate her own
     * change.  This is probably only a good idea for projects of
     * less than 3 people.  The idea is for as many people as
     * possible to critically examine a change.
     */
    developer_may_integrate = boolean;

    /*
     * If this field is true, then a reviewer may integrate a change
     * she reviewed.  This is probably only a good idea for projects
     * of less than 3 people.  The idea is for as many people as
     * possible to critically examine a change.
     */
    reviewer_may_integrate = boolean;

    /*
     * This field is true if developers may created changes, in
     * addition to administrators.  This tends to be a very useful
     * thing, since developers find most of the bugs.
     */
    developers_may_create_changes = boolean;

    /*
     * This command is used to notify a developer that a change
     * requires developing; it is issued when a project
     * administrator uses an 'aedb -User' command to force
     * development of a change by a specific user.  All of the
     * substitutions described in aesub(5) are available.  This
     * field is optional.
     *
     * Executed as: the new developer.
     * Current directory: the development directory of the change
     *	for the new developer.
     * Exit status: ignored.
     */
    forced_develop_begin_notify_command = string;

    /*
     * Notify that a change requires reviewing All of the
     * substitutions described in aesub(5) are available.  This
     * field is optional.
     *
     * This command could also be used to notify other management
     * systems, such as progress and defect tracking.
     *
     * Executed as: the developer.
     * Current directory: the development directory of the change.
     * Exit status: ignored.
     */
    develop_end_notify_command = string;

    /*
     * Notify that a change has been withdrawn from review for
     * further development.  All of the substitutions described in
     * aesub(5) are available.  This field is optional.
     *
     * This command could also be used to notify other management
     * systems, such as progress and defect tracking.
     *
     * Executed as: the developer.
     * Current directory: the development directory of the change.
     * Exit status: ignored.
     */
    develop_end_undo_notify_command = string;

    /*
     * notify that the review has begun
     * All of the substitutions described in aesub(5) are available.
     * this field is optional
     *
     * This command could also be used to notify other management systems,
     * such as progress and defect tracking.
     *
     * Executed as: the reviewer.
     * Current directory: the development directory of the change.
     * Exit status: ignored.
     */
    review_begin_notify_command = string;

    /*
     * notify that the review has no longer begun
     * All of the substitutions described in aesub(5) are available.
     * this field is optional
     *
     * This command could also be used to notify other management systems,
     * such as progress and defect tracking.
     *
     * Executed as: the reviewer.
     * Current directory: the development directory of the change.
     * Exit status: ignored.
     */
    review_begin_undo_notify_command = string;

    /*
     * Notify that the review has passed.  All of the substitutions
     * described in aesub(5) are available.  This field is optional.
     *
     * This command could also be used to notify other management
     * systems, such as progress and defect tracking.
     *
     * Executed as: the reviewer.
     * Current directory: the development directory of the change.
     * Exit status: ignored.
     */
    review_pass_notify_command = string;

    /*
     * Notify that a review pass has has been rescinded.  All of the
     * substitutions described in aesub(5) are available.  This
     * field is optional.
     *
     * This command could also be used to notify other management
     * systems, such as progress and defect tracking.
     *
     * Executed as: the reviewer.
     * Current directory: the development directory of the change.
     * Exit status: ignored.
     */
    review_pass_undo_notify_command = string;

    /*
     * Notify that the review has failed.  All of the substitutions
     * described in aesub(5) are available.  This field is optional.
     *
     * This command could also be used to notify other management
     * systems, such as progress and defect tracking.
     *
     * Executed as: the reviewer.
     * Current directory: the development directory of the change.
     * Exit status: ignored.
     */
    review_fail_notify_command = string;

    /*
     * Notify that the integration has passed.  All of the
     * substitutions described in aesub(5) are available.  This
     * field is optional.
     *
     * This command could also be used to notify other management
     * systems, such as progress and defect tracking.
     *
     * Executed as: the project owner.
     * Current directory: the new baseline of the project.
     * Exit status: ignored.
     */
    integrate_pass_notify_command = string;

    /*
     * Notify that the integration has failed.  All of the
     * substitutions described in aesub(5) are available.  This
     * field is optional.
     *
     * This command could also be used to notify other management
     * systems, such as progress and defect tracking.
     *
     * Executed as: the integrator.
     * Current directory: the development directory of the change.
     * Exit status: ignored.
     */
    integrate_fail_notify_command = string;

    /*
     * This field contains what to do when a change is created with
     * no test exemption specified.
     */
    default_test_exemption = boolean;

    /*
     * This field contains what to do when a change is created with
     * no regression test exemption specified.
     */
    default_test_regression_exemption = boolean
	show_if_default;

    /*
     * This field may be set to true if you want to skip various
     * unlucky numbers for changes, branches and tests.  Various
     * traditions are avoided, both Eastern and Western.  Defaults to
     * false if not set.
     */
    skip_unlucky = boolean;

    /*
     * This field may be set to true if you want to compress the
     * database on writing.  (It is always uncompress on reading
     * if necessary.)
     */
    compress_database = boolean;

    /*
     * This field controls the state entered on a successfil develop end
     * state transition.  The default is "being reviewed".
     *
     * goto_being_reviewed
     *      This means that the state machine goes from the being_developed
     *      state to the being_reviewed state.  The aerb command only sends
     *      informative email.
     *
     * goto_awaiting_review
     *      This means that the state machine goes from the being_developed
     *      state to the awaiting_review state.  The aerb command is now
     *      essential.
     *
     * goto_awaiting_integration
     *      This means that the state machine goes from the being_developed
     *      state into the awaiting_inmtegartion state.  Code review is
     *      skipped entirely.
     *
     * Note that the "developer_may_review" setting may not contradict
     * the "develop_end_action".  If developers may not review their
     * own work, then you may not goto directly to being integrated
     * (as this means much te same thing).
     */
    develop_end_action = (goto_being_reviewed, goto_awaiting_review,
	    goto_awaiting_integration);

    /*
     * This field contains a history of integrations for the branch.
     * Update by each successful 'aegis -Integrate_Pass' command.
     */
    history =
    [
	{
	    /*
	     * The delta number of the integration.
	     */
	    delta_number = integer;

	    /*
	     * The number of the change which was integrated.
	     */
	    change_number = integer;

	    /*
	     * the names by which this delta is known
	     */
	    name = [ string ];
	}
    ];

    /*
     * The list of changes which have been created to date.
     */
    change = [integer];

    /*
     * The list of branches which have been created to date.  This
     * will be a subset of the above (possibly empty, possibly
     * complete, never larger).
     */
    sub_branch = [integer];

    /*
     * The list of administrators of the branch.
     */
    administrator = [string];

    /*
     * The list of developers of the branch.
     */
    developer = [string];

    /*
     * The list of reviewers of the branch.
     */
    reviewer = [string];

    /*
     * The list of integrators of the branch.
     */
    integrator = [string];

    /*
     * The change currently being integrated.  Only one change
     * (within a branch) may be integrated at a time.  Only set when
     * an integration is in progress.
     */
    currently_integrating_change = integer;

    /*
     * The pathname of where to place new development directories.
     * The pathname must be absolute.  Only consulted if the uconf
     * field of the same name is not set.  Defaults to $HOME.
     */
    default_development_directory = string;

    /*
     * The minimum change number for aenc, if no change number is
     * specified.  This allows the low-numbered change numbers to be
     * used for branches later in the project.  Defaults to 10 if
     * not set, may not be less than 1.
     */
    minimum_change_number = integer;

    /*
     * This controls whether the automatically selected aenc(1) change
     * numbers "fill in" any gaps.  Defaults to true if not set.
     */
    reuse_change_numbers = boolean;

    /*
     * The minimum branchhange number for aebr, if no branch number is
     * specified.  Defaults to 1 if not set.
     */
    minimum_branch_number = integer;

    /*
     * This field may be used to protect the development directory
     * after the "being developed" state.  It does this by making
     * it read-only at develop end time.  Should the change ever
     * be returned to the "being developed" state, it will be made
     * writble again.
     *
     * The default is false, meaning to leave the development
     * directory writable while is being reviewed and integrated.
     * Aegis' normal tampering detection will notice if files are
     * changed, but there is no reminder to the developer that the
     * change should be left alone.
     */
    protect_development_directory = boolean;
};

/************************ OBSOLETE FIELDS ************************/

/*
 * This field is a list of all the files in the change.
 * This field is not obsolete, and will automatically be moved to fstate
 * in any change aegis detects it in.
 *
 * Note: this field is used by aedist to record file state, rather than
 * add another file to the transfer format, which has compatibility
 * problems already.
 */
src =
[
    {
	/*
	 * This file names the file.
	 * The name is relative to the root of the
	 * baseline directory tree.
	 */
	file_name = string;

	/*
         * This field uniquely identifies the file for its entire
         * lifetime.  This field remains constant across file renames.
         * The value of this field shall be formatted as a valid UUID,
         * all in lower case.
	 */
	uuid = string;

	/*
	 * This field describes what is being done with the file.
	 */
	action = file_action;

	/*
	 * This field records the edit number of the file
	 * when it was added to the change (or updated using the
	 * 'aegis -DIFFerence' command).
	 * This field is not present for new files.
	 */
	edit_number = string;

	/*
	 * This field describes what function the file serves.
	 */
	usage = file_usage;

	/*
	 * These fields are set by a successful
	 * 'aegis -DIFFerence' command to the last-time-modified
	 * of the source file and the difference listing.
	 * It is only present between the 'being_developed' and
	 * 'being_integrated' states, inclusive.
	 * This allows checking that the files have not been modified
	 * at the develop_end, review_pass and integrate_begin
	 * state transitions.
	 */
	diff_time = time;
	diff_file_time = time;

	/*
	 * To change the name of a file,
	 * a combination of aerm and aenf are used.
	 * With deleted files, this field is used to say where it went.
	 * With new files, this field is used to say where it came from.
	 */
	move = string;

	/*
	 * This field tracks whether this incarnation of the file
	 * was executable at `develop end' time.  This mode
	 * is restored (taking the project umask into account)
	 * when the file is copied.
	 *
	 * This field is only meaningful for changes in the
	 * "completed" state, because this field is only set
	 * by aeip.  Until then, the mode if the file itself is
	 * the authority.
	 */
	executable = boolean hide_if_default;

	/*
         * This field records the file attributes.
	 */
	attribute = attributes;
    }
];
