// // aegis - project change supervisor // Copyright (C) 1995-2009, 2011-2014 Peter Miller // Copyright (C) 2007, 2008 Walter Franzini // // 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 . // #ifndef LIBAEGIS_CHANGE_H #define LIBAEGIS_CHANGE_H #include #include #include #include #include #include class nstring_list; // forward // // Name of the project configuration file, // relative to the baseline/devdir root. // #define THE_CONFIG_FILE_OLD "config" #define THE_CONFIG_FILE_NEW "aegis.conf" #include // // Define a magic number to represent the trunk transaction // of the project. It has an exceptional file name. // #define TRUNK_CHANGE_NUMBER ((long)((~(unsigned long)0) >> 1)) #define TIME_NOT_SET (time_t)0 #define UUID_NOT_SET (string_ty*)0 struct string_list_ty; // forward struct sub_context_ty; // forward struct symtab_ty; // forward class project; // forward /** * The change class is used to represent the internal state of a * change set. */ class change { public: /** * The pointer typedef is provided so that clients of this * interface may use change::pointer everywhere they need to point * at a change instance, and only this typedef needs to be edited * to use some variety of smart pointer instead. */ typedef change_pointer pointer; private: /** * The destructor do not use directly. Use the * #reference_count_down method instead, it takes care of all the * reference counting. */ ~change(); private: /** * The constructor. * It is private on purpose, use the #change::create method instead. * * @param pp * The project that this change set isd a part of. * @param number * The number of the new hange set. */ change(project *pp, long number); // NOTE: methods are sorted alphabetically. To have methods // grouped, make sure they change their suffix rather than their // prefix. E.g. thingumy_get and thingumy_set rather than // get_thingumy and set_thingumy. // ---------- A ------------------------------------------------------ public: /** * The architecture_name instance variable is used to remember * FIXME: fill me in */ string_ty *architecture_name; /** * The attributes_get method is used to obtain the value of an * attribute of this change set. * * @param name * The name of the attribute. * Attribute names are not case sensitive. * @returns * the string value of the attribute, or the empty string * if not found. */ nstring attributes_get(const nstring &name); /** * The attributes_get_boolean method is used to obtain the * value of an attribute of this change set, as a true/false * attribute. * * @param name * The name of the attribute. * Attribute names are not case sensitive. * @returns * the boolean value of the attribute, or false if the * attribute is not found or is not interpretable as a * boolean. */ bool attributes_get_boolean(const nstring &name); // ---------- B ------------------------------------------------------ public: void bind_existing(void); bool bind_existing_errok(void); private: bool bind_existing_inner(bool errok); public: /** * The bind_new method during cvhange set vonstruvtion, where a new * change set is being created for he first time. */ void bind_new(void); private: /** * The bogus instance variable is used to remember whether or not * this change set is a fake. * * @sa * #create_bogus class method, * #is_bogus method */ bool bogus; public: /** * The brief_description_get method is used to obtain the brief * description of this change set. */ nstring brief_description_get(void); // ---------- C ------------------------------------------------------ /** * The copyright_years_get_string is used to get a string * containing the list fo copyrigth years, a union of the project's * copyright years and this change set's copyright years. */ nstring copyright_years_get_string(void); /** * The completion_timestamp method is used to obtain the time that * the change set completed integration, or "now" if it is not yet * complete. use the #is_completed method to distinguish the two cases. */ time_t completion_timestamp(void); /** * The create class method is used to create new dynamically * allocated instances of this class * * @param pp * A pointer to the project to which the new change set belongs. * @param number * The number of the new hange set. */ static pointer create(project *pp, long number); /** * The create_bogus class method is used to crete new change set * instances (similar to the #create class method). But the * change set is bogus / pretend for situations that need such a * beast. * * @param pp * A pointer to the project to which the new change set belongs. * @sa * #bogus instance variable, * #is_bogus method */ static pointer create_bogus(project *pp); /** * The creator_name method is used to obtain the Unix name of the * user that created this change. * * @returns * The string value of the Unix name or NULL if not defined. * DO NOT str_free it when you are done with it, it is cached. */ string_ty *creator_name(void); private: /** * The cstate_data instance variable is used to remember thye * change set's meta-data in memory (write back to disk using the * #cstate_write method). */ cstate_ty *cstate_data; /** * The cstate_filename instance variable is used to remember the * absolute path of the file holding he vhange-set's mta-data, * except the meta-data for files. */ nstring cstate_filename; /** * The cstate_to_fstate method is used to migrate a cvhange set on * an old project, to use the more recent fstate. */ void cstate_to_fstate(void); public: /** * The cstate_filename_get method is used to obtain the name of * the file containing cstate meta-data of this change. * * @returns * a string. DO NOT str_free it when you are done with it, * it is cached. */ nstring cstate_filename_get(void); private: /** * The cstate_data method is used to improve a vhange set's meta * data, thi is usually after a tranition from the old style of * cstate and the news style, using fstate to split the files out. */ static void cstate_improve(cstate_ty *d); /** * The cstate_is_a_new_file instance variable is used to remember * $whether or not the change-set meta-data file is being created * the firsdt time. */ bool cstate_is_a_new_file; public: /** * The cstate_get method may be used to obtain the cstate meta-data * of this change. */ cstate_ty *cstate_get(void); /** * THe cstate_write method may be used to write the cstate * meta-data of this change */ void cstate_write(void); // ---------- D ------------------------------------------------------ /** * The delta_number_get method is used to get the delta number of a * change, or zero if the change is not yet completed. */ long delta_number_get(void); /** * The description_get method is used to obtain the long * description of this change set. */ nstring description_get(void); /** * The developer_name method is used to obtain the Unix name of * the developer of this change. * * @returns * The string value of the Unix name or NULL if not defined. * DO NOT str_free it when you are done with it, it is * cached. */ string_ty *developer_name(void); /** * The developer_user_get method is used to obtain a user_ty * instance representing the (most recent) developer of this change * set. */ user_ty::pointer developer_user_get(void); public: void development_directory_clear(void); /** * The development_directory_get method is used to obtain the * absolute path of he development directory of this change set. */ string_ty *development_directory_get(bool resolved); public: /** * The development_directory_resolved instance variable is used to * remember * FIXME: fill me in */ nstring development_directory_resolved; void development_directory_set(string_ty *path); void development_directory_set(const nstring &path); public: /** * The development_directory_unresolved instance variable is used * to remember * FIXME: fill me in */ nstring development_directory_unresolved; public: /** * The download_files_acessable method may be used to to determine * whether or not the calling user has permission to access the * change set's download files. This usually means read and search * premission on the development directory and/or the integration * director, unless the change set is in the completed state. */ bool download_files_accessable(void); // ---------- E ------------------------------------------------------ // ---------- F ------------------------------------------------------ /** * The file_exists method is used to determine whether or not a * file exists in the change set. (view_path == view_path_first) * * @param filename * The base-relative name of the file to search for. */ bool file_exists(const nstring &filename); public: /** * The file_list instance variable is used to remember * FIXME: fill me in */ string_list_ty *file_list[view_path_MAX]; private: /** * The fstate_data instance variable is used to remember the file * meta-data read from th chnage set's file state file. */ fstate_ty *fstate_data; private: /** * The fstate_filename instance variable is used to remeber the * absolute path of the change-files state file. This is the meta * data about files, as opposed to the meta-data about the cvhnage * set. */ nstring fstate_filename; public: /** * The fstate_filename_get function is used to obtain the absolute * path of the file which holds the change's file state. * * @returns * a string. DO NOT str_free it when you are done with it, * it is cached. */ nstring fstate_filename_get(void); public: /** * The fstate_get method is used to obtain a current value for the * change file state symbol table. * * @note * This would be static to aegis/change_file.c if only * aegis/aer/value/fstate.c did not need it. No other place * should access this directly. */ fstate_ty *fstate_get(void); private: /** * The fstate_is_a_new_file instance variable is used to remember * whether or not the fstate meta-data is a new fstte file, or not. * The way the file is written differs the first time. */ bool fstate_is_a_new_file; public: // FIXME: not for much longer /** * The fstate_stp instance variable is used to remember indivdual * file state meta-data, indexed by file name. */ symtab_ty *fstate_stp; public: // FIXME: not for much longer /** * The fstate_uuid_stp instance variable is used to remember * individual fle state meta-data, indexed by UUID. */ symtab_ty *fstate_uuid_stp; public: /** * The file_find method is used to locate a change file similar to * the file named. * * @param filename * The name of the file to be found. * @param vp * The style of view path to be used. */ fstate_src_ty *file_find(const nstring &filename, view_path_ty vp); /** * The file_find method is used to locate a change file similar to * the one indicated. If possible it uses the UUID otherwise (for * backwards compatibility) it uses the file name. * * @param src * The meta-data of the file to be found. * @param vp * The style of view path to be used. */ fstate_src_ty *file_find(fstate_src_ty *src, view_path_ty vp); /** * The file_find method is used to locate a change file similar to * the one indicated. If possible it uses the UUID otherwise (for * backwards compatibility) it uses the file name. * * @param src * The meta-data of the file to be found. * @param vp * The style of view path to be used. */ fstate_src_ty *file_find(cstate_src_ty *src, view_path_ty vp); /** * The file_find method is used to locate a change file similar to * the file named, in the change set itself * (view_path == view_path_first). * * @param filename * The name of the file to be found. */ fstate_src_ty *file_find(const nstring &filename); /** * The file_find_fuzzy method is used to locate a change file with * a name similar to the one given. * * @param filename * The name of the file to be found. * @param vp * The style of view path to be used. */ fstate_src_ty *file_find_fuzzy(const nstring &filename, view_path_ty vp); /** * The file_find_uuid method is used to find a source file given * the UUID. * * @param uuid * The UUID to search for. * @param view_path * The style and depth of search for the file. * @returns * a pointer to the file information, or NULL if no file has the * specified UUID. */ fstate_src_ty *file_find_uuid(string_ty *uuid, view_path_ty view_path); /** * The file_find_uuid method is used to find a source file given * the UUID. * * @param uuid * The UUID to search for. * @param view_path * The style and depth of search for the file. * @returns * a pointer to the file information, or NULL if no file has the * specified UUID. */ fstate_src_ty *file_find_uuid(const nstring &uuid, view_path_ty view_path); /** * The file_is_config method is used to determine whether or not * the named file is a configuration file. * * @param name * The name of the file of interest * @returns * true if it is a config file, false if not. */ bool file_is_config(string_ty *name); /** * The file_is_config method is used to determine whether or not * the named file is a configuration file. * * @param name * The name of the file of interest * @returns * true if it is a config file, false if not. */ bool file_is_config(const nstring &name); /** * The file_new method is used to add a new file to a change set's * file manifest. No checking is poerformed, it is up to the caller * to ensure that the name is unique. * * @param file_name * The name of the file to be created. * @returns * A newly allocated file, with the name set, and everything * else blank. */ fstate_src_ty *file_new(string_ty *file_name); /** * The file_new method is used to add a new file to a change set's * file manifest. No checking is poerformed, it is up to the caller * to ensure that the name is unique. * * @param file_name * The name of the file to be created. * @returns * A newly allocated file, with the name set, and everything * else blank. */ fstate_src_ty *file_new(const nstring &file_name); /** * The file_new method is used to add a new file to a change * set's file manifest. No checking is poerformed, it is up to * the caller to ensure that the file name and UUID are unique. * Typically this is used when adding a project file to a change * set for modification or removal. * * @param meta * The meta-data of the file to be created. * @returns * A newly allocated file, with the name set, and everything * else blank. */ fstate_src_ty *file_new(fstate_src_ty *meta); /** * The file_path method is used to obtain the absolute path to * the given change file. * * @param file_name * The name of the file in question. * @returns * a string containing the absolute path, or NULL if the file is * not a change source file. */ string_ty *file_path(string_ty *file_name); /** * The file_path method is used to obtain the absolute path to * the given change file. * * @param file_name * The name of the file in question. * @returns * a string containing the absolute path, or the empty string * if the file is not a change source file. */ nstring file_path(const nstring &file_name); /** * The file_path method is used to obtain the absolute path to * the given change file. * * @param src * The meta-data of the file in question. * @returns * a string containing the absolute path, or NULL if the file is * not a change source file. */ string_ty *file_path(fstate_src_ty *src); /** * The file_path_by_uuid method is used to obtain the absolute * path to the given change file. * * @param uuid * The UUID of the file in question. * @returns * a string containing the absolute path, or NULL if the file is * not a change source file. */ string_ty *file_path_by_uuid(string_ty *uuid); /** * The file_path_by_uuid method is used to obtain the absolute * path to the given change file. * * @param uuid * The UUID of the file in question. * @returns * a string containing the absolute path, or NULL if the file is * not a change source file. */ nstring file_path_by_uuid(const nstring &uuid); /** * The file_promote method is used to check whether or not recent * integrations have change the actions the change files must * perform. * * If two changes are creating the same file, the first one integrated * means that the second one must update its action to "modify". * * If two changes are removing the same file, the first one integrated * means that the second one needs to drop the file from its list. * * If one change is removing a file, and a second change is modifying * the same file, after the first change is integrated, the second * change must update its action to "create". * * @returns * true if anything changed, false if nothing changed. */ bool file_promote(void); /** * The file_remove method is used to remove the named file from the * change-set meta-data. Including the symtab indexing. * * @param file_name * The name of the file to be removed. */ void file_remove(const nstring &file_name); /** * The file_remove method is used to remove the named file from the * change-set meta-data. Including the symtab indexing. * * @param file_name * The name of the file to be removed. */ // DEPRECATED // ... later void file_remove(string_ty *file_name); /** * The file_remove_all method is used to remove all of the files from the * change-set meta-data. Including the symtab indexing. */ void file_remove_all(void); /** * The file_resolve_name method is used to resolve an arbitrary * UNIX pathname (relative or absolute) into a base relative path * within a change set's search path. * * @param up * The user invoking the program. * @param file_name * The file name to be resolved. * @returns * The resolved base relative file name. Use str_free when you are * done with it. */ string_ty *file_resolve_name(user_ty::pointer up, string_ty *file_name); /** * The file_resolve_name method is used to resolve an arbitrary * UNIX pathname (relative or absolute) into a base relative path * within a change set's search path. * * @param up * The user invoking the program. * @param file_name * The file name to be resolved. * @returns * The resolved base relative file name. Use str_free when you are * done with it. */ nstring file_resolve_name(user_ty::pointer up, const nstring &file_name); /** * The file_resolve_names method is used to resolve arbitrary UNIX * pathnames (relative or absolute) into base relative paths within * a change set's search path. * * @param up * The user invoking the program. * @param file_names * The file names to be resolved. * This parameter ISN'T const because this will be done in situ. */ void file_resolve_names(user_ty::pointer up, string_list_ty &file_names); /** * The file_source method is used to abtain a pathname or the given * file. If the does not exist (orhas been removed) the empty * string is returned. * * @param name * The name of the file to look for. * @returns * String containing the path, or the empty string if not found. */ nstring file_source(const nstring &name); public: /** * The file_unchanged method is used to determine whether a source * file is unchanged compared to the file in the baseline. * * @param src_data * The file in question. * @param up * The user to perform file actions as. * @returns * bool; true if the file is unchanged, false if the file has * changed, and false if the comparison isn't meaningful. */ bool file_unchanged(fstate_src_ty *src_data, user_ty::pointer up); public: /** * The file_version_path method is used to obtain a file path * that contains the source of the file referenced by the given * meta-data. * * @param src * Meta data of the file in question. Contains uuid and version info. * @param need_to_unlink * This is set to true on return for files that need to be * unlinked when done with (i.e. historical versions). */ string_ty *file_version_path(fstate_src_ty *src, bool &need_to_unlink); private: /** * The fimprove method is used to cope with previous versions * of the file meta data, and rewrite them to conform to later * expectations. * * @param fstate_data * The file meta-data to be massaged. */ void fimprove(fstate_ty *fstate_data); public: // ---------- G ------------------------------------------------------ /** * The gid_get method is used to obtain the Unix group id of the * change owner. */ int gid_get(void) const; // ---------- H ------------------------------------------------------ cstate_history_ty *history_new(const user_ty::pointer &up); // ---------- I ------------------------------------------------------ void integration_directory_clear(); /** * The integration_directory_get method may be used to obtain the * change's integration directory path. It is an error if the * change is not in the 'being integrated' state. * * @param resolve * whether or not to resolve symlinks in the path. */ string_ty *integration_directory_get(bool resolve); public: // not for much longer /** * The integration_directory_resolved instance variable is used to * remember * FIXME: fill me in */ nstring integration_directory_resolved; public: void integration_directory_set(string_ty *path); void integration_directory_set(const nstring &path); private: /** * The integration_directory_unresolved instance variable is used * to remember * FIXME: fill me in */ nstring integration_directory_unresolved; public: /** * The integrator_name method is used to obtain the Unix group * name of the integrator. * * @returns * The string value of the Unix name or NULL if not defined. * DO NOT str_free it when you are done with it, it is * cached. */ string_ty *integrator_name(void); /** * The is_a_branch method is used to determine whether or not this * change set is an active branch. If you want to know if it was * ever an active branch (e.g. now completed) use the #was_a_branch * method. */ bool is_a_branch(void); /** * The is_awaiting_development method returns true if the given * change is in the awaiting development state, and false if it is * not. */ bool is_awaiting_development(void); /** * The is_being_developed method returns true if the given change * is in the being developed state, and false if it is not. */ bool is_being_developed(void); /** * The is_being_integrated method is used to determine whether or * not this is in the being integrated state. * * @returns * bool; true if this is in the being integrated state, and * false if it is not. */ bool is_being_integrated(void); /** * The is_bogus method may be used to determine whether or not a * change set is bogus. */ bool is_bogus(void) const { return bogus; } /** * The change_is_completed function returns true (non-zero) if this * change is in the completed state, and false (zero) if it is not. */ bool is_completed(void); /** * The is_trunk method is to determine whether or not this hange * set is a project trunk. */ bool is_trunk(void) const { return (number == TRUNK_CHANGE_NUMBER); } // ---------- J ------------------------------------------------------ // ---------- K ------------------------------------------------------ // ---------- L ------------------------------------------------------ public: /** * The FUBAR instance variable is used to remember * FIXME: fill me in */ long lock_magic; /** * The lock_sync method is used to sync the locks if they have * become out of date. The lock_sync method is used to invalidate * the project state data if the lock has been released and taken * again. */ void lock_sync(void); /** * The lock_sync_forced method is used to sync the locks if they * have not become out of date. The lock_sync_forced method is * used to invalidate the vhnage set state meta data if the lock * has been released and taken again. */ void lock_sync_forced(void); public: static nstring logfile_basename(void); public: /** * We are abput to start logging, into the returned filename. * * The log_open function is used to start sending stdout * and stderr to a logs-file. If necessary it creates the log * file before returning. */ nstring logfile_get(void); private: /** * The logfile instance variable is used to remember * FIXME: fill me in */ nstring logfile; // ---------- M ------------------------------------------------------ // ---------- N ------------------------------------------------------ private: /** * The number instance variable is used to remeber the number * of the the change. The change number is relative to the * branch/project it forms part of. Use the #number-get method to * obtain thi value. * * @sa * #magic_zero_encode, #magic_zero_decode, #pp */ long number; public: /** * The number_get method is used to obtain the hange number of * this change set. The number is relative to the containing * branch/projet. */ long number_get(void) const { return number; } /** * The number_get_mzd method is used to obtain the hange number of * this change set, after passing it through #magic_zero_decode. * The number is relative to the containing branch/project. */ long number_get_mzd(void) const; // ---------- O ------------------------------------------------------ // ---------- P ------------------------------------------------------ /** * The pconf_attributes_get method is used to obtain the * value of an attribute of the project, from the project * configuration file. It could be in this change, or it could * be in a baseline or an ancestor baseline. * * @param name * The name of the attribute. * Attribute names are not case sensitive. * @returns * the string value of the attribute, or the empty string * if not found. */ nstring pconf_attributes_find(const nstring &name); /** * The pconf_attributes_get_boolean method is used to obtain the * value of an attribute of the project, from the project * configuration file. It could be in this change, or it could * be in a baseline or an ancestor baseline. * * @param name * The name of the attribute. * Attribute names are not case sensitive. * @param dflt * The default value to return if no attribute available. * @returns * the string value of the attribute, or the empty string * if not found. */ bool pconf_attributes_get_boolean(const nstring &name, bool dflt = false); /** * The pconf_copyright_owner_get method is used to obtain the * name of the copyright holder of a project. */ nstring pconf_copyright_owner_get(void); public: /** * The pconf_data instance variable is used to remember * FIXME: fill me in */ pconf_ty *pconf_data; public: /** * The pfstate_data instance variable is used to remember * FIXME: fill me in */ fstate_ty *pfstate_data; private: /** * The pfstate_filename instance variable is used to remeber the * looks of the project/branch file state file. */ nstring pfstate_filename; public: /** * The pfstate_filename_get method is used to obtain the absolute * path of the file which holds the delta's cache of the project * file state. */ nstring pfstate_filename_get(void); public: /** * The pfstate_get method is used to obtain the project file state * information for a change set. This is all of the project files, * not just one. */ fstate_ty *pfstate_get(void); public: /** * The pfstate_stp instance variable is used to remember * FIXME: fill me in */ symtab_ty *pfstate_stp; public: /** * The pfstate_uuid_stp instance variable is used to remember * FIXME: fill me in */ symtab_ty *pfstate_uuid_stp; public: // FIXME: not for much longer /** * The pp instance variable is used to remember the parent project * of this change set. * * Use the #project_get method to obtain access. * * @note: * Care mut be taken to avoid infinite reference loops with * change sets, particularly the trunk change set. This is why * we use a simple pointer, rather than a "smart" reference * counted pointer. */ project *pp; public: /** * The project_get method may be used to abtain a pointer to the * parent project of this change set. * * @sa * See note attached to #pp instance variable. */ project *project_get(void) const { return pp; } public: /** * The project_specific_setenv_performed instance variable is used * to remember * FIXME: fill me in */ bool project_specific_setenv_performed; public: /** * The project_specific_setenv_performed_set method is used to * remember if the environment variable(s), specified as * project_specific attributes, has been already exported. * * @returns * Void. */ void project_specific_setenv_performed_set(void); /** * The project_specific_setenv_performed_get method is used to * know if the environment variable(s), specified as * project_specific attributes, has been already exported. * * @returns * True if the variables has been already exported, false * otherwise. */ bool project_specific_setenv_performed_get(void) const; // ---------- Q ------------------------------------------------------ // ---------- R ------------------------------------------------------ private: /** * The reference_count instance variable is used to remember how * many references exist to this instance. This permits resource * tracking and clean-up in the absence of garbage collection. * * It is managed via the #reference_count_up and * #reference_count_down methods. */ long reference_count; public: /** * The reference_count_down method is used to destrory the objet, * but only after the last reference has been destroyed. */ void reference_count_down(void); /** * The reference_count_up method is used to obtain a copy of the * change set state. * * @note * however this is simply reference counted, and does not * involve an expensive deep copy. */ void reference_count_up(void); /** * The reviewer_name method is used to determine the Unix name of * the (last) reviewer. * * @returns * The string representation of the Unix name or NULL if not * defined. DO NOT str_free it when you are done with it, it * is cached. */ string_ty *reviewer_name(void); /** * The run_project_file_command_needed method may be used to * determine whether or not the project_file_command needstosed in * recent integration history. * * @returns * true if need to run it (see next method), false if not. */ bool run_project_file_command_needed(void); /** * The run_project_file_command method is used to run the command * configured in the aegis.conf file's project_file_command field. * * @param up * The user to run the command as. * * @note * this method MUST be called outside the change set lock */ void run_project_file_command(const user_ty::pointer &up); /** * The run_project_file_command_done method is used to remember * that the project_file comman has been (is about to be) called * recently. * * @note * this method MUST be called INSIDE the change set lock */ void run_project_file_command_done(void); /** * The run_new_file_command method is used to run the * new_file_command field of the aegis.conf file. * * @param slp * The list of new file names * @param up * Th euser to run the command as. */ void run_new_file_command(string_list_ty *slp, const user_ty::pointer &up); /** * The run_new_file_undo_command method is used to run the command * in the new_file_undo_command field of the aegis.conf file. * * @param slp * The list of filenames affected. * @param up * the user to run the program as */ void run_new_file_undo_command(string_list_ty *slp, const user_ty::pointer &up); /** * The run_new_test_command method is used to run the command in * the new_test_command field of the aegis.conf file. * * @param slp * The list of filenames affected. * @param up * the user to run the program as */ void run_new_test_command(string_list_ty *slp, const user_ty::pointer &up); /** * The run_new_test_command method is used to run the command in * the new_test_command field of the aegis.conf file. * * @param file_names * The list of filenames affected. * @param up * the user to run the program as */ void run_new_test_command(const nstring_list &file_names, const user_ty::pointer &up); /** * The run_new_test_undo_command method is used to run the command * in the new_test_undo_command field of the aegis.conf file. * * @param slp * The list of filenames affected. * @param up * the user to run the program as */ void run_new_test_undo_command(string_list_ty *slp, const user_ty::pointer &up); /** * The run_copy_file_command method is used to run the command in * the copy_file_command field of the aegis.conf file. * * @param slp * The list of filenames affected. * @param up * the user to run the program as */ void run_copy_file_command(string_list_ty *slp, const user_ty::pointer &up); /** * The run_copy_file_undo_command method is used to run the command * in the copy_file_undo_command field of the aegis.conf file. * * @param slp * The list of filenames affected. * @param up * the user to run the program as */ void run_copy_file_undo_command(string_list_ty *slp, const user_ty::pointer &up); void run_copy_file_undo_command(const nstring_list &slp, const user_ty::pointer &up); /** * The run_remove_file_command method is used to run the command in * the remove_file_command field of the aegis.conf file. * * @param slp * The list of filenames affected. * @param up * the user to run the program as */ void run_remove_file_command(string_list_ty *slp, const user_ty::pointer &up); /** * The run_remove_file_undo_command method is used to run the * command in the remove_file_undo_command field of the aegis.conf * file. * * @param slp * The list of filenames affected. * @param up * the user to run the program as */ void run_remove_file_undo_command(string_list_ty *slp, const user_ty::pointer &up); /** * The run_make_transparent_command method is used to run the * command in the make_transparent_command field of the aegis.conf * file. * * @param slp * The list of filenames affected. * @param up * the user to run the program as */ void run_make_transparent_command(string_list_ty *slp, const user_ty::pointer &up); /** * The run_make_transparent_undo_comman method is used to run * the command in the make_transparent_undo_command field of the * aegis.conf file. * * @param slp * The list of filenames affected. * @param up * the user to run the program as */ void run_make_transparent_undo_command(string_list_ty *slp, const user_ty::pointer &up); /** * The run_forced_develop_begin_notify_command method is used to * run the command in the forced_develop_begin_notify_command field * of the aegis.conf file. * * @param up * the user to run the program as */ void run_forced_develop_begin_notify_command(const user_ty::pointer &up); /** * The run_develop_end_notify_command method is used to run * the command in the develop_end_notify_command field of the * aegis.conf file. */ void run_develop_end_notify_command(void); /** * The run_develop_end_undo_notify_command method is used to run * the command in the develop_end_undo_notify_command field of the * aegis.conf file. */ void run_develop_end_undo_notify_command(void); /** * The run_review_begin_notify_command method is used to run * the command in the review_begin_notify_command field of the * aegis.conf file. */ void run_review_begin_notify_command(void); /** * The run_review_begin_undo_notify_command method is used to run * the command in the review_begin_undo_notify_command field of the * aegis.conf file. */ void run_review_begin_undo_notify_command(void); /** * The run_review_pass_notify_command method is used to run * the command in the review_pass_notify_command field of the * aegis.conf file. */ void run_review_pass_notify_command(void); /** * The run_review_pass_undo_notify_command method is used to run * the command in the review_pass_undo_notify_command field of the * aegis.conf file. */ void run_review_pass_undo_notify_command(void); /** * The run_review_fail_notify_command method is used to run * the command in the review_fail_notify_command field of the * aegis.conf file. */ void run_review_fail_notify_command(void); /** * The run_integrate_pass_notify_command method is used to run * the command in the integrate_pass_notify_command field of the * aegis.conf file. */ void run_integrate_pass_notify_command(void); /** * The run_integrate_fail_notify_command method is used to run * the command in the integrate_fail_notify_command field of the * aegis.conf file. */ void run_integrate_fail_notify_command(void); /** * The run_develop_begin_early_command method is used to run the * develop_begin_early_command from the project configuration file. * This is used by the aedb command, just after the development * directory has been created. * * @param up * The user to run the command as. */ void run_develop_begin_early_command(user_ty::pointer up); /** * The run_develop_begin_command method is used to run the * develop_begin_command from the projetc configuration file. This * is used by the aedb command, just all other actions performed by * aedb. * * @param up * The user to run the command as. */ void run_develop_begin_command(user_ty::pointer up); // ---------- S ------------------------------------------------------ /** * The search_path_get method may be used to obtain the search path * (list of progressively more out-of-date ancestor branches) * within which to search for files. * * @param result * Where to append the additional directories. * @param resolve * Whether or not to expand synbolic links within paths. */ void search_path_get(string_list_ty *result, bool resolve); /** * The search_path_get method may be used to obtain the search path * (list of progressively more out-of-date ancestor branches) * within which to search for files. * * @param result * Where to append the additional directories. * @param resolve * Whether or not to expand synbolic links within paths. */ void search_path_get(nstring_list &result, bool resolve); // ---------- T ------------------------------------------------------ time_t time_limit_get(void); /** * The change_top_path_set method is used to set the change set top * directory. This is done foe new branches. * * @param path * The absolute path of the top_path, if relative, relative to * trunk_top_path. */ void top_path_set(string_ty *path); /** * The change_top_path_set method is used to set the change set top * directory. This is done foe new branches. * * @param path * The absolute path of the top_path, if relative, relative to * trunk_top_path. */ void top_path_set(const nstring &path); /** * The change_top_path_get method is used to obtain th top path of * a psroject trunk or a branch. * * @param resolve * if true, resolve all symboliclinks in the path. */ nstring top_path_get(bool resolve); public: /** * The top_path_resolved instance variable is used to remember * FIXME: fill me in */ string_ty *top_path_resolved; public: /** * The top_path_unresolved instance variable is used to remember * FIXME: fill me in */ string_ty *top_path_unresolved; // ---------- U ------------------------------------------------------ /** * The umask method is used to obtain the umask for this change. * * @returns * An int representing the umask value. */ int umask_get(void) const; /** * The uuid_get method is used to obtain the UUID of this change set. * * @returns * The uuid of the change set, or the empty string of this * change set doesn't have a UUID. */ nstring uuid_get(void); /** * The uuid_get_list method is used to obtain all of the UUIDs * associated with this change set. This includes the change set's * UUID, if it has one, and all of the aoriginal-uuid attributes. * * @param uuids * Where to put all of the UUIDs associated with this change set. */ void uuid_get_list(nstring_list &uuids); // ---------- V ------------------------------------------------------ /** * The valid method is intended for use with assert statements, * to ensure the change meta-data is in a valid state. * For example, it checks the reference count. */ bool valid(void) const; /** * The version_debian_get method is used to get the version * of this change set, in Debian format. In particular, it * makes being-developed change sets look like they are "release * candidates" for the next project delta, otherwise business as * usual. */ nstring version_debian_get(void); /** * The version_rpm_get method is used to get the version of * this change set, in RPM format. In particular, it makes * being-developed change sets look like they are "branched from" * for the current project delta, otherwise business as usual. */ nstring version_rpm_get(void); /** * The version_get method is used to get the version of this change * set. This will consist of the branch name (1.2) combined with * ether a delta number (.D123) or, for incomplete changes, a * change number (.C123). */ nstring version_get(void); // ---------- W ------------------------------------------------------ /** * The was_a_branch method is used to determine whether or not this * change set is, or was ever, an active branch. If you want to * know if it is a currently active branch (beging_developed) use * the #is_a_branch method. */ bool was_a_branch(void); // ---------- X ------------------------------------------------------ // ---------- Y ------------------------------------------------------ // ---------- Z ------------------------------------------------------ // --------------------------------------------------------------------- // PLEASE keep the above method and instance variable declarations // in strcmp(3) alphabetical order. // // // If you add instance variables to this class, don't forget to update // change::change() in libaegis/change/alloc.cc // change::~change() in libaegis/change/free.cc // change_lock_sync() in libaegis/change/lock_sync.cc // private: /** * The default constructor. * Do not use. * Use the #change::create class method instead. */ change(); }; DEPRECATED // use change::bind_existing instead void change_bind_existing(const change::pointer &cp); DEPRECATED // use change::bind_existing_errok instead bool change_bind_existing_errok(const change::pointer &cp); DEPRECATED // use chnage::bind_new() instead void change_bind_new(const change::pointer &cp); DEPRECATED // use #change::bogus instead change::pointer change_bogus(project *); DEPRECATED// use vhange::history_new instead` cstate_history_ty *change_history_new(const change::pointer &cp, const user_ty::pointer &up); DEPRECATED // use change::development_directory_set instead void change_development_directory_set(string_ty *path); DEPRECATED // use change::development_directory_set instead void change_integration_directory_set(const change::pointer &cp, const nstring &path); DEPRECATED // use change::development_directory_get instead. string_ty *change_development_directory_get(const change::pointer &cp, bool resolve); DEPRECATED // use change::integration_directory_get instead. string_ty *change_integration_directory_get(const change::pointer &cp, bool resolve); DEPRECATED // use change::logfile_basename instead nstring change_logfile_basename(void); DEPRECATED // use change::logfile_get instead string_ty *change_logfile_get(const change::pointer &cp); void change_cstate_lock_prepare(const change::pointer &cp); void change_error(const change::pointer &cp, sub_context_ty *, const char *); void change_fatal(const change::pointer &cp, sub_context_ty *, const char *) NORETURN; void change_verbose(const change::pointer &cp, sub_context_ty *, const char *); /** * The change_warning function is used to issue a warning message * specific to a change. The message will be substituted accouring * to aesub(5) and any additional substitutions provided in the * substitution context. */ void change_warning(const change::pointer &cp, sub_context_ty *, const char *); /** * The change_warning_obsolete_field function is used to warn about the * use of obsolete fields (in user suppied files, Aegis will take care * of quietly cleaning up the meta-data files all by itself). */ void change_warning_obsolete_field(change::pointer cp, string_ty *errpos, const char *old_field, const char *new_field); pconf_ty *change_pconf_get(const change::pointer &cp, bool); // use cp->run_new_file_command instead void change_run_new_file_command(change::pointer cp, string_list_ty *slp, user_ty::pointer up) DEPRECATED; // use cp->run_new_file_undo_command instead void change_run_new_file_undo_command(change::pointer cp, string_list_ty *slp, user_ty::pointer up) DEPRECATED; // use cp->run_new_test_command instead void change_run_new_test_command(change::pointer cp, string_list_ty *slp, user_ty::pointer up) DEPRECATED; // use cp->run_new_test_undo_command instead void change_run_new_test_undo_command(change::pointer cp, string_list_ty *slp, user_ty::pointer up) DEPRECATED; // use cp->run_copy_file_command instead void change_run_copy_file_command(change::pointer cp, string_list_ty *slp, user_ty::pointer up) DEPRECATED; // use cp->run_copy_file_undo_command instead void change_run_copy_file_undo_command(change::pointer cp, string_list_ty *slp, user_ty::pointer up) DEPRECATED; // use cp->run_remove_file_command instead void change_run_remove_file_command(change::pointer cp, string_list_ty *slp, user_ty::pointer up) DEPRECATED; // use cp->run_remove_file_undo_command instead void change_run_remove_file_undo_command(change::pointer cp, string_list_ty *slp, user_ty::pointer up) DEPRECATED; // use cp->run_make_transparent_command instead void change_run_make_transparent_command(change::pointer cp, string_list_ty *slp, user_ty::pointer up) DEPRECATED; // use cp->run_make_transparent_undo_command instead void change_run_make_transparent_undo_command(change::pointer cp, string_list_ty *slp, user_ty::pointer up) DEPRECATED; // use cp->run_project_file_command_needed() instead int change_run_project_file_command_needed(change::pointer cp) DEPRECATED; // use cp->run_project_file_command(up) instead void change_run_project_file_command(change::pointer cp, user_ty::pointer up) DEPRECATED; // use cp->run_forced_develop_begin_notify_command instead void change_run_forced_develop_begin_notify_command(change::pointer cp, user_ty::pointer up) DEPRECATED; // use cp->run_develop_end_notify_command instead void change_run_develop_end_notify_command(change::pointer cp) DEPRECATED; // use cp->run_develop_end_undo_notify_command instead void change_run_develop_end_undo_notify_command(change::pointer cp) DEPRECATED; // use cp->run_review_begin_notify_command instead void change_run_review_begin_notify_command(change::pointer cp) DEPRECATED; // use cp->run_review_begin_undo_notify_command void change_run_review_begin_undo_notify_command(change::pointer cp) DEPRECATED; // use cp->run_review_pass_notify_command instead void change_run_review_pass_notify_command(change::pointer cp) DEPRECATED; // use cp->run_review_pass_undo_notify_command instead void change_run_review_pass_undo_notify_command(change::pointer cp) DEPRECATED; // use cp->run_review_fail_notify_command instead void change_run_review_fail_notify_command(change::pointer cp) DEPRECATED; // use cp->run_integrate_pass_notify_command instead void change_run_integrate_pass_notify_command(change::pointer cp) DEPRECATED; // use cp->run_integrate_fail_notify_command instead void change_run_integrate_fail_notify_command(change::pointer cp) DEPRECATED; void change_run_history_get_command(change::pointer cp, fstate_src_ty *src, string_ty *output_file, user_ty::pointer up); void change_run_history_create_command(change::pointer cp, fstate_src_ty *); void change_run_history_put_command(change::pointer cp, fstate_src_ty *); /** * The change_run_history_query_command function is used to obtain the * head revision number of the history of the given source file. * * @param cp * The change to operate within. * @param src * The source file meta-data of the file of interest. * @returns * Pointer to string containing the version. Use str_free() when * you are done with it. */ string_ty *change_run_history_query_command(change::pointer cp, fstate_src_ty *src); void change_run_history_label_command(change::pointer cp, fstate_src_ty *, string_ty *label); /** * The change_run_history_transaction_begin_command function is * used to run the history_transaction_begin_command in the project * configuration file. This is used by the aeipass(1) command before * any history put or create commands. * * @param cp * The change to operate within. */ void change_run_history_transaction_begin_command(change::pointer cp); /** * The change_run_history_transaction_end_command function is * used to run the history_transaction_end_command in the project * configuration file. This is used by the aeipass(1) command after * any history put or create commands. * * @param cp * The change to operate within. */ void change_run_history_transaction_end_command(change::pointer cp); /** * The change_run_history_transaction_abort_command function is * used to run the history_transaction_abort_command in the project * configuration file. This is used by the aeipass(1) command if * a history transaction needs to be aborted. * * @param cp * The change to operate within. */ void change_run_history_transaction_abort_command(change::pointer cp); void change_history_trashed_fingerprints(const change::pointer &cp, string_list_ty *); void change_run_diff_command(change::pointer cp, user_ty::pointer up, string_ty *original, string_ty *input, string_ty *output); void change_run_diff3_command(change::pointer cp, user_ty::pointer up, string_ty *original, string_ty *most_recent, string_ty *input, string_ty *output); void change_run_merge_command(change::pointer cp, user_ty::pointer up, string_ty *original, string_ty *most_recent, string_ty *input, string_ty *output); void change_run_patch_diff_command(change::pointer cp, user_ty::pointer up, string_ty *original, string_ty *input, string_ty *output, string_ty *index_name); void change_run_annotate_diff_command(change::pointer cp, user_ty::pointer up, string_ty *original, string_ty *input, string_ty *output, string_ty *index_name, const char *diff_option); bool change_has_merge_command(const change::pointer &cp); void change_run_integrate_begin_command(const change::pointer &cp); void change_run_integrate_begin_undo_command(const change::pointer &cp); void change_run_develop_begin_command(change::pointer cp, user_ty::pointer up) DEPRECATED; void change_run_develop_begin_undo_command(change::pointer cp, user_ty::pointer up); int change_run_test_command(change::pointer cp, user_ty::pointer up, string_ty *, string_ty *, int, int, const nstring_list &variable_assignments); int change_run_development_test_command(change::pointer cp, user_ty::pointer up, string_ty *, string_ty *, int, int, const nstring_list &variable_assignments); void change_run_build_command(const change::pointer &cp); void change_run_build_time_adjust_notify_command(const change::pointer &cp); void change_run_development_build_command(const change::pointer &cp, user_ty::pointer up, string_list_ty *); /** * The change_run_develop_end_policy_command function is used to * run the develop_end_policy_command specified in the project * configuration file. * * @param cp * The change in question. * @param up * The developer of the change. * @note * This function does not return if the command exits with a * non-zero exit status. */ void change_run_develop_end_policy_command(change::pointer cp, user_ty::pointer up); string_ty *change_file_whiteout(const change::pointer &cp, string_ty *filename); void change_file_whiteout_write(change::pointer cp, string_ty *path, user_ty::pointer up); void change_become(const change::pointer &cp); void change_become_undo(const change::pointer &cp); void change_developer_become(const change::pointer &cp); void change_developer_become_undo(change::pointer cp); DEPRECATED // use change::development_directory_clear instead void change_development_directory_clear(const change::pointer &cp); void change_integration_directory_clear(const change::pointer &cp); void change_architecture_clear(const change::pointer &cp); void change_architecture_add(const change::pointer &cp, string_ty *); void change_architecture_query(const change::pointer &cp); string_ty *change_architecture_name(const change::pointer &cp, int); string_ty *change_run_architecture_discriminator_command(change::pointer cp); cstate_architecture_times_ty *change_architecture_times_find( const change::pointer &cp, string_ty *name); void change_build_time_set(const change::pointer &cp); /** * The change_test_time_set function is used to set the test time for a * change. The architecture of the currently executing session is used. * * @param cp * The change in question. * @param when * The time the test was performed. */ void change_test_time_set(change::pointer cp, time_t when); /** * The change_test_time_set function is used to set the test time for a * change, for the given architecture variant. * * @param cp * The change in question. * @param variant * The name of the architecture of interest. * @param when * The time the test was performed. */ void change_test_time_set(change::pointer cp, string_ty *variant, time_t when); /** * The change_test_baseline_time_set function is used to set the * baseline test time for a change. The architecture of the currently * executing session is used. * * @param cp * The change in question. * @param when * The time the test was performed. */ void change_test_baseline_time_set(change::pointer cp, time_t when); /** * The change_test_baseline_time_set function is used to set the test * time for a change, for the given architecture variant. * * @param cp * The change in question. * @param variant * The name of the architecture of interest. * @param when * The time the test was performed. */ void change_test_baseline_time_set(change::pointer cp, string_ty *variant, time_t when); /** * The change_regression_test_time_set function is used to set (or * clear) the regression test time stamp of the chanegh set. * * @param cp * The change set in question. * @param when * The time the test was performed, or zero to clear the time. * @param arch_name * The name of the architecture, or the NULL pointer to mean "the * current one". */ void change_regression_test_time_set(change::pointer cp, time_t when, string_ty *arch_name = 0); void change_test_times_clear(const change::pointer &cp); void change_build_times_clear(const change::pointer &cp); void change_architecture_from_pconf(const change::pointer &cp); const char *change_outstanding_builds(const change::pointer &cp, time_t); const char *change_outstanding_tests(const change::pointer &cp, time_t); const char *change_outstanding_tests_baseline(const change::pointer &cp, time_t when); const char *change_outstanding_tests_regression(const change::pointer &cp, time_t when); int change_pathconf_name_max(const change::pointer &cp); string_ty *change_filename_check(const change::pointer &cp, string_ty *); void change_create_symlinks_to_baseline(const change::pointer &cp, user_ty::pointer up, const work_area_style_ty &); /** * The change_maintain_symlinks_to_baseline is used to repair the * symbolic links (etc) as dictated by the development_directory_style * field of the project configuration file. * * The "symlink" in the name is an historical accident, it also * maintains the hard links and copies as well. * * @param cp * The change to operatte on * @param up * The user to operate as * @param undoing * True if this call is in response to and undo operation (aecpu, * aemtu) because they need special attention for file time stamps. * Defaults to false if not specified. * * @note * This function is NOT to be called by aeb, because it needs * different logic. * @note * This function may only be called when the change is in the * "being developed" state. */ void change_maintain_symlinks_to_baseline(change::pointer cp, user_ty::pointer up, bool undoing = false); void change_remove_symlinks_to_baseline(const change::pointer &cp, user_ty::pointer up, const work_area_style_ty &); void change_rescind_test_exemption(const change::pointer &cp); DEPRECATED inline nstring change_fstate_filename_get(change::pointer cp) { return cp->fstate_filename_get(); } DEPRECATED string_ty *change_pfstate_filename_get(change::pointer cp); void change_rescind_test_exemption_undo(const change::pointer &cp); void change_force_regression_test_exemption(const change::pointer &cp); void change_force_regression_test_exemption_undo(const change::pointer &cp); void change_check_architectures(const change::pointer &cp); string_ty *change_new_test_filename_get(const change::pointer &cp, long n, bool is_auto); string_ty *change_development_directory_template(const change::pointer &cp, user_ty::pointer up); string_ty *change_metrics_filename_pattern_get(const change::pointer &cp); /** * The change_uuid_set function is used to set a change's UUID, * if it has not been set already. */ void change_uuid_set(const change::pointer &cp); /** * The change_uuid_clear function is used to clear a change's UUID, * if it has been set in the past. */ void change_uuid_clear(const change::pointer &cp); /** * The change_reviewer_list function is used to get the list of * reviewers since the last develop_end. There can be more than one * if the review_policy_command filed of the project configuration is * being used. * * @param cp * The change to be consulted. * @param result * where to put the answers. */ void change_reviewer_list(const change::pointer &cp, string_list_ty &result); /** * The change_reviewer_already function is used to determine if a user * has already reviewed a change, since the last develop end. * * @param cp * The change to be consulted. * @param login * The login name of the user in question. * @returns * bool; true if the user has reviewed already, false if not. */ bool change_reviewer_already(const change::pointer &cp, string_ty *login); /** * The change_reviewer_already function is used to determine if a user * has already reviewed a change, since the last develop end. * * @param cp * The change to be consulted. * @param login * The login name of the user in question. * @returns * bool; true if the user has reviewed already, false if not. */ bool change_reviewer_already(const change::pointer &cp, const nstring &login); /** * The change_when_get function is used to obtain the last (most * recent) time for the given state transition. * * @param cp * The change in qiestion. * @param what * The state transition to look for. * @returns * time_t; the time of the event, or 0 if not found. */ time_t change_when_get(const change::pointer &cp, cstate_history_what_ty what); /** * The change_diff_required function is used to see of the project (and * this specific change set) need the diff command to be run. * * @param cp * The change in question. * @returns * bool; true if diff command needs to be run, false if not. */ bool change_diff_required(change::pointer cp); /** * The change_build_required function is used to see of the project (and * this specific change set) need the build command to be run. * * @param cp * The change in question. * @param conf_exists * true if the project configuration file must exist (causing fatal * error if it does not), or false if it doesn't matter. * @returns * bool; true if build command needs to be run, false if not. */ bool change_build_required(change::pointer cp, bool conf_exists = true); /** * The change_find_architecture_variant function is used to obtain a * pointer to the architecture variant data for the currently executing * architecture. * * @param cp * The change in question. * @returns * a pointer to the desired data structure. It is never NULL. */ cstate_architecture_times_ty *change_find_architecture_variant( const change::pointer &cp); /** * The change_find_architecture_variant function is used to obtain a * pointer to the architecture variant data for the currently executing * architecture. * * @param cp * The change in question. * @param variant * The name of the architecture of interest. * @returns * a pointer to the desired data structure. It is never NULL. */ cstate_architecture_times_ty *change_find_architecture_variant( const change::pointer &cp, string_ty *variant); // vim: set ts=8 sw=4 et : #endif // LIBAEGIS_CHANGE_H