示例#1
0
    def run_command(self, args, config):
        workspace_path = get_workspace_path()
        manifest = get_workspace_manifest()

        manifest_repo = find_source_manifest_repo(manifest, config['cfg_file'],
                                                  config['user_cfg_file'],
                                                  args.source_manifest_repo)
        cfg, user_cfg, conflicts = list_available_manifest_repos(
            config['cfg_file'], config['user_cfg_file'])
        if manifest_repo in cfg:
            manifest_repo_path = config['cfg_file'].manifest_repo_abs_path(
                manifest_repo)
        elif manifest_repo in user_cfg:
            manifest_repo_path = config[
                'user_cfg_file'].manifest_repo_abs_path(manifest_repo)
        else:
            manifest_repo_path = None

        pin_path = self.__get_pin_path(args, workspace_path,
                                       manifest_repo_path, manifest)
        pin = ManifestXml(pin_path)
        manifest_sources = manifest.get_repo_sources(
            manifest.general_config.current_combo)
        check_dirty_repos(manifest, workspace_path)
        for source in manifest_sources:
            local_path = os.path.join(workspace_path, source.root)
            repo = Repo(local_path)
            origin = repo.remotes.origin
            origin.fetch()
        self.__pin_matches_project(pin, manifest, workspace_path)
        sparse_enabled = sparse_checkout_enabled(workspace_path,
                                                 manifest_sources)
        if sparse_enabled:
            ui_functions.print_info_msg(SPARSE_RESET, header=False)
            reset_sparse_checkout(workspace_path, manifest_sources)
        submodule_combo = pin.general_config.current_combo
        try:
            deinit_full(workspace_path, manifest, args.verbose)
        except Exception as e:
            ui_functions.print_error_msg(SUBMODULE_DEINIT_FAILED, header=False)
            if args.verbose:
                ui_functions.print_error_msg(e, header=False)
        pin_repo_sources = pin.get_repo_sources(
            pin.general_config.current_combo)
        try:
            checkout_repos(args.verbose, args.override, pin_repo_sources,
                           workspace_path, manifest)
            manifest.write_current_combo(humble.PIN_COMBO.format(args.pinfile))
        finally:
            cache_path = None
            cache_obj = get_repo_cache_obj(config)
            if cache_obj is not None:
                cache_path = cache_obj.get_cache_path(
                    SUBMODULE_CACHE_REPO_NAME)
            maintain_submodules(workspace_path, pin, submodule_combo,
                                args.verbose, cache_path)
            if sparse_enabled:
                ui_functions.print_info_msg(SPARSE_CHECKOUT, header=False)
                sparse_checkout(workspace_path, pin_repo_sources, manifest)
示例#2
0
 def run_command(self, args, config):
     workspace_path = get_workspace_path()
     manifest = get_workspace_manifest()
     manifest_config = manifest.general_config
     repo_sources_to_reset = manifest.get_repo_sources(manifest_config.current_combo)
     for repo_to_reset in repo_sources_to_reset:
         local_repo_path = os.path.join(workspace_path, repo_to_reset.root)
         repo = Repo(local_repo_path)
         if args.verbose:
             ui_functions.print_info_msg("{}Resetting {}".format("Hard " if args.hard else "", repo_to_reset.root))
         repo.head.reset(working_tree=args.hard)
示例#3
0
 def run_command(self, args, config):
     workspace_path = get_workspace_path()
     initial_manifest = get_workspace_manifest()
     current_combo = initial_manifest.general_config.current_combo
     current_sources = initial_manifest.get_repo_sources(current_combo)
     ui_functions.print_info_msg(
         humble.STATUS_CURRENT_COMBO.format(current_combo), header=False)
     for current_repo in current_sources:
         local_repo_path = os.path.join(workspace_path, current_repo.root)
         repo = Repo(local_repo_path)
         ui_functions.print_info_msg("{}: {}\n".format(
             current_repo.root, repo.git.status()),
                                     header=False)
