Example #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)
Example #2
0
    def __check_for_new_manifest(self, args, config, initial_manifest,
                                 workspace_path, global_manifest_directory):
        #if the manifest repository for the current manifest was not found then there is no project with the manifest
        #specified project name in the index file for any of the manifest repositories
        if global_manifest_directory is None:
            if args.override:
                return
            else:
                raise EdkrepoManifestNotFoundException(
                    SYNC_MANIFEST_NOT_FOUND.format(
                        initial_manifest.project_info.codename))

        #see if there is an entry in CiIndex.xml that matches the prject name of the current manifest
        index_path = os.path.join(global_manifest_directory, 'CiIndex.xml')
        ci_index_xml = CiIndexXml(index_path)
        if initial_manifest.project_info.codename not in ci_index_xml.project_list:
            if args.override:
                return
            else:
                raise EdkrepoManifestNotFoundException(
                    SYNC_MANIFEST_NOT_FOUND.format(
                        initial_manifest.project_info.codename))
        ci_index_xml_rel_path = ci_index_xml.get_project_xml(
            initial_manifest.project_info.codename)
        global_manifest_path = os.path.join(
            global_manifest_directory, os.path.normpath(ci_index_xml_rel_path))
        global_manifest = ManifestXml(global_manifest_path)
        if not initial_manifest.equals(global_manifest, True):
            ui_functions.print_warning_msg(SYNC_MANIFEST_DIFF_WARNING,
                                           header=False)
            ui_functions.print_info_msg(SYNC_MANIFEST_UPDATE, header=False)
 def validate_parsing(self):
     try:
         self._manifest_xmldata = ManifestXml(self._manifestfile)
         return ("PARSING", True, None
                 )  # (validation type, status, message)
     except Exception as e_message:
         self._manifest_xmldata = None
         return ("PARSING", False, e_message)
Example #4
0
def verify_single_manifest(cfg_file, manifest_repo, manifest_path, verbose=False):
    manifest = ManifestXml(manifest_path)
    print(VERIFY_PROJ.format(manifest.project_info.codename))
    index_path = os.path.join(cfg_file.manifest_repo_abs_path(manifest_repo), CI_INDEX_FILE_NAME)
    proj_val_data = validate_manifestfiles([manifest_path])
    proj_val_error = get_manifest_validation_status(proj_val_data)
    if proj_val_error:
        if verbose:
            print_manifest_errors(proj_val_data)
        raise EdkrepoManifestInvalidException(VERIFY_PROJ_FAIL.format(manifest.project_info.codename))
Example #5
0
    def main(args):
        # Optional data init
        new_manifest = None
        all_new_combos = None

        # Extract basic manifest data
        manifest = ManifestXml(args.manifest_file)
        init_manifest = manifest
        all_combos = manifest.combinations
        all_combos.extend(manifest.archived_combinations)
        if args.new_manifest is not None:
            new_manifest = ManifestXml(args.new_manifest)
            all_new_combos = new_manifest.combinations
            all_new_combos.extend(new_manifest.archived_combinations)
            init_manifest = new_manifest

        # Determine current and new combo information
        current_combo = manifest.general_config.current_combo
        new_combo = args.new_combo
        for combo in all_combos:
            if args.combo is not None:
                if args.combo.lower() == combo.name.lower():
                    current_combo = combo.name
            if args.new_combo is not None:
                if args.new_combo.lower() == combo.name.lower():
                    new_combo = combo.name
        init_combo = current_combo
        if new_combo is not None:
            init_combo = new_combo

        if args.deinit_full:
            deinit_full(args.workspace, manifest, args.verbose)
        elif args.init_full:
            init_full(args.workspace, manifest, args.verbose)
        else:
            if args.deinit:
                deinit_submodules(args.workspace, manifest, current_combo,
                                  new_manifest, new_combo, args.verbose)
            maintain_submodules(args.workspace, init_manifest, init_combo,
                                args.verbose)

        return 0
Example #6
0
def _get_manifest(project, config, source_manifest_repo=None):
    try:
        manifest_repo, source_cfg, manifest_path = find_project_in_all_indices(
            project,
            config['cfg_file'],
            config['user_cfg_file'],
            PROJECT_NOT_FOUND.format(project),
            NO_INSTANCE.format(project),
            source_manifest_repo)
    except Exception:
        raise EdkrepoCacheException(UNABLE_TO_LOAD_MANIFEST)
    try:
        manifest = ManifestXml(manifest_path)
    except Exception:
        raise EdkrepoCacheException(UNABLE_TO_PARSE_MANIFEST)
    return manifest
