def init(p4): """Ensure both global and host-specific initialization are completed. """ started_counter = p4gf_const.P4GF_COUNTER_INIT_STARTED complete_counter = p4gf_const.P4GF_COUNTER_INIT_COMPLETE _maybe_perform_init(p4, started_counter, complete_counter, _global_init) client_name = p4gf_util.get_object_client_name() started_counter = client_name + '-init-started' complete_counter = client_name + '-init-complete' home = os.environ.get("HOME") p4gf_dir = os.path.join(home, p4gf_const.P4GF_DIR) def client_init(p4): '''Perform host-specific initialization (and create sample usermap).''' # Set up the host-specific client. _create_client(p4, client_name, p4gf_dir) # Ensure the default user map file is in place. _write_user_map(p4, client_name, p4gf_dir) if not _maybe_perform_init(p4, started_counter, complete_counter, client_init): # If client already created, make sure it hasn't been tweaked. ###: do we really need to handle this case? this is here just to pass the tests view = ['//{depot}/... //{client}/...'.format(depot=p4gf_const.P4GF_DEPOT, client=client_name)] p4gf_util.ensure_spec_values(p4, "client", client_name, {'Root': p4gf_dir, 'View': view})
def init(p4): """Ensure both global and host-specific initialization are completed. """ started_counter = p4gf_const.P4GF_COUNTER_INIT_STARTED complete_counter = p4gf_const.P4GF_COUNTER_INIT_COMPLETE if not old_counter_present(p4): Verbosity.report(Verbosity.DEBUG, _('Old 2012.2 counter not present.')) if not _maybe_perform_init(p4, started_counter, complete_counter, _global_init): Verbosity.report(Verbosity.INFO, _('Permissions already initialized. Not changing.')) server_id = p4gf_util.get_server_id() started_counter = p4gf_const.P4GF_COUNTER_INIT_STARTED + '-' + server_id complete_counter = p4gf_const.P4GF_COUNTER_INIT_COMPLETE + '-' + server_id p4gf_dir = p4gf_const.P4GF_HOME client_name = p4gf_util.get_object_client_name() def client_init(p4): '''Perform host-specific initialization (and create sample usermap).''' # Set up the host-specific client. _create_client(p4, client_name, p4gf_dir) # Ensure the default user map and global config files are in place. _write_user_map(p4, client_name, p4gf_dir) p4gf_config.create_file_global(p4) _delete_old_init_counters(p4, server_id) if not _maybe_perform_init(p4, started_counter, complete_counter, client_init): Verbosity.report( Verbosity.INFO, _('Client and usermap already initialized. Not changing.')) # If client already created, make sure it hasn't been tweaked. ###: do we really need to handle this case? this is here just to pass the tests view = [ '//{depot}/... //{client}/...'.format(depot=p4gf_const.P4GF_DEPOT, client=client_name) ] p4gf_util.ensure_spec_values(p4, 'client', client_name, { 'Root': p4gf_dir, 'View': view }) # Perform any necessary upgrades within a "lock" to avoid race conditions. # For now, the lock is global, but could conceivably loosen to host-only. started_counter = p4gf_const.P4GF_COUNTER_UPGRADE_STARTED complete_counter = p4gf_const.P4GF_COUNTER_UPGRADE_COMPLETE if not _maybe_perform_init(p4, started_counter, complete_counter, _upgrade_p4gf): Verbosity.report( Verbosity.INFO, _('Global config file already initialized. Not changing.')) # Require non-empty Git config user.name and user.email. _ensure_git_config_non_empty('user.name', _('Git Fusion Machinery')) _ensure_git_config_non_empty('user.email', _('*****@*****.**'))
def create_p4_client(p4, view_name, client_name, client_root): """Create the p4 client to contain Git meta-data mirror. Keyword arguments: p4 -- Perforce client API view_name -- client view of repository to clone client_name -- client that will be created client_root -- path for client workspace Returns one of the INIT_REPO_* constants. """ # Ensure the client root directory has been created. if not os.path.exists(client_root): os.makedirs(client_root) # If a client for this view already exists, we're probably done. # # Make sure the client root is correct. if p4gf_util.spec_exists(p4, 'client', client_name): LOG.debug("%s client already exists for %s", client_name, view_name) p4gf_util.ensure_spec_values(p4, 'client', client_name, {'Root':client_root}) return INIT_REPO_EXISTS # Client does not yet exist. We'll have to configure it manually, using # the view's name as a template. if not p4gf_util.spec_exists(p4, 'client', view_name): LOG.warn("requested client %s does not exist, required for creating a mirror", view_name) sys.stderr.write("View {} does not exist\n".format(view_name)) return INIT_REPO_NOVIEW # Seed a new client using the view's view as a template. LOG.info("client %s does not exist, creating from view %s", client_name, view_name) view = p4gf_util.first_value_for_key( p4.run('client', '-o', '-t', view_name, client_name), 'View') if not view_depots_ok(p4, view_name, view): # nature of problem already reported return INIT_REPO_BADVIEW desc = ("Created by Perforce Git Fusion for work in {view}." .format(view=view_name)) p4gf_util.set_spec(p4, 'client', spec_id=client_name, values={'Owner' : p4gf_const.P4GF_USER, 'LineEnd' : 'unix', 'View' : view, 'Root' : client_root, 'Host' : None, 'Description' : desc}) LOG.debug("successfully created client %s", client_name) return INIT_REPO_OK
def _set_view_lines(self, client_name, view_lines): ''' Change an existing client's view. ''' new_view_map = p4gf_branch.replace_client_name( view_lines, self.ctx.config.p4client, client_name) if LOG.isEnabledFor(logging.DEBUG3): LOG.debug3('_set_view_lines() name={} view={}'.format( client_name, new_view_map.as_array())) else: LOG.debug2('_set_view_lines() name={}'.format(client_name)) p4gf_util.ensure_spec_values(self.ctx.p4gf, 'client', client_name, {'View': new_view_map.as_array()})
def ensure_group(): """Create Perforce group git-fusion-group if not already exists.""" users = [] # Keep the order of the users in the same order that P4 insists on # (if the order doesn't match then the group is updated repeatedly). users.append(p4gf_const.P4GF_REVIEWS__ALL_GF) users.append(p4gf_const.P4GF_REVIEWS__NON_GF) users.append(p4gf_util.gf_reviews_user_name()) users.append(p4gf_const.P4GF_USER) args = [p4, NTR("group")] spec = {'Timeout': NTR('unlimited'), 'Users': users} kwargs = {'spec_id': p4gf_const.P4GF_GROUP, 'values': spec} if not p4gf_util.ensure_spec(*args, **kwargs): # We change the list of users in the group from time to time, # so ensure the membership is up to date. users = p4gf_util.first_dict(p4.run('group', '-o', p4gf_const.P4GF_GROUP))['Users'] # Add the gf_reviews_user_name if not already in the group. # This avoids removing already existing reviews users from multiple GF instances. if not p4gf_util.gf_reviews_user_name() in users: users.append(p4gf_util.gf_reviews_user_name()) spec = {'Timeout': NTR('unlimited'), 'Users': users} kwargs = {'spec_id': p4gf_const.P4GF_GROUP, 'values': spec} if p4gf_util.ensure_spec_values(*args, **kwargs): Verbosity.report(Verbosity.INFO , _("Group '{}' updated.").format(p4gf_const.P4GF_GROUP)) else: Verbosity.report(Verbosity.INFO, _("Group '{}' already up to date.") .format(p4gf_const.P4GF_GROUP)) else: Verbosity.report(Verbosity.INFO, _("Group '{}' already up to date.") .format(p4gf_const.P4GF_GROUP)) return False else: Verbosity.report(Verbosity.INFO, _("Group '{}' created.").format(p4gf_const.P4GF_GROUP)) return True
def _create_client(p4, client_name, p4gf_dir): """Create the host-specific Perforce client to enable working with the object cache in the P4GF_DEPOT depot. """ # to prevent the mirrored git commit/tree objects from being retained in the # git-fusion workspace, set client option 'rmdir' and sync #none in p4gf_gitmirror # Assume the usual P4 client default options are being used so that # these options below differ ONLY with normdir -> rmdir # if this assumption proves troublesome, then read/write cycle will be needed. options = NTR('allwrite clobber nocompress unlocked nomodtime rmdir') view = ['//{depot}/... //{client}/...'.format(depot=p4gf_const.P4GF_DEPOT, client=client_name)] spec_created = False if not p4gf_util.spec_exists(p4, 'client', client_name): # See if the old object clients exist, in which case we will remove them. for old_client_name in [OLD_OBJECT_CLIENT, OLDER_OBJECT_CLIENT]: if p4gf_util.spec_exists(p4, 'client', old_client_name): p4.run('client', '-df', old_client_name) _info(_("Old client '{}' deleted.").format(old_client_name)) spec_created = p4gf_util.ensure_spec( p4, 'client', spec_id=client_name, values={'Host': None, 'Root': p4gf_dir, 'Description': _('Created by Perforce Git Fusion'), 'Options': options, 'View': view}) if spec_created: _info(_("Client '{}' created.").format(client_name)) if not spec_created: modified = p4gf_util.ensure_spec_values(p4, 'client', client_name, {'Root': p4gf_dir, 'View': view, 'Options': options}) if modified: _info(_("Client '{}' updated.").format(client_name)) else: _info(_("Client '{}' already exists.").format(client_name))
def init(p4): """Ensure both global and host-specific initialization are completed. """ started_counter = p4gf_const.P4GF_COUNTER_INIT_STARTED complete_counter = p4gf_const.P4GF_COUNTER_INIT_COMPLETE if not old_counter_present(p4): Verbosity.report(Verbosity.DEBUG, _('Old 2012.2 counter not present.')) if not _maybe_perform_init(p4, started_counter, complete_counter, _global_init): Verbosity.report(Verbosity.INFO, _('Permissions already initialized. Not changing.')) server_id = p4gf_util.get_server_id() started_counter = p4gf_const.P4GF_COUNTER_INIT_STARTED + '-' + server_id complete_counter = p4gf_const.P4GF_COUNTER_INIT_COMPLETE + '-' + server_id p4gf_dir = p4gf_const.P4GF_HOME client_name = p4gf_util.get_object_client_name() def client_init(p4): '''Perform host-specific initialization (and create sample usermap).''' # Set up the host-specific client. _create_client(p4, client_name, p4gf_dir) # Ensure the default user map and global config files are in place. _write_user_map(p4, client_name, p4gf_dir) p4gf_config.create_file_global(p4) _delete_old_init_counters(p4, server_id) if not _maybe_perform_init(p4, started_counter, complete_counter, client_init): Verbosity.report(Verbosity.INFO, _('Client and usermap already initialized. Not changing.')) # If client already created, make sure it hasn't been tweaked. ###: do we really need to handle this case? this is here just to pass the tests view = ['//{depot}/... //{client}/...'.format(depot=p4gf_const.P4GF_DEPOT, client=client_name)] p4gf_util.ensure_spec_values(p4, 'client', client_name, {'Root': p4gf_dir, 'View': view}) # Perform any necessary upgrades within a "lock" to avoid race conditions. # For now, the lock is global, but could conceivably loosen to host-only. started_counter = p4gf_const.P4GF_COUNTER_UPGRADE_STARTED complete_counter = p4gf_const.P4GF_COUNTER_UPGRADE_COMPLETE if not _maybe_perform_init(p4, started_counter, complete_counter, _upgrade_p4gf): Verbosity.report(Verbosity.INFO, _('Global config file already initialized. Not changing.')) # Require non-empty Git config user.name and user.email. _ensure_git_config_non_empty('user.name', _('Git Fusion Machinery')) _ensure_git_config_non_empty('user.email', _('*****@*****.**'))
def _create_client(p4, client_name, p4gf_dir): """Create the host-specific Perforce client to enable working with the object cache in the .git-fusion depot. """ view = ['//{depot}/... //{client}/...'.format(depot=p4gf_const.P4GF_DEPOT, client=client_name)] spec_created = False if not p4gf_util.spec_exists(p4, "client", client_name): # See if the old object clients exist, in which case we will remove them. if p4gf_util.spec_exists(p4, "client", OLD_OBJECT_CLIENT): p4.run('client', '-df', OLD_OBJECT_CLIENT) if p4gf_util.spec_exists(p4, "client", OLDER_OBJECT_CLIENT): p4.run('client', '-df', OLDER_OBJECT_CLIENT) spec_created = p4gf_util.ensure_spec( p4, "client", spec_id=client_name, values={'Host': None, 'Root': p4gf_dir, 'Description': 'Created by Perforce Git Fusion', 'View': view}) if not spec_created: p4gf_util.ensure_spec_values(p4, "client", client_name, {'Root': p4gf_dir, 'View': view})
def _create_client(p4, client_name, p4gf_dir): """Create the host-specific Perforce client to enable working with the object cache in the P4GF_DEPOT depot. """ # to prevent the mirrored git commit/tree objects from being retained in the # git-fusion workspace, set client option 'rmdir' and sync #none in p4gf_gitmirror # Assume the usual P4 client default options are being used so that # these options below differ ONLY with normdir -> rmdir # if this assumption proves troublesome, then read/write cycle will be needed. options = NTR('allwrite clobber nocompress unlocked nomodtime rmdir') view = [ '//{depot}/... //{client}/...'.format(depot=p4gf_const.P4GF_DEPOT, client=client_name) ] spec_created = False if not p4gf_util.spec_exists(p4, 'client', client_name): # See if the old object clients exist, in which case we will remove them. for old_client_name in [OLD_OBJECT_CLIENT, OLDER_OBJECT_CLIENT]: if p4gf_util.spec_exists(p4, 'client', old_client_name): p4.run('client', '-df', old_client_name) _info(_("Old client '{}' deleted.").format(old_client_name)) spec_created = p4gf_util.ensure_spec( p4, 'client', spec_id=client_name, values={ 'Host': None, 'Root': p4gf_dir, 'Description': _('Created by Perforce Git Fusion'), 'Options': options, 'View': view }) if spec_created: _info(_("Client '{}' created.").format(client_name)) if not spec_created: modified = p4gf_util.ensure_spec_values(p4, 'client', client_name, { 'Root': p4gf_dir, 'View': view, 'Options': options }) if modified: _info(_("Client '{}' updated.").format(client_name)) else: _info(_("Client '{}' already exists.").format(client_name))
def ensure_group(): """Create Perforce group git-fusion-group if not already exists.""" users = [] # Keep the order of the users in the same order that P4 insists on # (if the order doesn't match then the group is updated repeatedly). users.append(p4gf_const.P4GF_REVIEWS__ALL_GF) users.append(p4gf_const.P4GF_REVIEWS__NON_GF) users.append(p4gf_util.gf_reviews_user_name()) users.append(p4gf_const.P4GF_USER) args = [p4, NTR("group")] spec = {'Timeout': NTR('unlimited'), 'Users': users} kwargs = {'spec_id': p4gf_const.P4GF_GROUP, 'values': spec} if not p4gf_util.ensure_spec(*args, **kwargs): # We change the list of users in the group from time to time, # so ensure the membership is up to date. users = p4gf_util.first_dict( p4.run('group', '-o', p4gf_const.P4GF_GROUP))['Users'] # Add the gf_reviews_user_name if not already in the group. # This avoids removing already existing reviews users from multiple GF instances. if not p4gf_util.gf_reviews_user_name() in users: users.append(p4gf_util.gf_reviews_user_name()) spec = {'Timeout': NTR('unlimited'), 'Users': users} kwargs = {'spec_id': p4gf_const.P4GF_GROUP, 'values': spec} if p4gf_util.ensure_spec_values(*args, **kwargs): Verbosity.report( Verbosity.INFO, _("Group '{}' updated.").format(p4gf_const.P4GF_GROUP)) else: Verbosity.report( Verbosity.INFO, _("Group '{}' already up to date.").format( p4gf_const.P4GF_GROUP)) else: Verbosity.report( Verbosity.INFO, _("Group '{}' already up to date.").format( p4gf_const.P4GF_GROUP)) return False else: Verbosity.report( Verbosity.INFO, _("Group '{}' created.").format(p4gf_const.P4GF_GROUP)) return True
def main(): """Process command line arguments and call functions to do the real work of cleaning up the Git mirror and Perforce workspaces. """ # Set up argument parsing. parser = p4gf_util.create_arg_parser( "Convert 2012.2 Git Fusion configured Perforce Server for use with" " 2013.1 Git Fusion.\nThis is not reversable.") parser.add_argument("-y", "--convert", action="store_true", help="perform the conversion") parser.add_argument("-d", "--delete", action="store_true", help="skip obliterate and show delete command") parser.add_argument( '--id', nargs=1, help="Set this Git Fusion server's unique id. Default is hostname.") args = parser.parse_args() # Do not run as root, this is very git account specific user = getpass.getuser() if user == "root": print("This script should be run using the Git dedicated account") return 2 if args.convert: try: global LOG_FILE # pylint:disable=W1501 # "x" is not a valid mode for open. # Yes it is. Pylint 1.0.0 is incorrect here. LOG_FILE = open("p4gf_convert_v12_2.log", "x") # pylint:enable=W1501 print("Logging to p4gf_convert_v12_2.log") except IOError: print("Please remove or rename p4gf_convert_v12_2.log") sys.exit(1) client_name = p4gf_const.P4GF_OBJECT_CLIENT_PREFIX + p4gf_util.get_hostname( ) try: p4 = p4gf_create_p4.create_p4(client=client_name) except RuntimeError as e: sys.stderr.write("{}\n".format(e)) sys.exit(1) if not p4: return 2 # Sanity check the connection (e.g. user logged in?) before proceeding. try: p4.fetch_client() view = [ '//{depot}/... //{client}/...'.format(depot=p4gf_const.P4GF_DEPOT, client=client_name) ] spec = { 'Host': '', 'Root': os.path.join(os.environ.get("HOME"), p4gf_const.P4GF_DIR), 'View': view } p4gf_util.ensure_spec_values(p4, 'client', client_name, spec) except P4.P4Exception as e: sys.stderr.write("P4 exception occurred: {}".format(e)) sys.exit(1) try: convert(args, p4) except P4.P4Exception as e: sys.stderr.write("{}\n".format(e)) sys.exit(1) if not args.convert: print("This was report mode. Use -y to make changes.") else: print("Commands run were logged to p4gf_convert_v12_2.log.") if args.delete: print("You must now run: p4 delete //.git-fusion/objects/...") print(" p4 submit") print(" Use a client which has this location in its view") LOG_FILE.write( "Need to run: p4 delete //.git-fusion/objects/...\n") LOG_FILE.write(" p4 submit\n") LOG_FILE.close()
def _create_p4_client(p4, view_name, client_name, client_root, enable_mismatched_rhs, view_name_p4client, handle_imports=True): """Create the p4 client to contain Git meta-data mirror. Keyword arguments: p4 -- Perforce client API view_name -- client view of repository to clone - internal (translated) viewname client_name -- client that will be created client_root -- path for client workspace enable_mismatched_rhs -- allow branches to have differing RHS? view_name_p4client -- name of actual p4 client on which to base this new repo if None - will be determined from view_name if needed Returns one of the INIT_REPO_* constants. """ # Ensure the client root directory has been created. if not os.path.exists(client_root): os.makedirs(client_root) view_name_git = p4gf_translate.TranslateReponame.repo_to_git(view_name) LOG.debug("_create_p4_client(): view_name_git {0} view_name {1} view_name_p4client {2}". format(view_name_git, view_name ,view_name_p4client)) # If a Git Fusion client for this view already exists, use that, # no need to init the repo. # Do make sure that the client root is correct. if p4gf_util.spec_exists(p4, 'client', client_name): LOG.debug("%s client already exists for %s", client_name, view_name) p4gf_util.ensure_spec_values(p4, 'client', client_name , { 'Root' : client_root , 'Options' : CLIENT_OPTIONS }) return INIT_REPO_EXISTS # Repo config file already checked into Perforce? # Use that. config_path = p4gf_config.depot_path_repo(view_name) config_exists = p4gf_util.depot_file_exists(p4, config_path) if config_exists: return repo_from_config( p4, view_name, client_name, client_root , enable_mismatched_rhs) # Client exist with the same name as this Git Fusion repo? # Build a new config, check it into Perforce, and use that. if not view_name_p4client: view_name_p4client = p4gf_translate.TranslateReponame.git_to_p4client(view_name_git) nop4client = '' if p4gf_util.spec_exists(p4, 'client', view_name_p4client): return repo_from_template_client( p4, view_name, view_name_p4client, client_name , client_root , enable_mismatched_rhs) else: nop4client = _("p4 client '{0}' does not exist\n").format(view_name_p4client) # creating repo from stream? # note that we can't pass '//depot/stream' because git would be confused # but it's ok to pass 'depot/stream' and add the leading '//' here stream_name = '//'+view_name_git if p4gf_util.spec_exists(p4, 'stream', stream_name): return _repo_from_stream(p4, view_name, stream_name, client_name, client_root, enable_mismatched_rhs, handle_imports) # We don't have, and cannot create, a config for this repo. # Say so and give up. msg = p4gf_const.NO_REPO_MSG_TEMPLATE.format(view_name=view_name ,view_name_p4client=view_name_p4client ,nop4client=nop4client) LOG.warn(msg) _print_stderr(msg) return INIT_REPO_NOVIEW
def main(): """Process command line arguments and call functions to do the real work of cleaning up the Git mirror and Perforce workspaces. """ # Set up argument parsing. parser = p4gf_util.create_arg_parser( "Convert 2012.2 Git Fusion configured Perforce Server for use with" " 2013.1 Git Fusion.\nThis is not reversable.") parser.add_argument("-y", "--convert", action="store_true", help="perform the conversion") parser.add_argument("-d", "--delete", action="store_true", help="skip obliterate and show delete command") parser.add_argument('--id', nargs=1, help="Set this Git Fusion server's unique id. Default is hostname.") args = parser.parse_args() # Do not run as root, this is very git account specific user = getpass.getuser() if user == "root": print("This script should be run using the Git dedicated account") return 2 if args.convert: try: global LOG_FILE # pylint:disable=W1501 # "x" is not a valid mode for open. # Yes it is. Pylint 1.0.0 is incorrect here. LOG_FILE = open("p4gf_convert_v12_2.log", "x") # pylint:enable=W1501 print("Logging to p4gf_convert_v12_2.log") except IOError: print("Please remove or rename p4gf_convert_v12_2.log") sys.exit(1) client_name = p4gf_const.P4GF_OBJECT_CLIENT_PREFIX + p4gf_util.get_hostname() try: p4 = p4gf_create_p4.create_p4(client=client_name) except RuntimeError as e: sys.stderr.write("{}\n".format(e)) sys.exit(1) if not p4: return 2 # Sanity check the connection (e.g. user logged in?) before proceeding. try: p4.fetch_client() view = ['//{depot}/... //{client}/...'.format( depot=p4gf_const.P4GF_DEPOT, client=client_name)] spec = {'Host': '', 'Root': os.path.join(os.environ.get("HOME"), p4gf_const.P4GF_DIR), 'View': view} p4gf_util.ensure_spec_values(p4, 'client', client_name, spec) except P4.P4Exception as e: sys.stderr.write("P4 exception occurred: {}".format(e)) sys.exit(1) try: convert(args, p4) except P4.P4Exception as e: sys.stderr.write("{}\n".format(e)) sys.exit(1) if not args.convert: print("This was report mode. Use -y to make changes.") else: print("Commands run were logged to p4gf_convert_v12_2.log.") if args.delete: print("You must now run: p4 delete //.git-fusion/objects/...") print(" p4 submit") print(" Use a client which has this location in its view") LOG_FILE.write("Need to run: p4 delete //.git-fusion/objects/...\n") LOG_FILE.write(" p4 submit\n") LOG_FILE.close()
def delete_client(args, p4, client_name, metrics, prune_objs=True): """Delete the named Perforce client and its workspace. Raises P4Exception if the client is not present, or the client configuration is not set up as expected. Keyword arguments: args -- parsed command line arguments p4 -- Git user's Perforce client client_name -- name of client to be deleted metrics -- DeletionMetrics for collecting resulting metrics prune_objs -- if True, delete associated objects from cache """ # pylint: disable=R0912,R0915 group_list = [ p4gf_const.P4GF_GROUP_VIEW_PULL, p4gf_const.P4GF_GROUP_VIEW_PUSH ] p4.user = p4gf_const.P4GF_USER print_verbose(args, _("Checking for client '{}'...").format(client_name)) if not p4gf_util.spec_exists(p4, 'client', client_name): raise P4.P4Exception( _("No such client '{}' defined").format(client_name)) view_name = p4gf_util.client_to_view_name(client_name) p4gf_dir = p4gf_util.p4_to_p4gf_dir(p4) view_dirs = p4gf_view_dirs.from_p4gf_dir(p4gf_dir, view_name) p4gf_util.ensure_spec_values(p4, 'client', client_name, {'Root': view_dirs.p4root}) view_lock = None # We're clobbering and deleting. Overrule locks. with p4gf_context.create_context(view_name, view_lock) as ctx: command_path = ctx.client_view_path() homedir = os.path.expanduser('~') raise_if_homedir(homedir, view_name, view_dirs.view_container) # Scan for objects associated only with this view so we can remove them. objects_to_delete = [] if prune_objs: objects_to_delete = _find_client_commit_objects( args, p4, view_name) # Do we have a repo config file to delete? config_file = p4gf_config.depot_path_repo(view_name) + '*' config_file_exists = p4gf_util.depot_file_exists(p4, config_file) # What counters shall we delete? counter_list = [] counter_list.append( p4gf_context.calc_last_copied_change_counter_name( view_name, p4gf_util.get_server_id())) for spec in p4.run('counters', '-u', '-e', "git-fusion-index-last-{},*".format(view_name)): counter_list.append(spec['counter']) for spec in p4.run('counters', '-u', '-e', "git-fusion-index-branch-{},*".format(view_name)): counter_list.append(spec['counter']) if not args.delete: print(NTR('p4 sync -f {}#none').format(command_path)) print(NTR('p4 client -f -d {}').format(client_name)) print(NTR('rm -rf {}').format(view_dirs.view_container)) print( NTR('Deleting {} objects from //{}/objects/...').format( len(objects_to_delete), p4gf_const.P4GF_DEPOT)) for group_template in group_list: group = group_template.format(view=view_name) print(NTR('p4 group -a -d {}').format(group)) for c in counter_list: print(NTR('p4 counter -u -d {}').format(c)) if config_file_exists: print(NTR('p4 sync -f {}').format(config_file)) print(NTR('p4 delete {}').format(config_file)) print( NTR('p4 submit -d "Delete repo config for {view_name}" {config_file}' ).format(view_name=view_name, config_file=config_file)) else: print_verbose( args, NTR('Removing client files for {}...').format(client_name)) ctx.p4.run('sync', '-fq', command_path + '#none') print_verbose(args, NTR('Deleting client {}...').format(client_name)) p4.run('client', '-df', client_name) metrics.clients += 1 print_verbose( args, NTR("Deleting repo {0}'s directory {1}...").format( view_name, view_dirs.view_container)) _remove_tree(view_dirs.view_container, contents_only=False) metrics.files += _delete_files(p4, objects_to_delete, view_name) for group_template in group_list: _delete_group(args, p4, group_template.format(view=view_name), metrics) for c in counter_list: _delete_counter(p4, c, metrics) if config_file_exists: p4gf_util.p4run_logged(p4, ['sync', '-fq', config_file]) with p4gf_util.NumberedChangelist( p4=p4, description=_("Delete repo config for '{}'").format( view_name)) as nc: nc.p4run(["delete", config_file]) nc.submit()
def delete_client(args, p4, client_name, metrics, prune_objs=True): """Delete the named Perforce client and its workspace. Raises P4Exception if the client is not present, or the client configuration is not set up as expected. Keyword arguments: args -- parsed command line arguments p4 -- Git user's Perforce client client_name -- name of client to be deleted metrics -- DeletionMetrics for collecting resulting metrics prune_objs -- if True, delete associated objects from cache """ # pylint: disable=R0912,R0915 group_list = [p4gf_const.P4GF_GROUP_VIEW_PULL, p4gf_const.P4GF_GROUP_VIEW_PUSH] p4.user = p4gf_const.P4GF_USER print_verbose(args, _("Checking for client '{}'...").format(client_name)) if not p4gf_util.spec_exists(p4, 'client', client_name): raise P4.P4Exception(_("No such client '{}' defined") .format(client_name)) view_name = p4gf_util.client_to_view_name(client_name) p4gf_dir = p4gf_util.p4_to_p4gf_dir(p4) view_dirs = p4gf_view_dirs.from_p4gf_dir(p4gf_dir, view_name) p4gf_util.ensure_spec_values(p4, 'client', client_name, {'Root': view_dirs.p4root}) view_lock = None # We're clobbering and deleting. Overrule locks. with p4gf_context.create_context(view_name, view_lock) as ctx: command_path = ctx.client_view_path() homedir = os.path.expanduser('~') raise_if_homedir(homedir, view_name, view_dirs.view_container) # Scan for objects associated only with this view so we can remove them. objects_to_delete = [] if prune_objs: objects_to_delete = _find_client_commit_objects(args, p4, view_name) # Do we have a repo config file to delete? config_file = p4gf_config.depot_path_repo(view_name) + '*' config_file_exists = p4gf_util.depot_file_exists(p4, config_file) # What counters shall we delete? counter_list = [] counter_list.append(p4gf_context.calc_last_copied_change_counter_name( view_name, p4gf_util.get_server_id())) for spec in p4.run('counters', '-u', '-e', "git-fusion-index-last-{},*" .format(view_name)): counter_list.append(spec['counter']) for spec in p4.run('counters', '-u', '-e', "git-fusion-index-branch-{},*" .format(view_name)): counter_list.append(spec['counter']) if not args.delete: print(NTR('p4 sync -f {}#none').format(command_path)) print(NTR('p4 client -f -d {}').format(client_name)) print(NTR('rm -rf {}').format(view_dirs.view_container)) print(NTR('Deleting {} objects from //{}/objects/...').format( len(objects_to_delete), p4gf_const.P4GF_DEPOT)) for group_template in group_list: group = group_template.format(view=view_name) print(NTR('p4 group -a -d {}').format(group)) for c in counter_list: print(NTR('p4 counter -u -d {}').format(c)) if config_file_exists: print(NTR('p4 sync -f {}').format(config_file)) print(NTR('p4 delete {}').format(config_file)) print(NTR('p4 submit -d "Delete repo config for {view_name}" {config_file}') .format(view_name=view_name, config_file=config_file)) else: print_verbose(args, NTR('Removing client files for {}...').format(client_name)) ctx.p4.run('sync', '-fq', command_path + '#none') print_verbose(args, NTR('Deleting client {}...').format(client_name)) p4.run('client', '-df', client_name) metrics.clients += 1 print_verbose(args, NTR("Deleting repo {0}'s directory {1}...").format(view_name, view_dirs.view_container)) _remove_tree(view_dirs.view_container, contents_only=False) metrics.files += _delete_files(p4, objects_to_delete, view_name) for group_template in group_list: _delete_group(args, p4, group_template.format(view=view_name), metrics) for c in counter_list: _delete_counter(p4, c, metrics) if config_file_exists: p4gf_util.p4run_logged(p4, ['sync', '-fq', config_file]) with p4gf_util.NumberedChangelist( p4=p4, description=_("Delete repo config for '{}'") .format(view_name)) as nc: nc.p4run(["delete", config_file]) nc.submit()
def _create_p4_client(p4, view_name, client_name, client_root, enable_mismatched_rhs, view_name_p4client, handle_imports=True): """Create the p4 client to contain Git meta-data mirror. Keyword arguments: p4 -- Perforce client API view_name -- client view of repository to clone - internal (translated) viewname client_name -- client that will be created client_root -- path for client workspace enable_mismatched_rhs -- allow branches to have differing RHS? view_name_p4client -- name of actual p4 client on which to base this new repo if None - will be determined from view_name if needed Returns one of the INIT_REPO_* constants. """ # Ensure the client root directory has been created. if not os.path.exists(client_root): os.makedirs(client_root) view_name_git = p4gf_translate.TranslateReponame.repo_to_git(view_name) LOG.debug( "_create_p4_client(): view_name_git {0} view_name {1} view_name_p4client {2}" .format(view_name_git, view_name, view_name_p4client)) # If a Git Fusion client for this view already exists, use that, # no need to init the repo. # Do make sure that the client root is correct. if p4gf_util.spec_exists(p4, 'client', client_name): LOG.debug("%s client already exists for %s", client_name, view_name) p4gf_util.ensure_spec_values(p4, 'client', client_name, { 'Root': client_root, 'Options': CLIENT_OPTIONS }) return INIT_REPO_EXISTS # Repo config file already checked into Perforce? # Use that. config_path = p4gf_config.depot_path_repo(view_name) config_exists = p4gf_util.depot_file_exists(p4, config_path) if config_exists: return repo_from_config(p4, view_name, client_name, client_root, enable_mismatched_rhs) # Client exist with the same name as this Git Fusion repo? # Build a new config, check it into Perforce, and use that. if not view_name_p4client: view_name_p4client = p4gf_translate.TranslateReponame.git_to_p4client( view_name_git) nop4client = '' if p4gf_util.spec_exists(p4, 'client', view_name_p4client): return repo_from_template_client(p4, view_name, view_name_p4client, client_name, client_root, enable_mismatched_rhs) else: nop4client = _("p4 client '{0}' does not exist\n").format( view_name_p4client) # creating repo from stream? # note that we can't pass '//depot/stream' because git would be confused # but it's ok to pass 'depot/stream' and add the leading '//' here stream_name = '//' + view_name_git if p4gf_util.spec_exists(p4, 'stream', stream_name): return _repo_from_stream(p4, view_name, stream_name, client_name, client_root, enable_mismatched_rhs, handle_imports) # We don't have, and cannot create, a config for this repo. # Say so and give up. msg = p4gf_const.NO_REPO_MSG_TEMPLATE.format( view_name=view_name, view_name_p4client=view_name_p4client, nop4client=nop4client) LOG.warn(msg) _print_stderr(msg) return INIT_REPO_NOVIEW