示例#4
0
    def run_command(self, args, config):

        workspace_path = get_workspace_path()
        manifest = get_workspace_manifest()

        # Set the pinname/path == to the file name provided.
        # If a relative paths is provided save the file relative to the current working directory.
        if os.path.isabs(os.path.normpath(args.PinFileName)):
            pin_file_name = os.path.normpath(args.PinFileName)
        else:
            pin_file_name = os.path.abspath(os.path.normpath(args.PinFileName))
        # If the directory that the pin file is saved in does not exist create it and ensure pin file name uniqueness.
        if os.path.isfile(pin_file_name):
            raise EdkrepoInvalidParametersException(PIN_FILE_ALREADY_EXISTS)
        if not os.path.exists(os.path.dirname(pin_file_name)):
            os.mkdir(os.path.dirname(pin_file_name))

        repo_sources = manifest.get_repo_sources(
            manifest.general_config.current_combo)

        # get the repo sources and commit ids for the pin
        ui_functions.print_info_msg(GENERATING_PIN_DATA.format(
            manifest.project_info.codename,
            manifest.general_config.current_combo),
                                    header=False)
        updated_repo_sources = []
        for repo_source in repo_sources:
            local_repo_path = os.path.join(workspace_path, repo_source.root)
            if not os.path.exists(local_repo_path):
                raise EdkrepoWorkspaceCorruptException(
                    MISSING_REPO.format(repo_source.root))
            repo = Repo(local_repo_path)
            commit_id = repo.head.commit.hexsha
            if args.verbose:
                ui_functions.print_info_msg(GENERATING_REPO_DATA.format(
                    repo_source.root),
                                            header=False)
                ui_functions.print_info_msg(BRANCH.format(repo_source.branch),
                                            header=False)
                ui_functions.print_info_msg(COMMIT.format(commit_id),
                                            header=False)
            updated_repo_source = repo_source._replace(commit=commit_id)
            updated_repo_sources.append(updated_repo_source)

        # create the pin
        ui_functions.print_info_msg(WRITING_PIN_FILE.format(pin_file_name),
                                    header=False)
        manifest.generate_pin_xml(args.Description,
                                  manifest.general_config.current_combo,
                                  updated_repo_sources,
                                  filename=pin_file_name)
示例#5
0
 def run_command(self, args, config):
     workspace_path = get_workspace_path()
     manifest = get_workspace_manifest()
     manifest_config = manifest.general_config
     repo_sources_to_clean = manifest.get_repo_sources(
         manifest_config.current_combo)
     for repo_to_clean in repo_sources_to_clean:
         local_repo_path = os.path.join(workspace_path, repo_to_clean.root)
         repo = Repo(local_repo_path)
         result = repo.git.clean(f=args.force,
                                 d=args.dirs,
                                 n=(not args.force),
                                 q=(args.quiet and args.force))
         if result:
             ui_functions.print_info_msg(result, header=False)