Example #7
0
def checkout_pin(parsed_args, config):
    pins = []
    manifest = get_workspace_manifest()
    manifest_directory = None
    try:
        source_manifest_repo = find_source_manifest_repo(
            manifest,
            config['cfg_file'],
            config['user_cfg_file'],
        )
        if source_manifest_repo:
            cfg, user_cfg, conflicts = list_available_manifest_repos(
                config['cfg_file'], config['user_cfgFile'])
            if source_manifest_repo in cfg:
                manifest_directory = config['cfg_file'].manifest_repo_abs_path(
                    source_manifest_repo)
            elif source_manifest_repo in user_cfg:
                manifest_directory = config[
                    'user_cfg_file'].manifest_repo_abs_path(
                        source_manifest_repo)
            else:
                manifest_directory = None
    except EdkrepoManifestNotFoundException:
        manifest_directory = None
    if manifest_directory:
        pin_folder = os.path.normpath(
            os.path.join(manifest_directory, manifest.general_config.pin_path))
        for dirpath, _, filenames in os.walk(pin_folder):
            for file in filenames:
                pin_file = os.path.join(dirpath, file)
                # Capture error output from manifest parser stdout so it is hidden unless verbose is enabled
                stdout = sys.stdout
                sys.stdout = io.StringIO()
                pin = ManifestXml(pin_file)
                parse_output = sys.stdout.getvalue()
                sys.stdout = stdout
                if parsed_args.verbose and parse_output.strip() != '':
                    print('Pin {} Parsing Errors: {}\n'.format(
                        file, parse_output.strip()))
                if pin.project_info.codename == manifest.project_info.codename:
                    pins.append(file)
        print(' '.join(pins))
Example #8
0
    def __update_local_manifest(self, args, config, initial_manifest,
                                workspace_path, global_manifest_directory):
        #if the manifest repository for the current manifest was not found then there is no project with the manifest
        #specified project name in the index file for any of the manifest repositories
        if global_manifest_directory is None:
            raise EdkrepoManifestNotFoundException(
                SOURCE_MANIFEST_REPO_NOT_FOUND.format(
                    initial_manifest.project_info.codename))

        local_manifest_dir = os.path.join(workspace_path, 'repo')
        current_combo = initial_manifest.general_config.current_combo
        initial_sources = initial_manifest.get_repo_sources(current_combo)
        # Do a fetch for each repo in the initial to ensure that newly created upstream branches are available
        for initial_repo in initial_sources:
            local_repo_path = os.path.join(workspace_path, initial_repo.root)
            repo = Repo(local_repo_path)
            origin = repo.remotes.origin
            try:
                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:
                    # The sleep is to give the operating system time to close all the file handles that Git has open
                    time.sleep(1.0)
                    repo.git.remote('prune', 'origin')
                    time.sleep(1.0)
                    origin.fetch()
                else:
                    raise

        #see if there is an entry in CiIndex.xml that matches the prject name of the current manifest
        index_path = os.path.join(global_manifest_directory, 'CiIndex.xml')
        ci_index_xml = CiIndexXml(index_path)
        if initial_manifest.project_info.codename not in ci_index_xml.project_list:
            raise EdkrepoManifestNotFoundException(
                SYNC_MANIFEST_NOT_FOUND.format(
                    initial_manifest.project_info.codename))
        initial_manifest_remotes = {
            name: url
            for name, url in initial_manifest.remotes
        }
        ci_index_xml_rel_path = os.path.normpath(
            ci_index_xml.get_project_xml(
                initial_manifest.project_info.codename))
        global_manifest_path = os.path.join(global_manifest_directory,
                                            ci_index_xml_rel_path)
        new_manifest_to_check = ManifestXml(global_manifest_path)

        # Does the current combo exist in the new manifest? If not check to see if you can use the repo sources from
        # the default combo
        initial_combos = combinations_in_manifest(initial_manifest)
        new_combos = combinations_in_manifest(new_manifest_to_check)
        if current_combo not in new_combos:
            new_sources_for_current_combo = new_manifest_to_check.get_repo_sources(
                new_manifest_to_check.general_config.default_combo)
            new_sources = new_sources_for_current_combo
        else:
            new_sources_for_current_combo = new_manifest_to_check.get_repo_sources(
                current_combo)
            new_sources = new_manifest_to_check.get_repo_sources(current_combo)

        remove_included_config(initial_manifest.remotes,
                               initial_manifest.submodule_alternate_remotes,
                               local_manifest_dir)
        write_included_config(
            new_manifest_to_check.remotes,
            new_manifest_to_check.submodule_alternate_remotes,
            local_manifest_dir)

        self.__check_submodule_config(workspace_path, new_manifest_to_check,
                                      new_sources_for_current_combo)

        # Check that the repo sources lists are the same. If they are not the same and the override flag is not set, throw an exception.
        if not args.override and set(initial_sources) != set(new_sources):
            raise EdkrepoManifestChangedException(
                SYNC_REPO_CHANGE.format(
                    initial_manifest.project_info.codename))
        elif args.override and set(initial_sources) != set(new_sources):
            #get a set of repo source tuples that are not in both the new and old manifest
            uncommon_sources = []
            initial_common = []
            new_common = []
            for initial in initial_sources:
                common = False
                for new in new_sources:
                    if initial.root == new.root:
                        if initial.remote_name == new.remote_name:
                            if initial.remote_url == new.remote_url:
                                # If the source is unchanged between the old and the new manifest,
                                # add it to the common lists
                                common = True
                                initial_common.append(initial)
                                new_common.append(new)
                                break
                # If the source is different between the old and the new manifest, add it to the uncommon list
                if not common:
                    uncommon_sources.append(initial)
            for new in new_sources:
                common = False
                for initial in initial_sources:
                    if new.root == initial.root:
                        if new.remote_name == initial.remote_name:
                            if new.remote_url == initial.remote_url:
                                common = True
                                break
                # If the source is different between the old and the new manifest, add it to the uncommon list
                if not common:
                    uncommon_sources.append(new)
            uncommon_sources = set(uncommon_sources)
            initial_common = set(initial_common)
            new_common = set(new_common)
            sources_to_move = []
            sources_to_remove = []
            sources_to_clone = []
            for source in uncommon_sources:
                found_source = False
                for source_to_check in initial_sources:
                    if source_to_check.root == source.root:
                        if source_to_check.remote_name == source.remote_name:
                            if source_to_check.remote_url == source.remote_url:
                                found_source = True
                                break
                # If the source that is different came from the old manifest, then it is now outdated and either needs
                # to be deleted or moved to an archival location.
                if found_source:
                    roots = [s.root for s in new_sources]
                    # If there is a source in the new manifest that goes into the same folder name as a source in the
                    # old manifest, then we need to move that old folder to an archival location.
                    if source.root in roots:
                        sources_to_move.append(source)
                    else:
                        # If it doesn't exist at all in the new manifest, tell the user it is old and no longer used.
                        sources_to_remove.append(source)
                else:
                    # If the source that is different came from the new manifest, then we need to clone that new
                    # Git repository.
                    sources_to_clone.append(source)
            # Move the obsolete Git repositories to archival locations.
            for source in sources_to_move:
                old_dir = os.path.join(workspace_path, source.root)
                new_dir = generate_name_for_obsolete_backup(old_dir)
                ui_functions.print_warning_msg(SYNC_SOURCE_MOVE_WARNING.format(
                    source.root, new_dir),
                                               header=False)
                new_dir = os.path.join(workspace_path, new_dir)
                try:
                    shutil.move(old_dir, new_dir)
                except:
                    ui_functions.print_error_msg(SYNC_MOVE_FAILED.format(
                        initial_dir=source.root, new_dir=new_dir),
                                                 header=False)
                    raise
            # Tell the user about any Git repositories that are no longer used.
            if len(sources_to_remove) > 0:
                ui_functions.print_warning_msg(SYNC_REMOVE_WARNING,
                                               header=False)
            for source in sources_to_remove:
                path_to_source = os.path.join(workspace_path, source.root)
                ui_functions.print_warning_msg(path_to_source, header=False)
            if len(sources_to_remove) > 0:
                ui_functions.print_warning_msg(SYNC_REMOVE_LIST_END_FORMATTING,
                                               header=False)
            # Clone any new Git repositories
            clone_repos(args, workspace_path, sources_to_clone,
                        new_manifest_to_check.repo_hooks, config,
                        new_manifest_to_check)
            # Make a list of and only checkout repos that were newly cloned. Sync keeps repos on their initial active branches
            # cloning the entire combo can prevent existing repos from correctly being returned to their proper branch
            repos_to_checkout = []
            if sources_to_clone:
                for new_source in new_sources_for_current_combo:
                    for source in sources_to_clone:
                        if source.root == new_source.root:
                            repos_to_checkout.append(source)
            repos_to_checkout.extend(
                self.__check_combo_sha_tag_branch(workspace_path,
                                                  initial_common, new_common))
            if repos_to_checkout:
                checkout_repos(args.verbose, args.override, repos_to_checkout,
                               workspace_path, new_manifest_to_check)

        #remove the old manifest file and copy the new one
        ui_functions.print_info_msg(UPDATING_MANIFEST, header=False)
        local_manifest_path = os.path.join(local_manifest_dir, 'Manifest.xml')
        os.remove(local_manifest_path)
        shutil.copy(global_manifest_path, local_manifest_path)

        # Update the source manifest repository tag in the local copy of the manifest XML
        new_manifest = ManifestXml(local_manifest_path)
        try:
            if 'source_manifest_repo' in vars(args).keys():
                find_source_manifest_repo(new_manifest, config['cfg_file'],
                                          config['user_cfg_file'],
                                          args.source_manifest_repo)
            else:
                find_source_manifest_repo(new_manifest, config['cfg_file'],
                                          config['user_cfg_file'], None)
        except EdkrepoManifestNotFoundException:
            pass
    def run_command(self, args, config):
        print()
        init_color_console(args.color)

        pull_all_manifest_repos(config['cfg_file'], config['user_cfg_file'])
        print()

        cfg_manifest_repos, user_config_manifest_repos, conflicts = list_available_manifest_repos(config['cfg_file'], config['user_cfg_file'])

        found_manifests = {}
        manifests = {}
        repo_urls = set()
        config_manifest_repos_project_list = []
        user_config_manifest_repos_project_list = []

        for manifest_repo in cfg_manifest_repos:
            # Get path to global manifest file
            global_manifest_directory = config['cfg_file'].manifest_repo_abs_path(manifest_repo)
            if args.verbose:
                print(humble.MANIFEST_DIRECTORY)
                print(global_manifest_directory)
                print()
            #Create a dictionary containing all the manifests listed in the CiIndex.xml file
            index_path = os.path.join(global_manifest_directory, CI_INDEX_FILE_NAME)
            print(index_path)
            ci_index_xml = CiIndexXml(index_path)
            config_manifest_repos_project_list = ci_index_xml.project_list
            if args.archived:
                config_manifest_repos_project_list.extend(ci_index_xml.archived_project_list)
            for project in config_manifest_repos_project_list:
                xml_file = ci_index_xml.get_project_xml(project)
                manifest = ManifestXml(os.path.normpath(os.path.join(global_manifest_directory, xml_file)))
                found_manifests['{}:{}'.format(manifest_repo, project)] = manifest
                combo_list = [c.name for c in manifest.combinations]
                if args.archived:
                    combo_list.extend([c.name for c in manifest.archived_combinations])
                for combo in combo_list:
                    sources = manifest.get_repo_sources(combo)
                    for source in sources:
                        repo_urls.add(self.get_repo_url(source.remote_url))
        for manifest_repo in user_config_manifest_repos:
             # Get path to global manifest file
            global_manifest_directory = config['user_cfg_file'].manifest_repo_abs_path(manifest_repo)
            if args.verbose:
                print(humble.MANIFEST_DIRECTORY)
                print(global_manifest_directory)
                print()
            #Create a dictionary containing all the manifests listed in the CiIndex.xml file
            index_path = os.path.join(global_manifest_directory, CI_INDEX_FILE_NAME)
            ci_index_xml = CiIndexXml(index_path)
            user_config_manifest_repos_project_list = ci_index_xml.project_list
            if args.archived:
                user_config_manifest_repos_project_list.extend(ci_index_xml.archived_project_list)
            for project in user_config_manifest_repos_project_list:
                xml_file = ci_index_xml.get_project_xml(project)
                manifest = ManifestXml(os.path.normpath(os.path.join(global_manifest_directory, xml_file)))
                found_manifests['{}:{}'.format(manifest_repo, project)] = manifest
                combo_list = [c.name for c in manifest.combinations]
                if args.archived:
                    combo_list.extend([c.name for c in manifest.archived_combinations])
                for combo in combo_list:
                    sources = manifest.get_repo_sources(combo)
                    for source in sources:
                        repo_urls.add(self.get_repo_url(source.remote_url))

        #Remove the manifest repo portion of the key is there is not a duplicate project name
        key_list = list(found_manifests)
        for entry in key_list:
            new_key = entry.split(':')[1]
            value = found_manifests[entry]
            del found_manifests[entry]
            for found_manifest in list(found_manifests):
                if found_manifest.split(':')[1] == new_key:
                    new_key = 'Manifest Repository: {} Project: {}'.format(entry.split(':')[0], entry.split(':')[1])
                    break
            if new_key in manifests.keys():
                new_key = 'Manifest Repository: {} Project: {}'.format(entry.split(':'[0]), entry.split(':')[1])
            manifests[new_key] = value

        #Sort the manifests so projects will be displayed alphabetically
        manifests = collections.OrderedDict(sorted(manifests.items()))
        project_justify = len(max(manifests.keys(), key=len))

        #Determine the names of the repositories
        self.generate_repo_names(repo_urls, manifests, args.archived)
        print(humble.REPOSITORIES)

        #If the user provided a list of repositories to view, check to make sure
        #at least one repository will be shown, if not provide an error
        if args.repos and len([x for x in self.repo_names if x in args.repos]) <= 0:
            raise EdkrepoInvalidParametersException(humble.REPO_NOT_FOUND_IN_MANIFEST.format(','.join(args.repos)))

        #For each each git repository...
        for repo_name in self.repo_names:
            if args.repos and repo_name not in args.repos:
                continue
            repo = self.repo_names[repo_name][0]
            print(humble.REPO_NAME_AND_URL.format(repo_name, repo))
            print(humble.BRANCHES)

            #Determine the list of branches that used by any branch combination in any manifest
            branches = set()
            for project_name in manifests:
                combo_list = [c.name for c in manifests[project_name].combinations]
                if args.archived:
                    combo_list.extend([c.name for c in manifests[project_name].archived_combinations])
                for combo in combo_list:
                    sources = manifests[project_name].get_repo_sources(combo)
                    for source in sources:
                        if self.get_repo_url(source.remote_url) == repo:
                            branches.add(source.branch)

            #Sort the branch names so they will be displayed alphabetically
            #with the exception that if a branch named "master" exists, then it
            #will be displayed first
            branches = sorted(branches, key=str.casefold)
            if 'master' in branches:
                branches.remove('master')
                branches.insert(0, 'master')

            #For each interesting branch in the current git repository...
            for branch in branches:
                print(humble.BRANCH_FORMAT_STRING.format(branch))

                #Determine the branch combinations that use that branch
                for project_name in manifests:
                    combos = []
                    combo_list = [c.name for c in manifests[project_name].combinations]
                    if args.archived:
                        combo_list.extend([c.name for c in manifests[project_name].archived_combinations])
                    for combo in combo_list:
                        sources = manifests[project_name].get_repo_sources(combo)
                        for source in sources:
                            if self.get_repo_url(source.remote_url) == repo and source.branch == branch:
                                combos.append(combo)
                                break
                    if len(combos) > 0:
                        #Sort the branch combinations so they will be displayed alphabetically
                        #with the exception that the default branch combination for the manifest
                        #file will be displayed first
                        combos = sorted(combos, key=str.casefold)
                        default_combo = manifests[project_name].general_config.default_combo
                        if default_combo in combos:
                            combos.remove(default_combo)
                            combos.insert(0, default_combo)
                        first_combo = True
                        for combo in combos:
                            #Print the project name
                            if first_combo:
                                project_name_print = humble.PROJECT_NAME_FORMAT_STRING.format(project_name.ljust(project_justify))
                                first_combo = False
                            else:
                                project_name_print = '{} '.format((' ' * len(project_name)).ljust(project_justify))
                            #Print the branch combination name, if this is the default branch combination,
                            #then print it in green color with *'s around it
                            if default_combo == combo:
                                print(humble.DEFAULT_COMBO_FORMAT_STRING.format(project_name_print, combo))
                            else:
                                print(humble.COMBO_FORMAT_STRING.format(project_name_print, combo))
    def run_command(self, args, config):
        print()
        cfg_file = config['cfg_file']
        user_cfg = config['user_cfg_file']
        cfg_man_repos, user_cfg_man_repos, conflicts = list_available_manifest_repos(
            cfg_file, user_cfg)
        man_repos = {}

        pull_all_manifest_repos(cfg_file, user_cfg, False)

        # Get paths to the global manifest dirs and their index files
        for repo in cfg_man_repos:
            global_manifest_directory = cfg_file.manifest_repo_abs_path(repo)
            index_path = os.path.join(global_manifest_directory, 'CiIndex.xml')
            man_repos[repo] = (global_manifest_directory, index_path)
        for repo in user_cfg_man_repos:
            global_manifest_directory = user_cfg.manifest_repo_abs_path(repo)
            index_path = os.path.join(global_manifest_directory, 'CiIndex.xml')
            man_repos[repo] = (global_manifest_directory, index_path)

        try:
            wkspc_manifest = get_workspace_manifest()
            current_project = wkspc_manifest.project_info.codename
            src_man_repo = find_source_manifest_repo(wkspc_manifest, cfg_file,
                                                     user_cfg, None)
        except EdkrepoWorkspaceInvalidException:
            current_project = None
            src_man_repo = None
        except EdkrepoManifestNotFoundException:
            src_man_repo = None

        for repo in man_repos.keys():
            print()
            ui_functions.print_info_msg("Manifest directory:", header=False)
            ui_functions.print_info_msg(repo, header=False)
            if args.verbose:
                ui_functions.print_info_msg('Manifest directory path:',
                                            header=False)
                ui_functions.print_info_msg(man_repos[repo][0], header=False)
            print()

            ci_index_xml = CiIndexXml(man_repos[repo][1])

            # Attempt to make sure the manifest data is good
            try:
                validate_manifest_repo(man_repos[repo][0], args.verbose,
                                       args.archived)
            except:
                print()

            ui_functions.print_info_msg("Projects:", header=False)
            for project in sorted(ci_index_xml.project_list):
                if (project == current_project and src_man_repo == repo) or (
                        not src_man_repo and project == current_project):
                    ui_functions.print_info_msg(project, header=False)
                else:
                    ui_functions.print_warning_msg(project, header=False)
                if args.verbose:
                    ui_functions.print_info_msg("   -> {}".format(
                        ci_index_xml.get_project_xml(project)),
                                                header=False)
                    proj_manifest = ManifestXml(
                        find_project_in_single_index(project, ci_index_xml,
                                                     man_repos[repo][0])[1])
                    ui_functions.print_info_msg("   -> DevLead: {}".format(
                        ' '.join(
                            x for x in proj_manifest.project_info.dev_leads)),
                                                header=False)

            if args.archived:
                print()
                ui_functions.print_info_msg("Archived Projects:", header=False)
                for project in sorted(ci_index_xml.archived_project_list):
                    if project == current_project:
                        ui_functions.print_info_msg(project, header=False)
                    else:
                        ui_functions.print_warning_msg(project, header=False)
                    if args.verbose:
                        ui_functions.print_info_msg("   -> {}".format(
                            ci_index_xml.get_project_xml(project)),
                                                    header=False)
                        proj_manifest = ManifestXml(
                            find_project_in_single_index(
                                project, ci_index_xml, man_repos[repo][0])[1])
                        ui_functions.print_info_msg("   -> DevLead: {}".format(
                            ' '.join(x for x in
                                     proj_manifest.project_info.dev_leads)),
                                                    header=False)
