Files
pkgmgr/pkgmgr/cli/commands/repos.py
Kevin Veen-Birkenbach d50891dfe5 Refactor: Restructure pkgmgr into actions/, core/, and cli/ (full module breakup)
This commit introduces a large-scale structural refactor of the pkgmgr
codebase. All functionality has been moved from the previous flat
top-level layout into three clearly separated namespaces:

  • pkgmgr.actions      – high-level operations invoked by the CLI
  • pkgmgr.core         – pure logic, helpers, repository utilities,
                          versioning, git helpers, config IO, and
                          command resolution
  • pkgmgr.cli          – parser, dispatch, context, and command
                          handlers

Key improvements:
  - Moved all “branch”, “release”, “changelog”, repo-management
    actions, installer pipelines, and proxy execution logic into
    pkgmgr.actions.<domain>.
  - Reworked installer structure under
        pkgmgr.actions.repository.install.installers
    including OS-package installers, Nix, Python, and Makefile.
  - Consolidated all low-level functionality under pkgmgr.core:
        • git helpers → core/git
        • config load/save → core/config
        • repository helpers → core/repository
        • versioning & semver → core/version
        • command helpers (alias, resolve, run, ink) → core/command
  - Replaced pkgmgr.cli_core with pkgmgr.cli and updated all imports.
  - Added minimal __init__.py files for clean package exposure.
  - Updated all E2E, integration, and unit tests with new module paths.
  - Fixed patch targets so mocks point to the new structure.
  - Ensured backward compatibility at the CLI boundary (pkgmgr entry point unchanged).

This refactor produces a cleaner, layered architecture:
  - `core` = logic
  - `actions` = orchestrated behaviour
  - `cli` = user interface

Reference: ChatGPT-assisted refactor discussion
https://chatgpt.com/share/6938221c-e24c-800f-8317-7732cedf39b9
2025-12-09 14:20:19 +01:00

172 lines
5.3 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from __future__ import annotations
import sys
from typing import Any, Dict, List
from pkgmgr.cli.context import CLIContext
from pkgmgr.actions.repository.install import install_repos
from pkgmgr.actions.repository.deinstall import deinstall_repos
from pkgmgr.actions.repository.delete import delete_repos
from pkgmgr.actions.repository.update import update_repos
from pkgmgr.actions.repository.status import status_repos
from pkgmgr.actions.repository.list import list_repositories
from pkgmgr.core.command.run import run_command
from pkgmgr.actions.repository.create import create_repo
from pkgmgr.core.repository.selected import get_selected_repos
Repository = Dict[str, Any]
def handle_repos_command(
args,
ctx: CLIContext,
selected: List[Repository],
) -> None:
"""
Handle core repository commands (install/update/deinstall/delete/.../list).
"""
# ------------------------------------------------------------
# install
# ------------------------------------------------------------
if args.command == "install":
install_repos(
selected,
ctx.repositories_base_dir,
ctx.binaries_dir,
ctx.all_repositories,
args.no_verification,
args.preview,
args.quiet,
args.clone_mode,
args.dependencies,
)
return
# ------------------------------------------------------------
# update
# ------------------------------------------------------------
if args.command == "update":
update_repos(
selected,
ctx.repositories_base_dir,
ctx.binaries_dir,
ctx.all_repositories,
args.no_verification,
args.system,
args.preview,
args.quiet,
args.dependencies,
args.clone_mode,
)
return
# ------------------------------------------------------------
# deinstall
# ------------------------------------------------------------
if args.command == "deinstall":
deinstall_repos(
selected,
ctx.repositories_base_dir,
ctx.binaries_dir,
ctx.all_repositories,
preview=args.preview,
)
return
# ------------------------------------------------------------
# delete
# ------------------------------------------------------------
if args.command == "delete":
delete_repos(
selected,
ctx.repositories_base_dir,
ctx.all_repositories,
preview=args.preview,
)
return
# ------------------------------------------------------------
# status
# ------------------------------------------------------------
if args.command == "status":
status_repos(
selected,
ctx.repositories_base_dir,
ctx.all_repositories,
args.extra_args,
list_only=args.list,
system_status=args.system,
preview=args.preview,
)
return
# ------------------------------------------------------------
# path
# ------------------------------------------------------------
if args.command == "path":
for repository in selected:
print(repository["directory"])
return
# ------------------------------------------------------------
# shell
# ------------------------------------------------------------
if args.command == "shell":
if not args.shell_command:
print("[ERROR] 'shell' requires a command via -c/--command.")
sys.exit(2)
command_to_run = " ".join(args.shell_command)
for repository in selected:
print(
f"Executing in '{repository['directory']}': {command_to_run}"
)
run_command(
command_to_run,
cwd=repository["directory"],
preview=args.preview,
)
return
# ------------------------------------------------------------
# create
# ------------------------------------------------------------
if args.command == "create":
if not args.identifiers:
print(
"[ERROR] 'create' requires at least one identifier "
"in the format provider/account/repository."
)
sys.exit(1)
for identifier in args.identifiers:
create_repo(
identifier,
ctx.config_merged,
ctx.user_config_path,
ctx.binaries_dir,
remote=args.remote,
preview=args.preview,
)
return
# ------------------------------------------------------------
# list
# ------------------------------------------------------------
if args.command == "list":
list_repositories(
selected,
ctx.repositories_base_dir,
ctx.binaries_dir,
status_filter=getattr(args, "status", "") or "",
extra_tags=getattr(args, "tag", []) or [],
show_description=getattr(args, "description", False),
)
return
print(f"[ERROR] Unknown repos command: {args.command}")
sys.exit(2)