示例#6
0
    def run_command(self, args, config):
        # Collect workspace/repo data
        workspace_path = get_workspace_path()
        manifest = get_workspace_manifest()
        current_combo = manifest.general_config.current_combo
        repo_list = manifest.get_repo_sources(current_combo)
        sparse_settings = manifest.sparse_settings
        sparse_enabled = sparse_checkout_enabled(workspace_path, repo_list)

        # Determine if settings are being chaged or just status display
        if args.enable or args.disable:
            # Handle sparse checkout changes
            if args.enable and args.disable:
                raise EdkrepoSparseException(SPARSE_ENABLE_DISABLE)
            elif (args.enable and sparse_enabled) or (args.disable
                                                      and not sparse_enabled):
                raise EdkrepoSparseException(SPARSE_NO_CHANGE)

            check_dirty_repos(manifest, workspace_path)

            if args.enable and not sparse_enabled:
                ui_functions.print_info_msg(SPARSE_ENABLE, header=False)
                sparse_checkout(workspace_path, repo_list, manifest)
            elif args.disable and sparse_enabled:
                ui_functions.print_info_msg(SPARSE_DISABLE, header=False)
                reset_sparse_checkout(workspace_path, repo_list, True)
        else:
            # Display the current status of the project
            ui_functions.print_info_msg(SPARSE_STATUS, header=False)
            ui_functions.print_info_msg(
                SPARSE_CHECKOUT_STATUS.format(sparse_enabled), header=False)
            if sparse_settings is not None:
                ui_functions.print_info_msg(SPARSE_BY_DEFAULT_STATUS.format(
                    sparse_settings.sparse_by_default),
                                            header=False)
            ui_functions.print_info_msg(
                SPARSE_ENABLED_REPOS.format(current_combo), header=False)
            for repo in [x for x in repo_list if x.sparse]:
                ui_functions.print_info_msg('- {}: {}'.format(
                    repo.root, repo.remote_url),
                                            header=False)
    def run_command(self, args, config):

        # Configure git long path support
        ui_functions.print_info_msg(humble.LONGPATH_CONFIG, header=False)
        set_long_path_support()
        print()

        # Remove unneeded instead of entries from git global config
        ui_functions.print_info_msg(humble.CLEAN_INSTEAD_OFS, header=False)
        print()

        # If in a valid workspace run the following for each repo:
        # git reflog --expire, git gc, git remote prune origin
        try:
            workspace_path = get_workspace_path()
        except EdkrepoWorkspaceInvalidException:
            workspace_path = None
            ui_functions.print_error_msg(humble.NO_WOKKSPACE, header=False)
            print()

        if workspace_path:
            manifest = get_workspace_manifest()
            repos_to_maintain = manifest.get_repo_sources(
                manifest.general_config.current_combo)
            for repo_to_maintain in repos_to_maintain:
                local_repo_path = os.path.join(workspace_path,
                                               repo_to_maintain.root)
                repo = Repo(local_repo_path)
                ui_functions.print_info_msg(humble.REPO_MAINTENANCE.format(
                    repo_to_maintain.root),
                                            header=False)
                ui_functions.print_info_msg(humble.REFLOG_EXPIRE, header=False)
                repo.git.reflog('expire', '--expire=now', '--all')
                ui_functions.print_info_msg(humble.GC_AGGRESSIVE, header=False)
                repo.git.gc('--aggressive', '--prune=now')
                ui_functions.print_info_msg(humble.REMOTE_PRUNE, header=False)
                repo.git.remote('prune', 'origin')
                print()