Example #11
0
 def run_command(self, args, config):
     less_path, use_less = find_less()
     if use_less:
         output_string = ''
         separator = '\n'
     cfg, user_cfg, conflicts = list_available_manifest_repos(
         config['cfg_file'], config['user_cfg_file'])
     try:
         manifest = get_workspace_manifest()
         pull_workspace_manifest_repo(manifest, config['cfg_file'],
                                      config['user_cfg_file'],
                                      args.source_manifest_repo, False)
         src_manifest_repo = find_source_manifest_repo(
             manifest, config['cfg_file'], config['user_cfg_file'],
             args.source_manifest_repo)
         if src_manifest_repo in cfg:
             manifest_directory = config['cfg_file'].manifest_repo_abs_path(
                 src_manifest_repo)
         elif src_manifest_repo in user_cfg:
             manifest_directory = config[
                 'user_cfg_file'].manifest_repo_abs_path(src_manifest_repo)
         else:
             raise EdkrepoManifestNotFoundException(
                 SOURCE_MANIFEST_REPO_NOT_FOUND.format(
                     manifest.project_info.codename))
     except EdkrepoWorkspaceInvalidException:
         if not args.project:
             raise EdkrepoInvalidParametersException(humble.NOT_IN_WKSPCE)
         else:
             #arg parse provides a list so only use the first item since we are limiting users to one project
             manifest_repo, src_cfg, manifest_path = find_project_in_all_indices(
                 args.project[0], config['cfg_file'],
                 config['user_cfg_file'],
                 PROJ_NOT_IN_REPO.format(args.project[0]),
                 SOURCE_MANIFEST_REPO_NOT_FOUND.format(args.project[0]))
             if manifest_repo in cfg:
                 manifest_directory = config[
                     'cfg_file'].manifest_repo_abs_path(manifest_repo)
             elif manifest_repo in user_cfg:
                 manifest_directory = config[
                     'user_cfg_file'].manifest_repo_abs_path(manifest_repo)
             manifest = ManifestXml(manifest_path)
     if manifest.general_config.pin_path is None:
         print(humble.NO_PIN_FOLDER)
         return
     pin_folder = os.path.normpath(
         os.path.join(manifest_directory, manifest.general_config.pin_path))
     if args.verbose:
         if not use_less:
             print(humble.PIN_FOLDER.format(pin_folder))
         else:
             output_string = (humble.PIN_FOLDER.format(pin_folder))
     for dirpath, _, filenames in os.walk(pin_folder):
         for file in filenames:
             pin_file = os.path.join(dirpath, file)
             # Capture error output from manifest parser stdout to properly interleave with other pin data
             stdout = sys.stdout
             sys.stdout = io.StringIO()
             try:
                 pin = ManifestXml(pin_file)
             except TypeError:
                 continue
             parse_output = sys.stdout.getvalue()
             sys.stdout = stdout
             if pin.project_info.codename == manifest.project_info.codename:
                 if not use_less:
                     print('Pin File: {}'.format(file))
                     if args.verbose and not args.description:
                         print('Parsing Errors: {}\n'.format(
                             parse_output.strip()))
                     elif args.verbose and args.description:
                         print('Parsing Errors: {}'.format(
                             parse_output.strip()))
                     if args.description:
                         print('Description: {}\n'.format(
                             pin.project_info.description))
                 elif use_less:
                     output_string = separator.join(
                         (output_string, 'Pin File: {}'.format(file)))
                     if args.verbose and not args.description:
                         output_string = separator.join(
                             (output_string, 'Parsing Errors: {}\n'.format(
                                 parse_output.strip())))
                     elif args.verbose and args.description:
                         output_string = separator.join(
                             (output_string, 'Parsing Errors: {}'.format(
                                 parse_output.strip())))
                     if args.description:
                         output_string = separator.join(
                             (output_string, 'Description: {}\n'.format(
                                 pin.project_info.description)))
     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)
def find_project_in_all_indices(project,
                                edkrepo_cfg,
                                edkrepo_user_cfg,
                                except_msg_man_repo,
                                except_msg_not_found,
                                man_repo=None):
    '''
    Finds the project in all manifest repositories listed in the edkrepo.efg and
    edkrepo_user.cfg. If a project with the same name is found uses man_repo to select
    the correct entry
    '''

    cfg_man_repos, user_cfg_man_repos, conflicts = list_available_manifest_repos(
        edkrepo_cfg, edkrepo_user_cfg)
    projects = {}
    for repo in cfg_man_repos:
        manifest_dir = edkrepo_cfg.manifest_repo_abs_path(repo)
        # If the manifest directory does not exist clone it.
        if not os.path.exists(manifest_dir):
            pull_single_manifest_repo(
                edkrepo_cfg.get_manifest_repo_url(repo),
                edkrepo_cfg.get_manifest_repo_branch(repo),
                edkrepo_cfg.get_manifest_repo_local_path(repo),
                reset_hard=False)

        index_file = CiIndexXml(os.path.join(manifest_dir, CI_INDEX_FILE_NAME))
        found, man_path = find_project_in_single_index(project, index_file,
                                                       manifest_dir)
        if found:
            projects[repo] = ('edkrepo_cfg', man_path)
    for repo in user_cfg_man_repos:
        manifest_dir = edkrepo_user_cfg.manifest_repo_abs_path(repo)
        if not os.path.exists(manifest_dir):
            pull_single_manifest_repo(
                edkrepo_user_cfg.get_manifest_repo_url(repo),
                edkrepo_user_cfg.get_manifest_repo_branch(repo),
                edkrepo_user_cfg.get_manifest_repo_local_path(repo),
                reset_hard=False)
        index_file = CiIndexXml(os.path.join(manifest_dir, CI_INDEX_FILE_NAME))
        found, man_path = find_project_in_single_index(project, index_file,
                                                       manifest_dir)
        if found:
            projects[repo] = ('edkrepo_user_cfg', man_path)
    if len(projects.keys()) == 1:
        repo = list(projects.keys())[0]
        return repo, projects[repo][0], projects[repo][1]
    elif len(projects.keys()) > 1 and man_repo:
        try:
            return man_repo, projects[man_repo][0], projects[man_repo][1]
        except KeyError:
            raise EdkrepoInvalidParametersException(except_msg_man_repo)
    elif os.path.isabs(project):
        manifest = ManifestXml(project)
        try:
            found_manifest_repo, found_cfg, found_project = find_project_in_all_indices(
                manifest.project_info.codename, edkrepo_cfg, edkrepo_user_cfg,
                except_msg_man_repo, except_msg_not_found, man_repo)
            return found_manifest_repo, found_cfg, project
        except EdkrepoManifestNotFoundException:
            return None, None, project
    elif os.path.isfile(os.path.join(os.getcwd(), project)):
        manifest = ManifestXml(os.path.join(os.getcwd(), project))
        try:
            found_manifest_repo, found_cfg, found_project = find_project_in_all_indices(
                manifest.project_info.codename, edkrepo_cfg, edkrepo_user_cfg,
                except_msg_man_repo, except_msg_not_found, man_repo)
            return found_manifest_repo, found_cfg, project
        except EdkrepoManifestNotFoundException:
            return None, None, os.path.join(os.getcwd(), project)
    elif not os.path.dirname(project):
        for repo in cfg_man_repos:
            if (man_repo and (repo == man_repo)) or not man_repo:
                for dirpath, dirname, filenames in os.walk(
                        edkrepo_cfg.manifest_repo_abs_path(repo)):
                    if project in filenames:
                        return repo, 'edkrepo_cfg', os.path.join(
                            dirpath, project)
        for repo in user_cfg_man_repos:
            if (man_repo and (repo == man_repo)) or not man_repo:
                for dirpath, dirname, filenames in os.walk(
                        edkrepo_user_cfg.manifest_repo_abs_path(repo)):
                    if project in filenames:
                        return repo, 'edkrepo_user_cfg', os.path.join(
                            dirpath, project)
        raise EdkrepoManifestNotFoundException(
            humble.PROJ_NOT_IN_REPO.format(project))
    else:
        raise EdkrepoManifestNotFoundException(
            humble.PROJ_NOT_IN_REPO.format(project))
