Last active
August 1, 2026 00:42
-
-
Save claudenobs/e0e57dabc2d405de47c2784a1bdef83c to your computer and use it in GitHub Desktop.
decluttering cachyos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import re | |
| import sys | |
| import subprocess | |
| import urllib.request | |
| import yaml | |
| from pathlib import Path | |
| url = "https://githubusercontent.com" | |
| cache_path = Path(__file__).parent / "netinstall.yaml" | |
| # Group flags that are always included by default in CachyOS | |
| BASE_GROUPS_HELP = { | |
| "CachyOS required (hidden)", | |
| "CachyOS Packages", | |
| "CachyOS shell configuration", | |
| "Base-devel + Common packages", | |
| "CPU specific Microcode update packages", | |
| } | |
| def download_yaml(): | |
| """Downloads the netinstall.yaml definition from CachyOS repository.""" | |
| if "--help" in sys.argv or "-h" in sys.argv: | |
| print("(Downloading package list to show available groups...)", file=sys.stderr) | |
| try: | |
| with urllib.request.urlopen(url) as response: | |
| content = response.read() | |
| cache_path.write_bytes(content) | |
| except Exception as e: | |
| print(f"Error downloading package list: {e}", file=sys.stderr) | |
| sys.exit(1) | |
| def get_transitive_dependencies(packages): | |
| """ | |
| Uses the system's `pactree` utility to find all transitive dependencies | |
| for the provided list of base packages. | |
| """ | |
| print("(Resolving transitive dependencies via pactree... This may take a moment)", file=sys.stderr) | |
| all_deps = set(packages) | |
| # Check if pactree is available on the host system | |
| if subprocess.call(["type", "pactree"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) != 0: | |
| print("Warning: 'pactree' utility not found. Please install 'pacman-contrib'.", file=sys.stderr) | |
| print("Falling back to standard pacman dependency resolving...", file=sys.stderr) | |
| return resolve_dependencies_fallback(packages) | |
| for pkg in packages: | |
| try: | |
| # pactree -u output gives a unique list of dependencies, one per line | |
| result = subprocess.run( | |
| ["pactree", "-u", pkg], | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.DEVNULL, | |
| text=True, | |
| check=True | |
| ) | |
| for line in result.stdout.splitlines(): | |
| dep = line.strip() | |
| if dep: | |
| all_deps.add(dep) | |
| except subprocess.CalledProcessError: | |
| # Skip errors for virtual/meta packages or items not currently in synced repos | |
| continue | |
| return all_deps | |
| def resolve_dependencies_fallback(packages): | |
| """Fallback method using standard `pacman -Si` queries if pactree is missing.""" | |
| all_deps = set(packages) | |
| queue = list(packages) | |
| processed = set() | |
| while queue: | |
| current = queue.pop(0) | |
| if current in processed: | |
| continue | |
| processed.add(current) | |
| try: | |
| result = subprocess.run( | |
| ["pacman", "-Si", current], | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.DEVNULL, | |
| text=True | |
| ) | |
| if result.returncode != 0: | |
| continue | |
| # Extract the 'Depends On' section out of the pacman sync info | |
| match = re.search(r"(?:Depends On|Depends)\s*:\s*(.*)", result.stdout) | |
| if match: | |
| dep_string = match.group(1) | |
| # Parse out version identifiers like >=2.0, clean up spaces and None values | |
| raw_deps = re.split(r'\s+', dep_string) | |
| for rd in raw_deps: | |
| rd = re.sub(r'[>=<].*', '', rd).strip() | |
| if rd and rd != "None" and rd not in all_deps: | |
| all_deps.add(rd) | |
| queue.append(rd) | |
| except Exception: | |
| continue | |
| return all_deps | |
| # Check for explicit manual refresh or if data is missing | |
| if "--refresh" in sys.argv or not cache_path.exists(): | |
| download_yaml() | |
| try: | |
| temp_data = yaml.safe_load(cache_path.read_text()) | |
| except Exception as e: | |
| print(f"Error parsing local YAML cache: {e}", file=sys.stderr) | |
| sys.exit(1) | |
| optional = [ | |
| item for item in temp_data | |
| if isinstance(item, dict) and "name" in item and item["name"] not in BASE_GROUPS_HELP | |
| ] | |
| # Display help menu | |
| if "--help" in sys.argv or "-h" in sys.argv: | |
| print("Usage: get_names.py [OPTIONS] [--<group-flag> ...]") | |
| print() | |
| print("Prints a list of packages for different CachyOS desktop environments and optional extras.") | |
| print() | |
| print("The following base groups are always included:") | |
| for name in sorted(BASE_GROUPS_HELP): | |
| print(f" - {name}") | |
| print() | |
| print("Options:") | |
| print(" -h, --help Show this help message and exit") | |
| print(" --refresh Re-download the package list from GitHub (ignores cache)") | |
| print(" --sort Sort the output package list alphabetically") | |
| print(" --dependencies Include all recursive/transitive package dependencies") | |
| print() | |
| import textwrap | |
| print("Optional package groups:") | |
| for item in optional: | |
| flag = re.sub(r"[^a-z0-9]+", "-", item["name"].lower()).strip("-") | |
| desc = item.get("description", "No description available.") | |
| prefix = f" --{flag:<40} " | |
| indent = " " * len(prefix) | |
| print(textwrap.fill(desc, width=90, initial_indent=prefix, subsequent_indent=indent)) | |
| sys.exit(0) | |
| # Build list of active packages based on command line choices | |
| target_packages = set() | |
| def extract_pkg_names(pkg_list): | |
| names = [] | |
| for pkg in pkg_list: | |
| if isinstance(pkg, str): | |
| names.append(pkg) | |
| elif isinstance(pkg, dict) and "name" in pkg: | |
| names.append(pkg["name"]) | |
| return names | |
| for item in temp_data: | |
| if not isinstance(item, dict) or "name" not in item: | |
| continue | |
| name = item["name"] | |
| flag = f"--{re.sub(r'[^a-z0-9]+', '-', name.lower()).strip('-')}" | |
| # Process if mandatory or selected by runtime argument flags | |
| if name in BASE_GROUPS_HELP or flag in sys.argv: | |
| extracted = extract_pkg_names(item.get("packages", [])) | |
| target_packages.update(extracted) | |
| # Expand to all transitive dependencies if explicitly requested | |
| if "--dependencies" in sys.argv: | |
| final_packages = list(get_transitive_dependencies(target_packages)) | |
| else: | |
| final_packages = list(target_packages) | |
| # Apply alphabetic sort if specified | |
| if "--sort" in sys.argv: | |
| final_packages.sort() | |
| # Output the package inventory | |
| for package in final_packages: | |
| print(package) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import re | |
| import sys | |
| import urllib.request | |
| import yaml | |
| from pathlib import Path | |
| url = "https://raw.githubusercontent.com/CachyOS/cachyos-calamares/cachyos-dev/src/modules/netinstall/netinstall.yaml" | |
| cache_path = Path(__file__).parent / "netinstall.yaml" | |
| if "--help" in sys.argv or "-h" in sys.argv: | |
| import io | |
| temp_data = None | |
| if cache_path.exists(): | |
| temp_data = yaml.safe_load(cache_path.read_text()) | |
| else: | |
| print("(Downloading package list to show available groups...)", file=sys.stderr) | |
| with urllib.request.urlopen(url) as response: | |
| content = response.read() | |
| cache_path.write_bytes(content) | |
| temp_data = yaml.safe_load(cache_path.read_text()) | |
| BASE_GROUPS_HELP = { | |
| "CachyOS required (hidden)", | |
| "CachyOS Packages", | |
| "CachyOS shell configuration", | |
| "Base-devel + Common packages", | |
| "CPU specific Microcode update packages", | |
| } | |
| optional = [ | |
| item for item in temp_data | |
| if isinstance(item, dict) and "name" in item and item["name"] not in BASE_GROUPS_HELP | |
| ] | |
| print("Usage: get_names.py [OPTIONS] [--<group-flag> ...]") | |
| print() | |
| print("Prints a list of packages for different CachyOS desktop environments and optional extras.") | |
| print() | |
| print("The following base groups are always included:") | |
| for name in sorted(BASE_GROUPS_HELP): | |
| print(f" - {name}") | |
| print() | |
| print("Options:") | |
| print(" -h, --help Show this help message and exit") | |
| print(" --refresh Re-download the package list from GitHub (ignores cache)") | |
| print(" --sort Sort the output package list alphabetically") | |
| print() | |
| import textwrap | |
| print("Optional package groups:") | |
| for item in optional: | |
| flag = re.sub(r"[^a-z0-9]+", "-", item["name"].lower()).strip("-") | |
| desc = item.get("description", "") | |
| prefix = f" --{flag:<40} " | |
| indent = " " * len(prefix) | |
| wrapped = textwrap.fill(desc, width=120, initial_indent=prefix, subsequent_indent=indent) | |
| print(wrapped) | |
| sys.exit(0) | |
| force_download = "--refresh" in sys.argv | |
| if force_download or not cache_path.exists(): | |
| with urllib.request.urlopen(url) as response: | |
| content = response.read() | |
| cache_path.write_bytes(content) | |
| print(f"Downloaded and cached to {cache_path}", file=sys.stderr) | |
| else: | |
| print(f"Using cached file: {cache_path}", file=sys.stderr) | |
| data = yaml.safe_load(cache_path.read_text()) | |
| BASE_GROUPS = { | |
| "CachyOS required (hidden)", | |
| "CachyOS Packages", | |
| "CachyOS shell configuration", | |
| "Base-devel + Common packages", | |
| "CPU specific Microcode update packages", | |
| } | |
| def collect_packages(item): | |
| pkgs = list(item.get("packages") or []) | |
| for sub in item.get("subgroups") or []: | |
| pkgs.extend(collect_packages(sub)) | |
| return pkgs | |
| def name_to_flag(name): | |
| slug = name.lower() | |
| slug = re.sub(r"[^a-z0-9]+", "-", slug) | |
| return slug.strip("-") | |
| optional_groups = { | |
| name_to_flag(item["name"]): item | |
| for item in data | |
| if isinstance(item, dict) and "name" in item and item["name"] not in BASE_GROUPS | |
| } | |
| base_packages = [] | |
| for item in data: | |
| if isinstance(item, dict) and item.get("name") in BASE_GROUPS: | |
| base_packages.extend(collect_packages(item)) | |
| for flag, item in optional_groups.items(): | |
| if f"--{flag}" in sys.argv: | |
| base_packages.extend(collect_packages(item)) | |
| packages = sorted(base_packages) if "--sort" in sys.argv else base_packages | |
| for pkg in packages: | |
| print(pkg) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import re | |
| import sys | |
| import subprocess | |
| import urllib.request | |
| import yaml | |
| from pathlib import Path | |
| url = "https://githubusercontent.com" | |
| cache_path = Path(__file__).parent / "netinstall.yaml" | |
| # Group flags that are always included by default in CachyOS | |
| BASE_GROUPS_HELP = { | |
| "CachyOS required (hidden)", | |
| "CachyOS Packages", | |
| "CachyOS shell configuration", | |
| "Base-devel + Common packages", | |
| "CPU specific Microcode update packages", | |
| } | |
| def download_yaml(): | |
| """Downloads the netinstall.yaml definition from CachyOS repository.""" | |
| if "--help" in sys.argv or "-h" in sys.argv: | |
| print("(Downloading package list to show available groups...)", file=sys.stderr) | |
| try: | |
| with urllib.request.urlopen(url) as response: | |
| content = response.read() | |
| cache_path.write_bytes(content) | |
| except Exception as e: | |
| print(f"Error downloading package list: {e}", file=sys.stderr) | |
| sys.exit(1) | |
| def get_transitive_dependencies(packages): | |
| """ | |
| Uses the system's `pactree` utility to find all transitive dependencies | |
| for the provided list of base packages. | |
| """ | |
| print("(Resolving transitive dependencies via pactree... This may take a moment)", file=sys.stderr) | |
| all_deps = set(packages) | |
| # Check if pactree is available on the host system | |
| if subprocess.call(["type", "pactree"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) != 0: | |
| print("Warning: 'pactree' utility not found. Please install 'pacman-contrib'.", file=sys.stderr) | |
| print("Falling back to standard pacman dependency resolving...", file=sys.stderr) | |
| return resolve_dependencies_fallback(packages) | |
| for pkg in packages: | |
| try: | |
| # pactree -u output gives a unique list of dependencies, one per line | |
| result = subprocess.run( | |
| ["pactree", "-u", pkg], | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.DEVNULL, | |
| text=True, | |
| check=True | |
| ) | |
| for line in result.stdout.splitlines(): | |
| dep = line.strip() | |
| if dep: | |
| all_deps.add(dep) | |
| except subprocess.CalledProcessError: | |
| # Skip errors for virtual/meta packages or items not currently in synced repos | |
| continue | |
| return all_deps | |
| def resolve_dependencies_fallback(packages): | |
| """Fallback method using standard `pacman -Si` queries if pactree is missing.""" | |
| all_deps = set(packages) | |
| queue = list(packages) | |
| processed = set() | |
| while queue: | |
| current = queue.pop(0) | |
| if current in processed: | |
| continue | |
| processed.add(current) | |
| try: | |
| result = subprocess.run( | |
| ["pacman", "-Si", current], | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.DEVNULL, | |
| text=True | |
| ) | |
| if result.returncode != 0: | |
| continue | |
| # Extract the 'Depends On' section out of the pacman sync info | |
| match = re.search(r"(?:Depends On|Depends)\s*:\s*(.*)", result.stdout) | |
| if match: | |
| dep_string = match.group(1) | |
| # Parse out version identifiers like >=2.0, clean up spaces and None values | |
| raw_deps = re.split(r'\s+', dep_string) | |
| for rd in raw_deps: | |
| rd = re.sub(r'[>=<].*', '', rd).strip() | |
| if rd and rd != "None" and rd not in all_deps: | |
| all_deps.add(rd) | |
| queue.append(rd) | |
| except Exception: | |
| continue | |
| return all_deps | |
| def parse_extra_packages(): | |
| """Parses extra packages supplied via --include or -i flags.""" | |
| extra_pkgs = set() | |
| args = sys.argv | |
| for flag in ("--include", "-i"): | |
| if flag in args: | |
| try: | |
| idx = args.index(flag) | |
| val = args[idx + 1] | |
| # Split by commas and strip surrounding whitespace | |
| for p in val.split(","): | |
| p_cleaned = p.strip() | |
| if p_cleaned: | |
| extra_pkgs.add(p_cleaned) | |
| except IndexError: | |
| print(f"Error: {flag} requires a comma-separated list of packages.", file=sys.stderr) | |
| sys.exit(1) | |
| return extra_pkgs | |
| # Check for explicit manual refresh or if data is missing | |
| if "--refresh" in sys.argv or not cache_path.exists(): | |
| download_yaml() | |
| try: | |
| temp_data = yaml.safe_load(cache_path.read_text()) | |
| except Exception as e: | |
| print(f"Error parsing local YAML cache: {e}", file=sys.stderr) | |
| sys.exit(1) | |
| optional = [ | |
| item for item in temp_data | |
| if isinstance(item, dict) and "name" in item and item["name"] not in BASE_GROUPS_HELP | |
| ] | |
| # Display help menu | |
| if "--help" in sys.argv or "-h" in sys.argv: | |
| print("Usage: get_names.py [OPTIONS] [--<group-flag> ...]") | |
| print() | |
| print("Prints a list of packages for different CachyOS desktop environments and optional extras.") | |
| print() | |
| print("The following base groups are always included:") | |
| for name in sorted(BASE_GROUPS_HELP): | |
| print(f" - {name}") | |
| print() | |
| print("Options:") | |
| print(" -h, --help Show this help message and exit") | |
| print(" --refresh Re-download the package list from GitHub (ignores cache)") | |
| print(" --sort Sort the output package list alphabetically") | |
| print(" --dependencies Include all recursive/transitive package dependencies") | |
| print(" -i, --include <pkgs> Include extra comma-separated packages (e.g., -i gimp,vlc)") | |
| print() | |
| import textwrap | |
| print("Optional package groups:") | |
| for item in optional: | |
| flag = re.sub(r"[^a-z0-9]+", "-", item["name"].lower()).strip("-") | |
| desc = item.get("description", "No description available.") | |
| prefix = f" --{flag:<40} " | |
| indent = " " * len(prefix) | |
| print(textwrap.fill(desc, width=90, initial_indent=prefix, subsequent_indent=indent)) | |
| sys.exit(0) | |
| # Build list of active packages based on command line choices | |
| target_packages = set() | |
| def extract_pkg_names(pkg_list): | |
| names = [] | |
| for pkg in pkg_list: | |
| if isinstance(pkg, str): | |
| names.append(pkg) | |
| elif isinstance(pkg, dict) and "name" in pkg: | |
| names.append(pkg["name"]) | |
| return names | |
| for item in temp_data: | |
| if not isinstance(item, dict) or "name" not in item: | |
| continue | |
| name = item["name"] | |
| flag = f"--{re.sub(r'[^a-z0-9]+', '-', name.lower()).strip('-')}" | |
| # Process if mandatory or selected by runtime argument flags | |
| if name in BASE_GROUPS_HELP or flag in sys.argv: | |
| extracted = extract_pkg_names(item.get("packages", [])) | |
| target_packages.update(extracted) | |
| # Inject extra user-defined packages | |
| extra_packages = parse_extra_packages() | |
| target_packages.update(extra_packages) | |
| # Expand to all transitive dependencies if explicitly requested | |
| if "--dependencies" in sys.argv: | |
| final_packages = list(get_transitive_dependencies(target_packages)) | |
| else: | |
| final_packages = list(target_packages) | |
| # Apply alphabetic sort if specified | |
| if "--sort" in sys.argv: | |
| final_packages.sort() | |
| # Output the package inventory | |
| for package in final_packages: | |
| print(package) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import re | |
| import sys | |
| import subprocess | |
| import urllib.request | |
| import yaml | |
| from pathlib import Path | |
| url = "https://githubusercontent.com" | |
| cache_path = Path(__file__).parent / "netinstall.yaml" | |
| # Group flags that are always included by default in CachyOS | |
| BASE_GROUPS_HELP = { | |
| "CachyOS required (hidden)", | |
| "CachyOS Packages", | |
| "CachyOS shell configuration", | |
| "Base-devel + Common packages", | |
| "CPU specific Microcode update packages", | |
| } | |
| def download_yaml(): | |
| """Downloads the netinstall.yaml definition from CachyOS repository.""" | |
| if "--help" in sys.argv or "-h" in sys.argv: | |
| print("(Downloading package list to show available groups...)", file=sys.stderr) | |
| try: | |
| with urllib.request.urlopen(url) as response: | |
| content = response.read() | |
| cache_path.write_bytes(content) | |
| except Exception as e: | |
| print(f"Error downloading package list: {e}", file=sys.stderr) | |
| sys.exit(1) | |
| def get_transitive_dependencies(packages): | |
| """ | |
| Uses the system's `pactree` utility to find all transitive dependencies | |
| for the provided list of base packages. | |
| """ | |
| print("(Resolving transitive dependencies via pactree... This may take a moment)", file=sys.stderr) | |
| all_deps = set(packages) | |
| # Check if pactree is available on the host system | |
| if subprocess.call(["type", "pactree"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) != 0: | |
| print("Warning: 'pactree' utility not found. Please install 'pacman-contrib'.", file=sys.stderr) | |
| print("Falling back to standard pacman dependency resolving...", file=sys.stderr) | |
| return resolve_dependencies_fallback(packages) | |
| for pkg in packages: | |
| try: | |
| # pactree -u output gives a unique list of dependencies, one per line | |
| result = subprocess.run( | |
| ["pactree", "-u", pkg], | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.DEVNULL, | |
| text=True, | |
| check=True | |
| ) | |
| for line in result.stdout.splitlines(): | |
| dep = line.strip() | |
| if dep: | |
| all_deps.add(dep) | |
| except subprocess.CalledProcessError: | |
| # Skip errors for virtual/meta packages or items not currently in synced repos | |
| continue | |
| return all_deps | |
| def resolve_dependencies_fallback(packages): | |
| """Fallback method using standard `pacman -Si` queries if pactree is missing.""" | |
| all_deps = set(packages) | |
| queue = list(packages) | |
| processed = set() | |
| while queue: | |
| current = queue.pop(0) | |
| if current in processed: | |
| continue | |
| processed.add(current) | |
| try: | |
| result = subprocess.run( | |
| ["pacman", "-Si", current], | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.DEVNULL, | |
| text=True | |
| ) | |
| if result.returncode != 0: | |
| continue | |
| # Extract the 'Depends On' section out of the pacman sync info | |
| match = re.search(r"(?:Depends On|Depends)\s*:\s*(.*)", result.stdout) | |
| if match: | |
| dep_string = match.group(1) | |
| # Parse out version identifiers like >=2.0, clean up spaces and None values | |
| raw_deps = re.split(r'\s+', dep_string) | |
| for rd in raw_deps: | |
| rd = re.sub(r'[>=<].*', '', rd).strip() | |
| if rd and rd != "None" and rd not in all_deps: | |
| all_deps.add(rd) | |
| queue.append(rd) | |
| except Exception: | |
| continue | |
| return all_deps | |
| def parse_extra_packages(): | |
| """Parses extra packages supplied via --include or -i flags from raw strings or files.""" | |
| extra_pkgs = set() | |
| args = sys.argv | |
| for flag in ("--include", "-i"): | |
| if flag in args: | |
| try: | |
| idx = args.index(flag) | |
| val = args[idx + 1] | |
| path_target = Path(val) | |
| # If argument points to a valid file path, parse by whitespace/newlines | |
| if path_target.is_file(): | |
| content = path_target.read_text() | |
| # split() with no arguments matches any consecutive whitespace (newlines, tabs, spaces) | |
| for p in content.split(): | |
| p_cleaned = p.strip() | |
| if p_cleaned: | |
| extra_pkgs.add(p_cleaned) | |
| else: | |
| # Otherwise, fallback to fallback comma-separated values line parser | |
| for p in val.split(","): | |
| p_cleaned = p.strip() | |
| if p_cleaned: | |
| extra_pkgs.add(p_cleaned) | |
| except IndexError: | |
| print(f"Error: {flag} requires a comma-separated list or a valid file path.", file=sys.stderr) | |
| sys.exit(1) | |
| except Exception as e: | |
| print(f"Error reading include resource: {e}", file=sys.stderr) | |
| sys.exit(1) | |
| return extra_pkgs | |
| # Check for explicit manual refresh or if data is missing | |
| if "--refresh" in sys.argv or not cache_path.exists(): | |
| download_yaml() | |
| try: | |
| temp_data = yaml.safe_load(cache_path.read_text()) | |
| except Exception as e: | |
| print(f"Error parsing local YAML cache: {e}", file=sys.stderr) | |
| sys.exit(1) | |
| optional = [ | |
| item for item in temp_data | |
| if isinstance(item, dict) and "name" in item and item["name"] not in BASE_GROUPS_HELP | |
| ] | |
| # Display help menu | |
| if "--help" in sys.argv or "-h" in sys.argv: | |
| print("Usage: get_names.py [OPTIONS] [--<group-flag> ...]") | |
| print() | |
| print("Prints a list of packages for different CachyOS desktop environments and optional extras.") | |
| print() | |
| print("The following base groups are always included:") | |
| for name in sorted(BASE_GROUPS_HELP): | |
| print(f" - {name}") | |
| print() | |
| print("Options:") | |
| print(" -h, --help Show this help message and exit") | |
| print(" --refresh Re-download the package list from GitHub (ignores cache)") | |
| print(" --sort Sort the output package list alphabetically") | |
| print(" --dependencies Include all recursive/transitive package dependencies") | |
| print(" -i, --include <src> Include extra items via comma-separated list or whitespace-separated file path") | |
| print() | |
| import textwrap | |
| print("Optional package groups:") | |
| for item in optional: | |
| flag = re.sub(r"[^a-z0-9]+", "-", item["name"].lower()).strip("-") | |
| desc = item.get("description", "No description available.") | |
| prefix = f" --{flag:<40} " | |
| indent = " " * len(prefix) | |
| print(textwrap.fill(desc, width=90, initial_indent=prefix, subsequent_indent=indent)) | |
| sys.exit(0) | |
| # Build list of active packages based on command line choices | |
| target_packages = set() | |
| def extract_pkg_names(pkg_list): | |
| names = [] | |
| for pkg in pkg_list: | |
| if isinstance(pkg, str): | |
| names.append(pkg) | |
| elif isinstance(pkg, dict) and "name" in pkg: | |
| names.append(pkg["name"]) | |
| return names | |
| for item in temp_data: | |
| if not isinstance(item, dict) or "name" not in item: | |
| continue | |
| name = item["name"] | |
| flag = f"--{re.sub(r'[^a-z0-9]+', '-', name.lower()).strip('-')}" | |
| # Process if mandatory or selected by runtime argument flags | |
| if name in BASE_GROUPS_HELP or flag in sys.argv: | |
| extracted = extract_pkg_names(item.get("packages", [])) | |
| target_packages.update(extracted) | |
| # Inject extra user-defined packages | |
| extra_packages = parse_extra_packages() | |
| target_packages.update(extra_packages) | |
| # Expand to all transitive dependencies if explicitly requested | |
| if "--dependencies" in sys.argv: | |
| final_packages = list(get_transitive_dependencies(target_packages)) | |
| else: | |
| final_packages = list(target_packages) | |
| # Apply alphabetic sort if specified | |
| if "--sort" in sys.argv: | |
| final_packages.sort() | |
| # Output the package inventory | |
| for package in final_packages: | |
| print(package) |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
i'd suggest calling it as follows: