diff --git a/.github/workflows/test-nix-flake-e2e.yml b/.github/workflows/test-virgin-root.yml similarity index 81% rename from .github/workflows/test-nix-flake-e2e.yml rename to .github/workflows/test-virgin-root.yml index adec740..a81d9e2 100644 --- a/.github/workflows/test-nix-flake-e2e.yml +++ b/.github/workflows/test-virgin-root.yml @@ -1,4 +1,4 @@ -name: Test Virgin +name: Test Virgin Root on: push: @@ -10,7 +10,7 @@ on: pull_request: jobs: - test-virgin: + test-virgin-root: runs-on: ubuntu-latest timeout-minutes: 45 @@ -21,16 +21,14 @@ jobs: - name: Show Docker version run: docker version - - name: Virgin Arch pkgmgr flake test + - name: Virgin Arch pkgmgr flake test (root) run: | set -euo pipefail - echo ">>> Starting virgin ArchLinux container test (with shared caches)..." + echo ">>> Starting virgin ArchLinux container test (root, with shared caches)..." docker run --rm \ -v "$PWD":/src \ - -v pkgmgr_nix_store:/nix \ - -v pkgmgr_nix_cache:/root/.cache/nix \ -v pkgmgr_repos:/root/Repositories \ -v pkgmgr_pip_cache:/root/.cache/pip \ -w /src \ @@ -59,8 +57,8 @@ jobs: echo ">>> Running: pkgmgr update pkgmgr --clone-mode shallow --no-verification" pkgmgr update pkgmgr --clone-mode shallow --no-verification - echo ">>> Running: pkgmgr version" + echo ">>> Running: pkgmgr version pkgmgr" pkgmgr version pkgmgr - echo ">>> Virgin Arch test completed successfully." + echo ">>> Virgin Arch (root) test completed successfully." ' diff --git a/.github/workflows/test-virgin-user.yml b/.github/workflows/test-virgin-user.yml new file mode 100644 index 0000000..42ce61e --- /dev/null +++ b/.github/workflows/test-virgin-user.yml @@ -0,0 +1,79 @@ +name: Test Virgin User + +on: + push: + branches: + - main + - master + - develop + - "*" + pull_request: + +jobs: + test-virgin-user: + runs-on: ubuntu-latest + timeout-minutes: 45 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Show Docker version + run: docker version + + - name: Virgin Arch pkgmgr user test (non-root with sudo) + run: | + set -euo pipefail + + echo ">>> Starting virgin ArchLinux container test (non-root user with sudo)..." + + docker run --rm \ + -v "$PWD":/src \ + archlinux:latest \ + bash -lc ' + set -euo pipefail + + echo ">>> [root] Updating and upgrading Arch system..." + pacman -Syu --noconfirm git python python-pip sudo base-devel debugedit + + echo ">>> [root] Creating non-root user dev..." + useradd -m dev + + echo ">>> [root] Allowing passwordless sudo for dev..." + echo "dev ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/dev + chmod 0440 /etc/sudoers.d/dev + + echo ">>> [root] Adjusting ownership of /src for dev..." + chown -R dev:dev /src + + echo ">>> [root] Running pkgmgr flow as non-root user dev..." + sudo -u dev env PKGMGR_DISABLE_NIX_FLAKE_INSTALLER=1 bash -lc " + set -euo pipefail + cd /src + + echo \">>> [dev] Using user: \$(whoami)\" + echo \">>> [dev] Running scripts/installation/main.sh...\" + bash scripts/installation/main.sh + + echo \">>> [dev] Activating venv...\" + . \"\$HOME/.venvs/pkgmgr/bin/activate\" + + echo \">>> [dev] Installing pkgmgr into venv via pip...\" + python -m pip install /src >/dev/null + + echo \">>> [dev] PKGMGR_DISABLE_NIX_FLAKE_INSTALLER=\$PKGMGR_DISABLE_NIX_FLAKE_INSTALLER\" + echo \">>> [dev] Updating managed repo package-manager via pkgmgr...\" + pkgmgr update pkgmgr --clone-mode shallow --no-verification + + echo \">>> [dev] PATH:\" + echo \"\$PATH\" + + echo \">>> [dev] which pkgmgr:\" + which pkgmgr || echo \">>> [dev] pkgmgr not found in PATH\" + + echo \">>> [dev] Running: pkgmgr version pkgmgr\" + pkgmgr version pkgmgr + " + + echo ">>> [root] Container flow finished." + ' diff --git a/.gitignore b/.gitignore index ac557f6..e8055ba 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,7 @@ dist/ build/* *.egg-info/ pkg - +src/source package-manager-* # debian diff --git a/README.md b/README.md index 4c97e02..e863cc4 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,15 @@ - **Custom Aliases:** Generate and manage custom aliases for easy command invocation. +## Architecture & Setup Map 🗺️ + +The following diagram provides a full overview of PKGMGR’s package structure, +installation layers, and setup controller flow: + +![PKGMGR Architecture](assets/map.png) + +**Diagram status:** *Stand: 10. Dezember 2025* +**Always-up-to-date version:** https://s.veen.world/pkgmgrmp ## Installation ⚙️ @@ -51,55 +60,6 @@ The `make setup` command will: - Install required packages from `requirements.txt`. - Execute `python main.py install` to complete the installation. -## Docker Quickstart 🐳 - -Alternatively to installing locally, you can use Docker: build the image with - -```bash -docker build --no-cache -t pkgmgr . -``` - -or alternativ pull it via - -```bash -docker pull kevinveenbirkenbach/pkgmgr:latest -``` - -and then run - -```bash -docker run --rm pkgmgr --help -``` - -## Usage 📖 - -Run the script with different commands. For example: - -- **Install all packages:** - ```bash - pkgmgr install --all - ``` -- **Pull updates for a specific repository:** - ```bash - pkgmgr pull pkgmgr - ``` -- **Commit changes with extra Git parameters:** - ```bash - pkgmgr commit pkgmgr -- -m "Your commit message" - ``` -- **List all configured packages:** - ```bash - pkgmgr config show - ``` -- **Manage configuration:** - ```bash - pkgmgr config init - pkgmgr config add - pkgmgr config edit - pkgmgr config delete - pkgmgr config ignore --set true - ``` - ## License 📄 This project is licensed under the MIT License. @@ -108,9 +68,3 @@ This project is licensed under the MIT License. Kevin Veen-Birkenbach [https://www.veen.world](https://www.veen.world) - ---- - -**Repository:** [github.com/kevinveenbirkenbach/package-manager](https://github.com/kevinveenbirkenbach/package-manager) - -*Created with AI 🤖 - [View conversation](https://chatgpt.com/share/67c728c4-92d0-800f-8945-003fa9bf27c6)* diff --git a/assets/map.png b/assets/map.png new file mode 100644 index 0000000..f0fe773 Binary files /dev/null and b/assets/map.png differ diff --git a/scripts/installation/main.sh b/scripts/installation/main.sh index 0a9e469..c8559de 100755 --- a/scripts/installation/main.sh +++ b/scripts/installation/main.sh @@ -4,20 +4,22 @@ set -euo pipefail # ------------------------------------------------------------ # main.sh # -# Developer setup entrypoint. +# Developer / system setup entrypoint. # # Responsibilities: # - If inside a Nix shell (IN_NIX_SHELL=1): # * Skip venv creation and dependency installation # * Run `python3 main.py install` -# - Otherwise: +# - If running as root (EUID=0): +# * Run system-level installer (run-package.sh) +# - Otherwise (normal user): # * Create ~/.venvs/pkgmgr virtual environment if missing # * Install Python dependencies into that venv # * Append auto-activation to ~/.bashrc and ~/.zshrc # * Run `main.py install` using the venv Python # ------------------------------------------------------------ -echo "[installation/main] Starting developer setup..." +echo "[installation/main] Starting setup..." PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" cd "${PROJECT_ROOT}" @@ -26,20 +28,34 @@ VENV_DIR="${HOME}/.venvs/pkgmgr" RC_LINE='if [ -d "${HOME}/.venvs/pkgmgr" ]; then . "${HOME}/.venvs/pkgmgr/bin/activate"; if [ -n "${PS1:-}" ]; then echo "Global Python virtual environment '\''~/.venvs/pkgmgr'\'' activated."; fi; fi' # ------------------------------------------------------------ -# Nix shell mode: do not touch venv, only run main.py install +# 1) Nix shell mode: do not touch venv, only run main.py install # ------------------------------------------------------------ if [[ -n "${IN_NIX_SHELL:-}" ]]; then echo "[installation/main] Nix shell detected (IN_NIX_SHELL=1)." echo "[installation/main] Skipping virtualenv creation and dependency installation." echo "[installation/main] Running main.py install via system python3..." python3 main.py install - echo "[installation/main] Developer setup finished (Nix mode)." + echo "[installation/main] Setup finished (Nix mode)." exit 0 fi # ------------------------------------------------------------ -# Normal host mode: create/update venv and run main.py install +# 2) Root mode: system / distro-level installation # ------------------------------------------------------------ +if [[ "${EUID:-$(id -u)}" -eq 0 ]]; then + echo "[installation/main] Running as root (EUID=0)." + echo "[installation/main] Skipping user virtualenv and shell RC modifications." + echo "[installation/main] Delegating to scripts/installation/run-package.sh..." + bash scripts/installation/run-package.sh + echo "[installation/main] Root/system setup complete." + exit 0 +fi + +# ------------------------------------------------------------ +# 3) Normal user mode: dev setup with venv +# ------------------------------------------------------------ + +echo "[installation/main] Running in normal user mode (developer setup)." echo "[installation/main] Ensuring main.py is executable..." chmod +x main.py || true @@ -47,26 +63,8 @@ chmod +x main.py || true echo "[installation/main] Ensuring global virtualenv root: ${HOME}/.venvs" mkdir -p "${HOME}/.venvs" -if [[ ! -d "${VENV_DIR}" ]]; then - echo "[installation/main] Creating virtual environment at: ${VENV_DIR}" - python3 -m venv "${VENV_DIR}" -else - echo "[installation/main] Virtual environment already exists at: ${VENV_DIR}" -fi - -echo "[installation/main] Installing Python tooling into venv..." -"${VENV_DIR}/bin/python" -m ensurepip --upgrade -"${VENV_DIR}/bin/pip" install --upgrade pip setuptools wheel - -if [[ -f "requirements.txt" ]]; then - echo "[installation/main] Installing dependencies from requirements.txt..." - "${VENV_DIR}/bin/pip" install -r requirements.txt -elif [[ -f "_requirements.txt" ]]; then - echo "[installation/main] Installing dependencies from _requirements.txt..." - "${VENV_DIR}/bin/pip" install -r _requirements.txt -else - echo "[installation/main] No requirements.txt or _requirements.txt found. Skipping dependency installation." -fi +echo "[installation/main] Creating/updating virtualenv via helper..." +PKGMGR_VENV_DIR="${VENV_DIR}" bash scripts/installation/venv-create.sh echo "[installation/main] Ensuring ~/.bashrc and ~/.zshrc exist..." touch "${HOME}/.bashrc" "${HOME}/.zshrc" diff --git a/scripts/installation/venv-create.sh b/scripts/installation/venv-create.sh new file mode 100644 index 0000000..8d341b8 --- /dev/null +++ b/scripts/installation/venv-create.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +set -euo pipefail + +# venv-create.sh +# +# Small helper to create/update a Python virtual environment for pkgmgr. +# +# Usage: +# PKGMGR_VENV_DIR=/home/dev/.venvs/pkgmgr bash scripts/installation/venv-create.sh +# or +# bash scripts/installation/venv-create.sh /home/dev/.venvs/pkgmgr + +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +cd "${PROJECT_ROOT}" + +VENV_DIR="${PKGMGR_VENV_DIR:-${1:-${HOME}/.venvs/pkgmgr}}" + +echo "[venv-create] Using VENV_DIR=${VENV_DIR}" + +echo "[venv-create] Ensuring virtualenv parent directory exists..." +mkdir -p "$(dirname "${VENV_DIR}")" + +if [[ ! -d "${VENV_DIR}" ]]; then + echo "[venv-create] Creating virtual environment at: ${VENV_DIR}" + python3 -m venv "${VENV_DIR}" +else + echo "[venv-create] Virtual environment already exists at: ${VENV_DIR}" +fi + +echo "[venv-create] Installing Python tooling into venv..." +"${VENV_DIR}/bin/python" -m ensurepip --upgrade +"${VENV_DIR}/bin/pip" install --upgrade pip setuptools wheel + +if [[ -f "requirements.txt" ]]; then + echo "[venv-create] Installing dependencies from requirements.txt..." + "${VENV_DIR}/bin/pip" install -r requirements.txt +elif [[ -f "_requirements.txt" ]]; then + echo "[venv-create] Installing dependencies from _requirements.txt..." + "${VENV_DIR}/bin/pip" install -r _requirements.txt +else + echo "[venv-create] No requirements.txt or _requirements.txt found. Skipping dependency installation." +fi + +echo "[venv-create] Done."