diff --git a/config/defaults.yaml b/config/defaults.yaml index d4715b0..d975f88 100644 --- a/config/defaults.yaml +++ b/config/defaults.yaml @@ -34,10 +34,9 @@ repositories: alias: bsr provider: github.com repository: bulk-string-replacer - command: python replace_string.py description: Bulk String Replacer CLI (bsr) is a command-line tool for efficiently searching and replacing strings in file names, folder names, and file contents across directories. It's perfect for bulk updates and streamlining your workflow. homepage: https://github.com/kevinveenbirkenbach/bulk-string-replacer - verified: ce964188786d4d2d6f046de6e070fed1443ccc73 + verified: daf45389383ef6b3d6569d63eb3e052ab811916d - account: kevinveenbirkenbach alias: imgrszr provider: github.com @@ -219,4 +218,4 @@ repositories: Bulk Rename is a Python-based CLI tool that renames files in bulk by replacing specified substrings in file names. It supports both recursive and non-recursive renaming with verbose output. homepage: https://github.com/kevinveenbirkenbach/bulk-rename - verified: dc2ecefd3b7a64f5dcbd808fed5f53886a766315 \ No newline at end of file + verified: f76b29720edf2df5760070e34eacae23beb9d3a7 \ No newline at end of file diff --git a/pkgmgr/list_repositories.py b/pkgmgr/list_repositories.py index 614c3a8..c391207 100644 --- a/pkgmgr/list_repositories.py +++ b/pkgmgr/list_repositories.py @@ -1,9 +1,11 @@ import os from pkgmgr.get_repo_identifier import get_repo_identifier from pkgmgr.get_repo_dir import get_repo_dir + def list_repositories(all_repos, repositories_base_dir, bin_dir, search_filter="", status_filter=""): """ - List all repositories with their attributes and status information. + Lists all repositories with their attributes and status information. + The repositories are sorted in ascending order by their identifier. Parameters: all_repos (list): List of repository configurations. @@ -20,7 +22,7 @@ def list_repositories(all_repos, repositories_base_dir, bin_dir, search_filter=" """ search_filter = search_filter.lower() if search_filter else "" status_filter = status_filter.lower() if status_filter else "" - + # Define status colors using colors not used for other attributes: # Avoid red (for ignore), blue (for homepage) and yellow (for verified). status_colors = { @@ -32,8 +34,11 @@ def list_repositories(all_repos, repositories_base_dir, bin_dir, search_filter=" "Active": "\033[38;5;129m", # Light Purple (extended) "Installable": "\033[38;5;82m" # Light Green (extended) } - - for repo in all_repos: + + # Sort all repositories by their identifier in ascending order. + sorted_repos = sorted(all_repos, key=lambda repo: get_repo_identifier(repo, all_repos)) + + for repo in sorted_repos: # Combine all attribute values into one string for filtering. repo_text = " ".join(str(v) for v in repo.values()).lower() if search_filter and search_filter not in repo_text: @@ -44,7 +49,7 @@ def list_repositories(all_repos, repositories_base_dir, bin_dir, search_filter=" executable_path = os.path.join(bin_dir, identifier) repo_dir = get_repo_dir(repositories_base_dir, repo) status_list = [] - + # Check if the executable exists (Installed). if os.path.exists(executable_path): status_list.append("Installed") @@ -63,11 +68,11 @@ def list_repositories(all_repos, repositories_base_dir, bin_dir, search_filter=" # Define installable as cloned but not installed. if os.path.exists(repo_dir) and not os.path.exists(executable_path): status_list.append("Installable") - + # Build a colored status string. colored_statuses = [f"{status_colors.get(s, '')}{s}\033[0m" for s in status_list] status_str = ", ".join(colored_statuses) - + # If a status_filter is provided, only display repos whose status contains the filter. if status_filter and status_filter not in status_str.lower(): continue @@ -83,10 +88,10 @@ def list_repositories(all_repos, repositories_base_dir, bin_dir, search_filter=" # Loop through all attributes. for key, value in repo.items(): formatted_value = str(value) - # Special formatting for "verified" attribute (yellow). + # Special formatting for the "verified" attribute (yellow). if key == "verified" and value: formatted_value = f"\033[1;33m{value}\033[0m" - # Special formatting for "ignore" flag (red if True). + # Special formatting for the "ignore" flag (red if True). if key == "ignore" and value: formatted_value = f"\033[1;31m{value}\033[0m" if key == "description": @@ -100,4 +105,4 @@ def list_repositories(all_repos, repositories_base_dir, bin_dir, search_filter=" # If the repository is installed, display a hint for more info. if os.path.exists(executable_path): print(f"\nMore information and help: \033[1;4mpkgmgr {identifier} --help\033[0m\n") - print("-" * 40) \ No newline at end of file + print("-" * 40) diff --git a/pkgmgr/pull_with_verification.py b/pkgmgr/pull_with_verification.py index 097bf40..904e036 100644 --- a/pkgmgr/pull_with_verification.py +++ b/pkgmgr/pull_with_verification.py @@ -7,10 +7,11 @@ from pkgmgr.get_repo_dir import get_repo_dir def pull_with_verification(selected_repos, repositories_base_dir, all_repos, extra_args, no_verification, preview=False): """ Executes "git pull" for each repository with hash verification. - + For repositories with a 'verified' hash in the configuration, this function first - checks the current commit hash. If it does not match the verified hash, the user is prompted - to confirm the pull (unless --no-verification is set, in which case the pull proceeds automatically). + retrieves the remote commit hash (using 'git ls-remote origin HEAD'). If the remote hash + does not match the verified hash, the user is prompted to confirm the pull (unless --no-verification + is set, in which case the pull proceeds automatically). """ for repo in selected_repos: repo_identifier = get_repo_identifier(repo, all_repos) @@ -20,17 +21,18 @@ def pull_with_verification(selected_repos, repositories_base_dir, all_repos, ext continue verified_hash = repo.get("verified") - current_hash = "" + remote_hash = "" try: - result = subprocess.run("git rev-parse HEAD", cwd=repo_dir, shell=True, check=True, - stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - current_hash = result.stdout.strip() + result = subprocess.run("git ls-remote origin HEAD", cwd=repo_dir, shell=True, check=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + # The first token in the output is the remote HEAD commit hash. + remote_hash = result.stdout.split()[0].strip() except Exception as e: - print(f"Error retrieving current commit for {repo_identifier}: {e}") + print(f"Error retrieving remote commit for {repo_identifier}: {e}") proceed = True - if not no_verification and verified_hash and current_hash != verified_hash: - print(f"Warning: For {repo_identifier}, the current hash ({current_hash}) does not match the verified hash ({verified_hash}).") + if not no_verification and verified_hash and remote_hash and remote_hash != verified_hash: + print(f"Warning: For {repo_identifier}, the remote hash ({remote_hash}) does not match the verified hash ({verified_hash}).") choice = input("Proceed with 'git pull'? (y/N): ").strip().lower() if choice != "y": proceed = False