示例#8
0
    def run_command(self, args, config):
        workspace_path = get_workspace_path()
        initial_manifest = get_workspace_manifest()
        current_combo = initial_manifest.general_config.current_combo
        initial_sources = initial_manifest.get_repo_sources(current_combo)
        initial_hooks = initial_manifest.repo_hooks
        initial_combo = current_combo

        try:
            pull_workspace_manifest_repo(initial_manifest, config['cfg_file'],
                                         config['user_cfg_file'],
                                         args.source_manifest_repo, False)
        except:
            pull_all_manifest_repos(config['cfg_file'],
                                    config['user_cfg_file'], False)
        source_global_manifest_repo = find_source_manifest_repo(
            initial_manifest, config['cfg_file'], config['user_cfg_file'],
            args.source_manifest_repo)
        cfg_manifest_repos, user_cfg_manifest_repos, conflicts = list_available_manifest_repos(
            config['cfg_file'], config['user_cfg_file'])
        if source_global_manifest_repo in cfg_manifest_repos:
            global_manifest_directory = config[
                'cfg_file'].manifest_repo_abs_path(source_global_manifest_repo)
            verify_single_manifest(config['cfg_file'],
                                   source_global_manifest_repo,
                                   get_workspace_manifest_file(), args.verbose)
        elif source_global_manifest_repo in user_cfg_manifest_repos:
            global_manifest_directory = config[
                'user_cfg_file'].manifest_repo_abs_path(
                    source_global_manifest_repo)
            verify_single_manifest(config['user_cfg_file'],
                                   source_global_manifest_repo,
                                   get_workspace_manifest_file(), args.verbose)
        else:
            global_manifest_directory = None

        if global_manifest_directory is not None:
            update_editor_config(config, global_manifest_directory)

        if not args.update_local_manifest:
            self.__check_for_new_manifest(args, config, initial_manifest,
                                          workspace_path,
                                          global_manifest_directory)
        check_dirty_repos(initial_manifest, workspace_path)

        # Determine if sparse checkout needs to be disabled for this operation
        sparse_settings = initial_manifest.sparse_settings
        sparse_enabled = sparse_checkout_enabled(workspace_path,
                                                 initial_sources)
        sparse_reset_required = False
        if sparse_settings is None:
            sparse_reset_required = True
        elif args.update_local_manifest:
            sparse_reset_required = True
        if sparse_enabled and sparse_reset_required:
            ui_functions.print_info_msg(SPARSE_RESET, header=False)
            reset_sparse_checkout(workspace_path, initial_sources)

        # Get the latest manifest if requested
        if args.update_local_manifest:  # NOTE: hyphens in arg name replaced with underscores due to argparse
            self.__update_local_manifest(args, config, initial_manifest,
                                         workspace_path,
                                         global_manifest_directory)
        manifest = get_workspace_manifest()
        if args.update_local_manifest:
            try:
                repo_sources_to_sync = manifest.get_repo_sources(current_combo)
            except ValueError:
                # The manifest file was updated and the initial combo is no longer present so use the default combo
                current_combo = manifest.general_config.default_combo
                repo_sources_to_sync = manifest.get_repo_sources(current_combo)
        else:
            repo_sources_to_sync = manifest.get_repo_sources(current_combo)
        manifest.write_current_combo(current_combo)

        # At this point both new and old manifest files are ready so we can deinit any
        # submodules that are removed due to a manifest update.
        if not args.skip_submodule:
            deinit_submodules(workspace_path, initial_manifest, initial_combo,
                              manifest, current_combo, args.verbose)

        sync_error = False
        # Calculate the hooks which need to be updated, added or removed for the sync
        if args.update_local_manifest:
            new_hooks = manifest.repo_hooks
            hooks_add = set(new_hooks).difference(set(initial_hooks))
            hooks_update = set(initial_hooks).intersection(set(new_hooks))
            hooks_uninstall = set(initial_hooks).difference(set(new_hooks))
        else:
            hooks_add = None
            hooks_update = initial_hooks
            hooks_uninstall = None
        # Update submodule configuration
        if not args.update_local_manifest:  #Performance optimization, __update_local_manifest() will do this
            self.__check_submodule_config(workspace_path, manifest,
                                          repo_sources_to_sync)
        clean_git_globalconfig()
        for repo_to_sync in repo_sources_to_sync:
            local_repo_path = os.path.join(workspace_path, repo_to_sync.root)
            # Update any hooks
            if global_manifest_directory is not None:
                update_hooks(hooks_add, hooks_update, hooks_uninstall,
                             local_repo_path, repo_to_sync, config,
                             global_manifest_directory)
            repo = Repo(local_repo_path)
            #Fetch notes
            repo.remotes.origin.fetch("refs/notes/*:refs/notes/*")
            if repo_to_sync.commit is None and repo_to_sync.tag is None:
                local_commits = False
                initial_active_branch = repo.active_branch
                repo.remotes.origin.fetch(
                    "refs/heads/{0}:refs/remotes/origin/{0}".format(
                        repo_to_sync.branch))
                #The new branch may not exist in the heads list yet if it is a new branch
                repo.git.checkout(repo_to_sync.branch)
                if not args.fetch:
                    ui_functions.print_info_msg(SYNCING.format(
                        repo_to_sync.root, repo.active_branch),
                                                header=False)
                else:
                    ui_functions.print_info_msg(FETCHING.format(
                        repo_to_sync.root, repo.active_branch),
                                                header=False)
                try:
                    repo.remotes.origin.fetch()
                except GitCommandError as e:
                    prune_needed = False
                    prune_needed_heuristic_str = "error: some local refs could not be updated"
                    if e.stdout.strip().find(prune_needed_heuristic_str) != -1:
                        prune_needed = True
                    if e.stderr.strip().find(prune_needed_heuristic_str) != -1:
                        prune_needed = True
                    if prune_needed:
                        time.sleep(1.0)
                        repo.git.remote('prune', 'origin')
                        time.sleep(1.0)
                        repo.remotes.origin.fetch()
                    else:
                        raise
                if has_primary_repo_remote(repo, args.verbose):
                    fetch_from_primary_repo(repo, repo_to_sync, args.verbose)
                if not args.override and not repo.is_ancestor(
                        ancestor_rev='HEAD',
                        rev='origin/{}'.format(repo_to_sync.branch)):
                    ui_functions.print_info_msg(SYNC_COMMITS_ON_TARGET.format(
                        repo_to_sync.branch, repo_to_sync.root),
                                                header=False)
                    local_commits = True
                    sync_error = True
                if not args.fetch and (not local_commits or args.override):
                    repo.head.reset(commit='origin/{}'.format(
                        repo_to_sync.branch),
                                    working_tree=True)

                # Check to see if mirror is up to date
                if not in_sync_with_primary(repo, repo_to_sync, args.verbose):
                    ui_functions.print_info_msg(MIRROR_BEHIND_PRIMARY_REPO,
                                                header=False)

                # Switch back to the initially active branch before exiting
                repo.heads[initial_active_branch.name].checkout()

                # Warn user if local branch is behind target branch
                try:
                    latest_sha = get_latest_sha(repo, repo_to_sync.branch)
                    commit_count = int(
                        repo.git.rev_list('--count',
                                          '{}..HEAD'.format(latest_sha)))
                    branch_origin = next(
                        itertools.islice(repo.iter_commits(), commit_count,
                                         commit_count + 1))
                    behind_count = int(
                        repo.git.rev_list(
                            '--count', '{}..{}'.format(branch_origin.hexsha,
                                                       latest_sha)))
                    if behind_count:
                        ui_functions.print_info_msg(SYNC_NEEDS_REBASE.format(
                            behind_count=behind_count,
                            target_remote='origin',
                            target_branch=repo_to_sync.branch,
                            local_branch=initial_active_branch.name,
                            repo_folder=repo_to_sync.root),
                                                    header=False)
                except:
                    ui_functions.print_error_msg(SYNC_REBASE_CALC_FAIL,
                                                 header=False)
            elif args.verbose:
                ui_functions.print_warning_msg(NO_SYNC_DETACHED_HEAD.format(
                    repo_to_sync.root),
                                               header=False)

            # Update commit message templates
            if global_manifest_directory is not None:
                update_repo_commit_template(workspace_path, repo, repo_to_sync,
                                            config, global_manifest_directory)

        if sync_error:
            ui_functions.print_error_msg(SYNC_ERROR, header=False)

        # Initialize submodules
        if not args.skip_submodule:
            cache_path = None
            cache_obj = get_repo_cache_obj(config)
            if cache_obj is not None:
                cache_path = cache_obj.get_cache_path(
                    SUBMODULE_CACHE_REPO_NAME)
            maintain_submodules(workspace_path, manifest, current_combo,
                                args.verbose, cache_path)

        # Restore sparse checkout state
        if sparse_enabled:
            ui_functions.print_info_msg(SPARSE_CHECKOUT, header=False)
            sparse_checkout(workspace_path, repo_sources_to_sync, manifest)