Example #13
0
    def run_command(self, args, config):
        pull_all_manifest_repos(config['cfg_file'], config['user_cfg_file'],
                                False)

        name_or_manifest = args.ProjectNameOrManifestFile
        workspace_dir = args.Workspace
        # Check to see if requested workspace exists. If not create it. If so check for empty
        if workspace_dir == '.':
            # User has selected the directory they are running edkrepo from
            workspace_dir = os.getcwd()
        else:
            workspace_dir = os.path.abspath(workspace_dir)
        if sys.platform == "win32":
            subst = get_subst_drive_dict()
            drive = os.path.splitdrive(workspace_dir)[0][0].upper()
            if drive in subst:
                workspace_dir = os.path.join(
                    subst[drive],
                    os.path.splitdrive(workspace_dir)[1][1:])
                workspace_dir = os.path.normpath(workspace_dir)
        if os.path.isdir(workspace_dir) and os.listdir(workspace_dir):
            raise EdkrepoInvalidParametersException(CLONE_INVALID_WORKSPACE)
        if not os.path.isdir(workspace_dir):
            os.makedirs(workspace_dir)

        cfg, user_cfg, conflicts = list_available_manifest_repos(
            config['cfg_file'], config['user_cfg_file'])
        try:
            manifest_repo, source_cfg, global_manifest_path = find_project_in_all_indices(
                args.ProjectNameOrManifestFile, config['cfg_file'],
                config['user_cfg_file'],
                PROJ_NOT_IN_REPO.format(args.ProjectNameOrManifestFile),
                SOURCE_MANIFEST_REPO_NOT_FOUND.format(
                    args.ProjectNameOrManifestFile), args.source_manifest_repo)
        except EdkrepoManifestNotFoundException:
            raise EdkrepoInvalidParametersException(CLONE_INVALID_PROJECT_ARG)

        # If this manifest is in a defined manifest repository validate the manifest within the manifest repo
        if manifest_repo in cfg:
            verify_single_manifest(config['cfg_file'], manifest_repo,
                                   global_manifest_path)
            update_editor_config(
                config,
                config['cfg_file'].manifest_repo_abs_path(manifest_repo))
        elif manifest_repo in user_cfg:
            verify_single_manifest(config['user_cfg_file'], manifest_repo,
                                   global_manifest_path)
            update_editor_config(
                config,
                config['user_cfg_file'].manifest_repo_abs_path(manifest_repo))

        # Copy project manifest to local manifest dir and rename it Manifest.xml.
        local_manifest_dir = os.path.join(workspace_dir, "repo")
        os.makedirs(local_manifest_dir)
        local_manifest_path = os.path.join(local_manifest_dir, "Manifest.xml")
        shutil.copy(global_manifest_path, local_manifest_path)
        manifest = ManifestXml(local_manifest_path)

        # Update the source manifest repository tag in the local copy of the manifest XML
        try:
            if 'source_manifest_repo' in vars(args).keys():
                find_source_manifest_repo(manifest, config['cfg_file'],
                                          config['user_cfg_file'],
                                          args.source_manifest_repo)
            else:
                find_source_manifest_repo(manifest, config['cfg_file'],
                                          config['user_cfg_file'], None)
        except EdkrepoManifestNotFoundException:
            pass

        # Process the combination name and make sure it can be found in the manifest
        if args.Combination is not None:
            try:
                combo_name = case_insensitive_single_match(
                    args.Combination, combinations_in_manifest(manifest))
            except:
                #remove the repo directory and Manifest.xml from the workspace so the next time the user trys to clone
                #they will have an empty workspace and then raise an exception
                shutil.rmtree(local_manifest_dir)
                raise EdkrepoInvalidParametersException(
                    CLONE_INVALID_COMBO_ARG)
            manifest.write_current_combo(combo_name)
        elif manifest.is_pin_file():
            # Since pin files are subset of manifest files they do not have a "default combo" it is set to None. In this
            # case use the current_combo instead.
            combo_name = manifest.general_config.current_combo
        else:
            # If a combo was not specified or a pin file used the default combo should be cloned.  Also ensure that the
            # current combo is updated to match.
            combo_name = manifest.general_config.default_combo
            manifest.write_current_combo(combo_name)

        # Get the list of repos to clone and clone them
        repo_sources_to_clone = manifest.get_repo_sources(combo_name)

        #check that the repo sources do not contain duplicated local roots
        local_roots = [r.root for r in repo_sources_to_clone]
        for root in local_roots:
            if local_roots.count(root) > 1:
                #remove the repo dir and manifest.xml so the next time the user trys to clone they will have an empty
                #workspace
                shutil.rmtree(local_manifest_dir)
                raise EdkrepoManifestInvalidException(
                    CLONE_INVALID_LOCAL_ROOTS)
        project_client_side_hooks = manifest.repo_hooks
        # Set up submodule alt url config settings prior to cloning any repos
        submodule_included_configs = write_included_config(
            manifest.remotes, manifest.submodule_alternate_remotes,
            local_manifest_dir)
        write_conditional_include(workspace_dir, repo_sources_to_clone,
                                  submodule_included_configs)

        # Determine if caching is going to be used and then clone
        cache_obj = get_repo_cache_obj(config)
        if cache_obj is not None:
            add_missing_cache_repos(cache_obj, manifest, args.verbose)
        clone_repos(args, workspace_dir, repo_sources_to_clone,
                    project_client_side_hooks, config, manifest, cache_obj)

        # Init submodules
        if not args.skip_submodule:
            cache_path = None
            if cache_obj is not None:
                cache_path = cache_obj.get_cache_path(
                    SUBMODULE_CACHE_REPO_NAME)
            maintain_submodules(workspace_dir, manifest, combo_name,
                                args.verbose, cache_path)

        # Perform a sparse checkout if requested.
        use_sparse = args.sparse
        sparse_settings = manifest.sparse_settings
        if sparse_settings is None:
            # No SparseCheckout information in manifest so skip sparse checkout
            use_sparse = False
        elif sparse_settings.sparse_by_default:
            # Sparse settings enabled by default for the project
            use_sparse = True
        if args.nosparse:
            # Command line disables sparse checkout
            use_sparse = False
        if use_sparse:
            ui_functions.print_info_msg(SPARSE_CHECKOUT)
            sparse_checkout(workspace_dir, repo_sources_to_clone, manifest)