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)
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)
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)
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)
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)
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()
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)
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)
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)