示例#9
0
def checkout(combination, verbose=False, override=False, log=None, cache_obj=None):
    workspace_path = get_workspace_path()
    manifest = get_workspace_manifest()

    # Create combo so we have original input and do not introduce any
    # unintended behavior by messing with parameters.
    combo = combination
    submodule_combo = manifest.general_config.current_combo
    try:
        # Try to handle normalize combo name to match the manifest file.
        combo = case_insensitive_single_match(combo, combinations_in_manifest(manifest))
        submodule_combo = combo
    except:
        raise EdkrepoInvalidParametersException(CHECKOUT_INVALID_COMBO)

    repo_sources = manifest.get_repo_sources(combo)
    initial_repo_sources = manifest.get_repo_sources(manifest.general_config.current_combo)

    # Disable sparse checkout
    current_repos = initial_repo_sources
    sparse_enabled = sparse_checkout_enabled(workspace_path, initial_repo_sources)
    sparse_diff = False
    for source in initial_repo_sources:
        for src in repo_sources:
            if source.root == src.root:
                if source.sparse != src.sparse:
                    sparse_diff = True
        if sparse_diff:
            break
    # Sparse checkout only needs to be recomputed if
    # the dynamic sparse list is being used instead of the static sparse list
    # or the sparse settings between two combinations differ
    if sparse_enabled:
        sparse_settings = manifest.sparse_settings
        if sparse_settings is not None:
            sparse_enabled = False
    if sparse_enabled or sparse_diff:
        print(SPARSE_RESET)
        reset_sparse_checkout(workspace_path, current_repos)

    # Deinit all submodules due to the potential for issues when switching
    # branches.
    if combo != manifest.general_config.current_combo:
        try:
            deinit_full(workspace_path, manifest, verbose)
        except Exception as e:
            print(SUBMODULE_DEINIT_FAILED)
            if verbose:
                print(e)

    print(CHECKING_OUT_COMBO.format(combo))

    try:
        checkout_repos(verbose, override, repo_sources, workspace_path, manifest)
        current_repos = repo_sources
        # Update the current checkout combo in the manifest only if this
        # combination exists in the manifest
        if combination_is_in_manifest(combo, manifest):
            manifest.write_current_combo(combo)
    except:
        if verbose:
            traceback.print_exc()
        print (CHECKOUT_COMBO_UNSUCCESSFULL.format(combo))
        # Return to the initial combo, since there was an issue with cheking out the selected combo
        checkout_repos(verbose, override, initial_repo_sources, workspace_path, manifest)
    finally:
        cache_path = None
        if cache_obj is not None:
            cache_path = cache_obj.get_cache_path(SUBMODULE_CACHE_REPO_NAME)
        maintain_submodules(workspace_path, manifest, submodule_combo, verbose, cache_path)
        if sparse_enabled or sparse_diff:
            print(SPARSE_CHECKOUT)
            sparse_checkout(workspace_path, current_repos, manifest)
