def _discover_config_file(self):
        """Discover the status of the repo config file."""
        server_rev = self._get_server_repo_config_rev()
        config_path = p4gf_config.depot_path_repo(self.repo_name)
        (head_rev, head_action,
         head_change) = p4gf_util.depot_file_head_rev_action(
             self.p4, config_path)

        was_initialized = server_rev != '0'
        deleted = head_action and 'delete' in head_action
        exists = head_action and 'delete' not in head_action
        readded = was_initialized and exists and p4gf_util.depot_file_is_re_added(
            self.p4, config_path, server_rev, head_rev)
        if readded:
            return (CONFIG_READDED, head_rev, head_change)
        if exists:
            if was_initialized:
                if head_rev == server_rev:
                    self.config_needs_validation = False
                return (CONFIG_EXISTS, head_rev, head_change)
            else:
                return (CONFIG_NEW, head_rev, head_change)
        if deleted:
            # The p4gf_config file has been deleted and we will not resurrect from
            # a p4 client of the same name.
            return (CONFIG_DELETED, head_rev, head_change)

        if was_initialized:
            # The p4gf_config file has apparently been obliterated.
            return (CONFIG_MISSING, head_rev, head_change)

        return (CONFIG_NONE, head_rev, head_change)
 def from_depot_p4gf_config(view_name, p4):
     ''' initialize from config file stored in depot'''
     v = Validator()
     v.view_name = view_name
     v.config_file_path = p4gf_config.depot_path_repo(view_name)
     # Do _not_ use a shared instance, since we explicitly release it later;
     # instead, get a fresh, unmerged copy for validation purposes.
     v.config = p4gf_config.read_repo(p4, view_name)
     v.config_merged = Validator._combine_repo_with_global(p4, v.config)
     v.p4 = p4
     return v
 def from_depot_p4gf_config(view_name, p4):
     ''' initialize from config file stored in depot'''
     v = Validator()
     v.view_name = view_name
     v.config_file_path = p4gf_config.depot_path_repo(view_name)
     # Do _not_ use a shared instance, since we explicitly release it later;
     # instead, get a fresh, unmerged copy for validation purposes.
     v.config = p4gf_config.read_repo(p4, view_name)
     v.config_merged = Validator._combine_repo_with_global(p4, v.config)
     v.p4 = p4
     return v
    def get_branch_dict(self):
        """Get a branch dictionary for this repo.

        If the p4gf_config exists, use that.
        Else if the p4 client exists
        create a branch dict containing a branch from the client views.
        Else return None
        """
        LOG.debug("get_branch_dict for {0}".format(self.view_name))
        # Repo config file already checked into Perforce?
        # Use that.
        config_path = p4gf_config.depot_path_repo(self.view_name)
        config_exists = p4gf_util.depot_file_exists(self.p4, config_path)
        if config_exists:
            self.config = p4gf_config.get_repo(self.p4, self.view_name)
            if self.config:
                return p4gf_branch.dict_from_config(self.config, self.p4)
            else:
                return None
        else:
            LOG.debug("checking if client {0} exists.".format(self.view_name))
            if not p4gf_util.spec_exists(self.p4, 'client', self.view_name):
                LOG.debug("         client {0} NOT exists.".format(
                    self.view_name))
                return None
            view_lines = p4gf_util.first_value_for_key(
                self.p4.run('client', '-o', '-t', self.view_name,
                            self.p4client), 'View')
            if not view_lines:
                return None
            else:
                # create a Branch object to manage this client view
                if isinstance(view_lines, str):
                    view_lines = view_lines.splitlines()
                LOG.debug(
                    "create branch from client views: {0}".format(view_lines))
                branch = p4gf_branch.Branch()
                branch.branch_id = 'master'
                branch.git_branch_name = 'master'
                branch.view_p4map = P4.Map(view_lines)
                branch.view_lines = view_lines
                LOG.debug(
                    "create branch from client branch view_p4map: {0}".format(
                        branch.view_p4map))
                LOG.debug(
                    "create branch from client branch view_lines: {0}".format(
                        branch.view_lines))
                branch_dict = {}
                branch_dict[branch.branch_id] = branch
                return branch_dict
    def get_branch_dict(self):
        """Get a branch dictionary for this repo.

        If the p4gf_config exists, use that.
        Else if the p4 client exists
        create a branch dict containing a branch from the client views.
        Else return None
        """
        LOG.debug("get_branch_dict for {0}".format(self.view_name))
        # Repo config file already checked into Perforce?
        # Use that.
        config_path   = p4gf_config.depot_path_repo(self.view_name)
        config_exists = p4gf_util.depot_file_exists(self.p4, config_path)
        if config_exists:
            self.config = p4gf_config.get_repo(self.p4, self.view_name)
            if self.config:
                return p4gf_branch.dict_from_config(self.config, self.p4)
            else:
                return None
        else:
            LOG.debug("checking if client {0} exists.".format(self.view_name))
            if not p4gf_util.spec_exists(self.p4, 'client', self.view_name):
                LOG.debug("         client {0} NOT exists.".format(self.view_name))
                return None
            view_lines = p4gf_util.first_value_for_key(
                    self.p4.run('client', '-o', '-t', self.view_name, self.p4client),
                    'View')
            if not view_lines:
                return None
            else:
                # create a Branch object to manage this client view
                if isinstance(view_lines, str):
                    view_lines = view_lines.splitlines()
                LOG.debug("create branch from client views: {0}".format(view_lines))
                branch = p4gf_branch.Branch()
                branch.branch_id = 'master'
                branch.git_branch_name = 'master'
                branch.view_p4map = P4.Map(view_lines)
                branch.view_lines = view_lines
                LOG.debug("create branch from client branch view_p4map: {0}".
                        format(branch.view_p4map))
                LOG.debug("create branch from client branch view_lines: {0}".
                        format(branch.view_lines))
                branch_dict = {}
                branch_dict[branch.branch_id] = branch
                return branch_dict
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
Exemple #7
0
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
def _repo_config_exists(p4, repo_name):
    """Return true is repo p4gf_config exists."""
    config_path = p4gf_config.depot_path_repo(repo_name)
    return p4gf_util.depot_file_exists(p4, config_path)