示例#10
0
    def run_command(self, args, config):
        if args.number:
            try:
                args.number = int(args.number)
            except ValueError:
                print("Error: \'{}\' is not an integer".format(args.number))
                return

        workspace_path = get_workspace_path()
        manifest = get_workspace_manifest()

        sorted_commit_list = sort_commits(manifest, workspace_path,
                                          args.number)

        less_path, use_less = find_less()

        if use_less:
            output_string = ''
            separator = '\n'

        for commit in sorted_commit_list:
            if args.oneline:
                oneline = "{}{:.9s}{} {:15.15s}{} {:.80s}".format(
                    Fore.YELLOW, commit.hexsha, Fore.CYAN,
                    os.path.basename(commit.repo.working_dir), Fore.RESET,
                    ui_functions.safe_str(commit.summary))
                if use_less:
                    output_string = separator.join((output_string, oneline))

                else:
                    print(oneline)
            else:
                time_string = datetime.utcfromtimestamp(
                    commit.authored_date -
                    commit.author_tz_offset).strftime("%c")
                time_zone_string = "{}{:04.0f}".format(
                    "-" if commit.author_tz_offset > 0 else "+",
                    abs(commit.author_tz_offset / 36))
                hexsha_string = "{}commit {}{} ({}){}".format(
                    Fore.YELLOW, commit.hexsha, Fore.CYAN,
                    os.path.basename(commit.repo.working_dir), Fore.RESET)
                author_string = "Author: {} <{}>".format(
                    commit.author.name, commit.author.email)
                date_string = "Date:   {} {}".format(time_string,
                                                     time_zone_string)
                if use_less:
                    output_string = separator.join(
                        (output_string, hexsha_string,
                         ui_functions.safe_str(author_string), date_string))

                    commit_string = ""
                    for line in commit.message.splitlines():
                        commit_string = separator.join(
                            (commit_string,
                             ui_functions.safe_str("    {}".format(line))))

                    output_string = separator.join(
                        (output_string, commit_string, separator))
                else:
                    print(hexsha_string)
                    ui_functions.print_safe(author_string)
                    print(date_string)
                    print("")
                    for line in commit.message.splitlines():
                        ui_functions.print_safe("    {}".format(line))
                    print("")
        if less_path:
            less_output = subprocess.Popen(
                [str(less_path), '-F', '-R', '-S', '-X', '-K'],
                stdin=subprocess.PIPE,
                stdout=sys.stdout,
                universal_newlines=True)
            less_output.communicate(input=output_string)