Compare commits
25 Commits
v0.9.0
...
eeda944b73
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eeda944b73 | ||
|
|
52cfbebba4 | ||
|
|
f4385807f1 | ||
|
|
e9e083c9dd | ||
|
|
3218b2b39f | ||
|
|
ba296a79c9 | ||
|
|
62e05e2f5b | ||
|
|
77d8b68ba5 | ||
|
|
bb0a801396 | ||
|
|
ee968efc4b | ||
|
|
644b2b8fa0 | ||
|
|
0f74907f82 | ||
|
|
5a8b1b11de | ||
|
|
389ec40163 | ||
|
|
1d03055491 | ||
|
|
7775c6d974 | ||
|
|
a24a819511 | ||
|
|
0a6c2f2988 | ||
|
|
0c90e984ad | ||
|
|
0a0cbbfe6d | ||
|
|
15c44cd484 | ||
|
|
6d7ee6fc04 | ||
|
|
5a022db0db | ||
|
|
37ac22e0b4 | ||
|
|
bcea440e40 |
@@ -25,7 +25,5 @@ venv/
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|
||||||
# Arch pkg artifacts
|
# Logs
|
||||||
*.pkg.tar.*
|
|
||||||
*.log
|
*.log
|
||||||
package-manager-*
|
|
||||||
26
.github/workflows/ci.yml
vendored
Normal file
26
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test-unit:
|
||||||
|
uses: ./.github/workflows/test-unit.yml
|
||||||
|
|
||||||
|
test-integration:
|
||||||
|
uses: ./.github/workflows/test-integration.yml
|
||||||
|
|
||||||
|
test-container:
|
||||||
|
uses: ./.github/workflows/test-container.yml
|
||||||
|
|
||||||
|
test-e2e:
|
||||||
|
uses: ./.github/workflows/test-e2e.yml
|
||||||
|
|
||||||
|
test-virgin-user:
|
||||||
|
uses: ./.github/workflows/test-virgin-user.yml
|
||||||
|
|
||||||
|
test-virgin-root:
|
||||||
|
uses: ./.github/workflows/test-virgin-root.yml
|
||||||
64
.github/workflows/mark-stable.yml
vendored
Normal file
64
.github/workflows/mark-stable.yml
vendored
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
name: Mark stable commit
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test-unit:
|
||||||
|
uses: ./.github/workflows/test-unit.yml
|
||||||
|
|
||||||
|
test-integration:
|
||||||
|
uses: ./.github/workflows/test-integration.yml
|
||||||
|
|
||||||
|
test-container:
|
||||||
|
uses: ./.github/workflows/test-container.yml
|
||||||
|
|
||||||
|
test-e2e:
|
||||||
|
uses: ./.github/workflows/test-e2e.yml
|
||||||
|
|
||||||
|
test-virgin-user:
|
||||||
|
uses: ./.github/workflows/test-virgin-user.yml
|
||||||
|
|
||||||
|
test-virgin-root:
|
||||||
|
uses: ./.github/workflows/test-virgin-root.yml
|
||||||
|
|
||||||
|
mark-stable:
|
||||||
|
needs:
|
||||||
|
- test-unit
|
||||||
|
- test-integration
|
||||||
|
- test-container
|
||||||
|
- test-e2e
|
||||||
|
- test-virgin-user
|
||||||
|
- test-virgin-root
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write # to move the tag
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Move 'stable' tag to this commit
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
|
echo "Tagging commit $GITHUB_SHA as stable…"
|
||||||
|
|
||||||
|
# delete local tag if exists
|
||||||
|
git tag -d stable 2>/dev/null || true
|
||||||
|
# delete remote tag if exists
|
||||||
|
git push origin :refs/tags/stable || true
|
||||||
|
|
||||||
|
# create new tag on this commit
|
||||||
|
git tag stable "$GITHUB_SHA"
|
||||||
|
git push origin stable
|
||||||
|
|
||||||
|
echo "✅ Stable tag updated."
|
||||||
8
.github/workflows/test-container.yml
vendored
8
.github/workflows/test-container.yml
vendored
@@ -1,13 +1,7 @@
|
|||||||
name: Test OS Containers
|
name: Test OS Containers
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
workflow_call:
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
- "*"
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-container:
|
test-container:
|
||||||
|
|||||||
8
.github/workflows/test-e2e.yml
vendored
8
.github/workflows/test-e2e.yml
vendored
@@ -1,13 +1,7 @@
|
|||||||
name: Test End-To-End
|
name: Test End-To-End
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
workflow_call:
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
- "*"
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-e2e:
|
test-e2e:
|
||||||
|
|||||||
8
.github/workflows/test-integration.yml
vendored
8
.github/workflows/test-integration.yml
vendored
@@ -1,13 +1,7 @@
|
|||||||
name: Test Code Integration
|
name: Test Code Integration
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
workflow_call:
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
- "*"
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-integration:
|
test-integration:
|
||||||
|
|||||||
8
.github/workflows/test-unit.yml
vendored
8
.github/workflows/test-unit.yml
vendored
@@ -1,13 +1,7 @@
|
|||||||
name: Test Units
|
name: Test Units
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
workflow_call:
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
- "*"
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-unit:
|
test-unit:
|
||||||
|
|||||||
@@ -1,16 +1,10 @@
|
|||||||
name: Test Virgin
|
name: Test Virgin Root
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
workflow_call:
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
- "*"
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-virgin:
|
test-virgin-root:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 45
|
timeout-minutes: 45
|
||||||
|
|
||||||
@@ -21,16 +15,14 @@ jobs:
|
|||||||
- name: Show Docker version
|
- name: Show Docker version
|
||||||
run: docker version
|
run: docker version
|
||||||
|
|
||||||
- name: Virgin Arch pkgmgr flake test
|
- name: Virgin Arch pkgmgr flake test (root)
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
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 \
|
docker run --rm \
|
||||||
-v "$PWD":/src \
|
-v "$PWD":/src \
|
||||||
-v pkgmgr_nix_store:/nix \
|
|
||||||
-v pkgmgr_nix_cache:/root/.cache/nix \
|
|
||||||
-v pkgmgr_repos:/root/Repositories \
|
-v pkgmgr_repos:/root/Repositories \
|
||||||
-v pkgmgr_pip_cache:/root/.cache/pip \
|
-v pkgmgr_pip_cache:/root/.cache/pip \
|
||||||
-w /src \
|
-w /src \
|
||||||
@@ -59,8 +51,8 @@ jobs:
|
|||||||
echo ">>> Running: pkgmgr update pkgmgr --clone-mode shallow --no-verification"
|
echo ">>> Running: pkgmgr update pkgmgr --clone-mode shallow --no-verification"
|
||||||
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
|
pkgmgr version pkgmgr
|
||||||
|
|
||||||
echo ">>> Virgin Arch test completed successfully."
|
echo ">>> Virgin Arch (root) test completed successfully."
|
||||||
'
|
'
|
||||||
73
.github/workflows/test-virgin-user.yml
vendored
Normal file
73
.github/workflows/test-virgin-user.yml
vendored
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
name: Test Virgin User
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
|
||||||
|
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."
|
||||||
|
'
|
||||||
12
.gitignore
vendored
12
.gitignore
vendored
@@ -14,17 +14,8 @@ venv/
|
|||||||
dist/
|
dist/
|
||||||
build/*
|
build/*
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
pkg
|
|
||||||
|
|
||||||
package-manager-*
|
package-manager-*
|
||||||
|
|
||||||
# debian
|
|
||||||
debian/package-manager/
|
|
||||||
debian/debhelper-build-stamp
|
|
||||||
debian/files
|
|
||||||
debian/.debhelper/
|
|
||||||
debian/package-manager.substvars
|
|
||||||
|
|
||||||
# Editor files
|
# Editor files
|
||||||
.vscode/
|
.vscode/
|
||||||
.idea/
|
.idea/
|
||||||
@@ -35,6 +26,9 @@ Thumbs.db
|
|||||||
|
|
||||||
# Nix Cache to speed up tests
|
# Nix Cache to speed up tests
|
||||||
.nix/
|
.nix/
|
||||||
|
.nix-dev-installed
|
||||||
|
|
||||||
# Ignore logs
|
# Ignore logs
|
||||||
*.log
|
*.log
|
||||||
|
|
||||||
|
result
|
||||||
@@ -1,3 +1,11 @@
|
|||||||
|
## [0.9.1] - 2025-12-10
|
||||||
|
|
||||||
|
* * Refactored installer: new `venv-create.sh`, cleaner root/user setup flow, updated README with architecture map.
|
||||||
|
* Split virgin tests into root/user workflows; stabilized Nix installer across distros; improved test scripts with dynamic distro selection and isolated Nix stores.
|
||||||
|
* Fixed repository directory resolution; improved `pkgmgr path` and `pkgmgr shell`; added full unit/E2E coverage.
|
||||||
|
* Removed deprecated files and updated `.gitignore`.
|
||||||
|
|
||||||
|
|
||||||
## [0.9.0] - 2025-12-10
|
## [0.9.0] - 2025-12-10
|
||||||
|
|
||||||
* Introduce a virgin Arch-based Nix flake E2E workflow that validates pkgmgr’s full flake installation path using shared caches for faster and reproducible CI runs.
|
* Introduce a virgin Arch-based Nix flake E2E workflow that validates pkgmgr’s full flake installation path using shared caches for faster and reproducible CI runs.
|
||||||
|
|||||||
6
Makefile
6
Makefile
@@ -2,12 +2,6 @@
|
|||||||
test build build-no-cache test-unit test-e2e test-integration \
|
test build build-no-cache test-unit test-e2e test-integration \
|
||||||
test-container
|
test-container
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# Local Nix cache directories in the repo
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
NIX_STORE_VOLUME := pkgmgr_nix_store
|
|
||||||
NIX_CACHE_VOLUME := pkgmgr_nix_cache
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
# Distro list and base images
|
# Distro list and base images
|
||||||
# (kept for documentation/reference; actual build logic is in scripts/build)
|
# (kept for documentation/reference; actual build logic is in scripts/build)
|
||||||
|
|||||||
64
README.md
64
README.md
@@ -24,6 +24,15 @@
|
|||||||
- **Custom Aliases:**
|
- **Custom Aliases:**
|
||||||
Generate and manage custom aliases for easy command invocation.
|
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:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
**Diagram status:** *Stand: 11. Dezember 2025*
|
||||||
|
**Always-up-to-date version:** https://s.veen.world/pkgmgrmp
|
||||||
|
|
||||||
## Installation ⚙️
|
## Installation ⚙️
|
||||||
|
|
||||||
@@ -51,55 +60,6 @@ The `make setup` command will:
|
|||||||
- Install required packages from `requirements.txt`.
|
- Install required packages from `requirements.txt`.
|
||||||
- Execute `python main.py install` to complete the installation.
|
- 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 <identifier>
|
|
||||||
pkgmgr config ignore <identifier> --set true
|
|
||||||
```
|
|
||||||
|
|
||||||
## License 📄
|
## License 📄
|
||||||
|
|
||||||
This project is licensed under the MIT License.
|
This project is licensed under the MIT License.
|
||||||
@@ -108,9 +68,3 @@ This project is licensed under the MIT License.
|
|||||||
|
|
||||||
Kevin Veen-Birkenbach
|
Kevin Veen-Birkenbach
|
||||||
[https://www.veen.world](https://www.veen.world)
|
[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)*
|
|
||||||
|
|||||||
7
TODO.md
Normal file
7
TODO.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# to-dos
|
||||||
|
|
||||||
|
For the following checkout the implementation map:
|
||||||
|
|
||||||
|
- Implement TAGS
|
||||||
|
- Implement MIRROR
|
||||||
|
- Implement SIGNING_KEY
|
||||||
BIN
assets/map.png
Normal file
BIN
assets/map.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 MiB |
27
flake.lock
generated
Normal file
27
flake.lock
generated
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1765186076,
|
||||||
|
"narHash": "sha256-hM20uyap1a0M9d344I692r+ik4gTMyj60cQWO+hAYP8=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "addf7cf5f383a3101ecfba091b98d0a1263dc9b8",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
35
flake.nix
35
flake.nix
@@ -26,12 +26,17 @@
|
|||||||
packages = forAllSystems (system:
|
packages = forAllSystems (system:
|
||||||
let
|
let
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
|
||||||
|
# Single source of truth for pkgmgr: Python 3.11
|
||||||
|
# - Matches pyproject.toml: requires-python = ">=3.11"
|
||||||
|
# - Uses python311Packages so that PyYAML etc. are available
|
||||||
|
python = pkgs.python311;
|
||||||
pyPkgs = pkgs.python311Packages;
|
pyPkgs = pkgs.python311Packages;
|
||||||
in
|
in
|
||||||
rec {
|
rec {
|
||||||
pkgmgr = pyPkgs.buildPythonApplication {
|
pkgmgr = pyPkgs.buildPythonApplication {
|
||||||
pname = "package-manager";
|
pname = "package-manager";
|
||||||
version = "0.9.0";
|
version = "0.9.1";
|
||||||
|
|
||||||
# Use the git repo as source
|
# Use the git repo as source
|
||||||
src = ./.;
|
src = ./.;
|
||||||
@@ -45,7 +50,7 @@
|
|||||||
pyPkgs.wheel
|
pyPkgs.wheel
|
||||||
];
|
];
|
||||||
|
|
||||||
# Runtime dependencies (matches [project.dependencies])
|
# Runtime dependencies (matches [project.dependencies] in pyproject.toml)
|
||||||
propagatedBuildInputs = [
|
propagatedBuildInputs = [
|
||||||
pyPkgs.pyyaml
|
pyPkgs.pyyaml
|
||||||
pyPkgs.pip
|
pyPkgs.pip
|
||||||
@@ -55,6 +60,7 @@
|
|||||||
|
|
||||||
pythonImportsCheck = [ "pkgmgr" ];
|
pythonImportsCheck = [ "pkgmgr" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
default = pkgmgr;
|
default = pkgmgr;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -65,29 +71,42 @@
|
|||||||
devShells = forAllSystems (system:
|
devShells = forAllSystems (system:
|
||||||
let
|
let
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
pkgmgrPkg = self.packages.${system}.pkgmgr;
|
|
||||||
|
|
||||||
ansiblePkg =
|
ansiblePkg =
|
||||||
if pkgs ? ansible-core then pkgs.ansible-core
|
if pkgs ? ansible-core then pkgs.ansible-core
|
||||||
else pkgs.ansible;
|
else pkgs.ansible;
|
||||||
|
|
||||||
# Python 3 + pip für alles, was "python3 -m pip" macht
|
# Use the same Python version as the package (3.11)
|
||||||
pythonWithPip = pkgs.python3.withPackages (ps: [
|
python = pkgs.python311;
|
||||||
|
|
||||||
|
pythonWithDeps = python.withPackages (ps: [
|
||||||
ps.pip
|
ps.pip
|
||||||
|
ps.pyyaml
|
||||||
]);
|
]);
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
default = pkgs.mkShell {
|
default = pkgs.mkShell {
|
||||||
buildInputs = [
|
buildInputs = [
|
||||||
pythonWithPip
|
pythonWithDeps
|
||||||
pkgmgrPkg
|
|
||||||
pkgs.git
|
pkgs.git
|
||||||
ansiblePkg
|
ansiblePkg
|
||||||
];
|
];
|
||||||
|
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
|
# Ensure our Python with dependencies is preferred on PATH
|
||||||
|
export PATH=${pythonWithDeps}/bin:$PATH
|
||||||
|
|
||||||
|
# Ensure src/ layout is importable:
|
||||||
|
# pkgmgr lives in ./src/pkgmgr
|
||||||
|
export PYTHONPATH="$PWD/src:${PYTHONPATH:-}"
|
||||||
|
# Also add repo root in case tools/tests rely on it
|
||||||
|
export PYTHONPATH="$PWD:$PYTHONPATH"
|
||||||
|
|
||||||
echo "Entered pkgmgr development shell for ${system}"
|
echo "Entered pkgmgr development shell for ${system}"
|
||||||
echo "pkgmgr CLI is available via the flake build"
|
echo "Python used in this shell:"
|
||||||
|
python --version
|
||||||
|
echo "pkgmgr CLI (from source) is available via:"
|
||||||
|
echo " python -m pkgmgr.cli --help"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
8
main.py
8
main.py
@@ -1,4 +1,12 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Ensure local src/ overrides installed package
|
||||||
|
ROOT = Path(__file__).resolve().parent
|
||||||
|
SRC = ROOT / "src"
|
||||||
|
if SRC.is_dir():
|
||||||
|
sys.path.insert(0, str(SRC))
|
||||||
|
|
||||||
from pkgmgr.cli import main
|
from pkgmgr.cli import main
|
||||||
|
|
||||||
|
|||||||
6
packaging/arch/.gitignore
vendored
Normal file
6
packaging/arch/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Arch pkg artifacts
|
||||||
|
*.pkg.tar.*
|
||||||
|
*.log
|
||||||
|
package-manager-*
|
||||||
|
src/
|
||||||
|
pkg/
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
# Maintainer: Kevin Veen-Birkenbach <info@veen.world>
|
# Maintainer: Kevin Veen-Birkenbach <info@veen.world>
|
||||||
|
|
||||||
pkgname=package-manager
|
pkgname=package-manager
|
||||||
pkgver=0.9.0
|
pkgver=0.9.1
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Local-flake wrapper for Kevin's package-manager (Nix-based)."
|
pkgdesc="Local-flake wrapper for Kevin's package-manager (Nix-based)."
|
||||||
arch=('any')
|
arch=('any')
|
||||||
@@ -15,7 +15,7 @@ makedepends=('rsync')
|
|||||||
install=${pkgname}.install
|
install=${pkgname}.install
|
||||||
|
|
||||||
# Local source checkout — avoids the tarball requirement.
|
# Local source checkout — avoids the tarball requirement.
|
||||||
# This assumes you build the package from inside the main project repository.
|
# We build from the project root (two levels above packaging/arch/).
|
||||||
source=()
|
source=()
|
||||||
sha256sums=()
|
sha256sums=()
|
||||||
|
|
||||||
@@ -24,12 +24,18 @@ _srcdir_name="source"
|
|||||||
|
|
||||||
prepare() {
|
prepare() {
|
||||||
mkdir -p "$srcdir/$_srcdir_name"
|
mkdir -p "$srcdir/$_srcdir_name"
|
||||||
|
|
||||||
|
local project_root
|
||||||
|
project_root="$(cd "$startdir/../.." && pwd)"
|
||||||
|
|
||||||
rsync -a \
|
rsync -a \
|
||||||
--exclude=".git" \
|
--exclude=".git" \
|
||||||
--exclude=".github" \
|
--exclude=".github" \
|
||||||
--exclude="pkg" \
|
--exclude="pkg" \
|
||||||
--exclude="srcpkg" \
|
--exclude="srcpkg" \
|
||||||
"$startdir/" "$srcdir/$_srcdir_name/"
|
--exclude="packaging" \
|
||||||
|
--exclude="assets" \
|
||||||
|
"$project_root/" "$srcdir/$_srcdir_name/"
|
||||||
}
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
@@ -62,7 +68,8 @@ package() {
|
|||||||
"$pkgdir/usr/lib/package-manager/PKGBUILD" \
|
"$pkgdir/usr/lib/package-manager/PKGBUILD" \
|
||||||
"$pkgdir/usr/lib/package-manager/Dockerfile" \
|
"$pkgdir/usr/lib/package-manager/Dockerfile" \
|
||||||
"$pkgdir/usr/lib/package-manager/debian" \
|
"$pkgdir/usr/lib/package-manager/debian" \
|
||||||
|
"$pkgdir/usr/lib/package-manager/packaging" \
|
||||||
"$pkgdir/usr/lib/package-manager/.gitignore" \
|
"$pkgdir/usr/lib/package-manager/.gitignore" \
|
||||||
"$pkgdir/usr/lib/package-manager/__pycache__" \
|
"$pkgdir/usr/lib/package-manager/__pycache__" \
|
||||||
"$pkgdir/usr/lib/package-manager/.gitkeep"
|
"$pkgdir/usr/lib/package-manager/.gitkeep" || true
|
||||||
}
|
}
|
||||||
6
packaging/debian/.gitignore
vendored
Normal file
6
packaging/debian/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# debian
|
||||||
|
package-manager/
|
||||||
|
debhelper-build-stamp
|
||||||
|
files
|
||||||
|
.debhelper/
|
||||||
|
package-manager.substvars
|
||||||
@@ -1,3 +1,12 @@
|
|||||||
|
package-manager (0.9.1-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* * Refactored installer: new `venv-create.sh`, cleaner root/user setup flow, updated README with architecture map.
|
||||||
|
* Split virgin tests into root/user workflows; stabilized Nix installer across distros; improved test scripts with dynamic distro selection and isolated Nix stores.
|
||||||
|
* Fixed repository directory resolution; improved `pkgmgr path` and `pkgmgr shell`; added full unit/E2E coverage.
|
||||||
|
* Removed deprecated files and updated `.gitignore`.
|
||||||
|
|
||||||
|
-- Kevin Veen-Birkenbach <kevin@veen.world> Wed, 10 Dec 2025 22:56:01 +0100
|
||||||
|
|
||||||
package-manager (0.9.0-1) unstable; urgency=medium
|
package-manager (0.9.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
* Introduce a virgin Arch-based Nix flake E2E workflow that validates pkgmgr’s full flake installation path using shared caches for faster and reproducible CI runs.
|
* Introduce a virgin Arch-based Nix flake E2E workflow that validates pkgmgr’s full flake installation path using shared caches for faster and reproducible CI runs.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
Name: package-manager
|
Name: package-manager
|
||||||
Version: 0.9.0
|
Version: 0.9.1
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: Wrapper that runs Kevin's package-manager via Nix flake
|
Summary: Wrapper that runs Kevin's package-manager via Nix flake
|
||||||
|
|
||||||
@@ -77,6 +77,12 @@ echo ">>> package-manager removed. Nix itself was not removed."
|
|||||||
/usr/lib/package-manager/
|
/usr/lib/package-manager/
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Dec 10 2025 Kevin Veen-Birkenbach <kevin@veen.world> - 0.9.1-1
|
||||||
|
- * Refactored installer: new `venv-create.sh`, cleaner root/user setup flow, updated README with architecture map.
|
||||||
|
* Split virgin tests into root/user workflows; stabilized Nix installer across distros; improved test scripts with dynamic distro selection and isolated Nix stores.
|
||||||
|
* Fixed repository directory resolution; improved `pkgmgr path` and `pkgmgr shell`; added full unit/E2E coverage.
|
||||||
|
* Removed deprecated files and updated `.gitignore`.
|
||||||
|
|
||||||
* Wed Dec 10 2025 Kevin Veen-Birkenbach <kevin@veen.world> - 0.9.0-1
|
* Wed Dec 10 2025 Kevin Veen-Birkenbach <kevin@veen.world> - 0.9.0-1
|
||||||
- Introduce a virgin Arch-based Nix flake E2E workflow that validates pkgmgr’s full flake installation path using shared caches for faster and reproducible CI runs.
|
- Introduce a virgin Arch-based Nix flake E2E workflow that validates pkgmgr’s full flake installation path using shared caches for faster and reproducible CI runs.
|
||||||
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
version: 1
|
|
||||||
|
|
||||||
author: "Kevin Veen-Birkenbach"
|
|
||||||
url: "https://github.com/kevinveenbirkenbach/package-manager"
|
|
||||||
description: "A configurable Python-based package manager for managing multiple repositories via Bash."
|
|
||||||
|
|
||||||
dependencies: []
|
|
||||||
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "package-manager"
|
name = "package-manager"
|
||||||
version = "0.9.0"
|
version = "0.9.1"
|
||||||
description = "Kevin's package-manager tool (pkgmgr)"
|
description = "Kevin's package-manager tool (pkgmgr)"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
@@ -39,13 +39,13 @@ pkgmgr = "pkgmgr.cli:main"
|
|||||||
# -----------------------------
|
# -----------------------------
|
||||||
# setuptools configuration
|
# setuptools configuration
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# We use find_packages(), not a fixed list,
|
# Source layout: all packages live under "src/"
|
||||||
# and explicitly include pkgmgr* and config*
|
[tool.setuptools]
|
||||||
|
package-dir = { "" = "src", "config" = "config" }
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
[tool.setuptools.packages.find]
|
||||||
where = ["."]
|
where = ["src", "."]
|
||||||
include = ["pkgmgr*", "config*"]
|
include = ["pkgmgr*", "config*"]
|
||||||
|
|
||||||
# Ensure defaults.yaml is shipped inside wheels & nix builds
|
|
||||||
[tool.setuptools.package-data]
|
[tool.setuptools.package-data]
|
||||||
"config" = ["defaults.yaml"]
|
"config" = ["defaults.yaml"]
|
||||||
|
|||||||
@@ -94,7 +94,15 @@ if [[ "${IN_CONTAINER}" -eq 1 && "${EUID:-0}" -eq 0 ]]; then
|
|||||||
# Ensure "nix" user (home at /home/nix)
|
# Ensure "nix" user (home at /home/nix)
|
||||||
if ! id nix >/dev/null 2>&1; then
|
if ! id nix >/dev/null 2>&1; then
|
||||||
echo "[init-nix] Creating user 'nix'..."
|
echo "[init-nix] Creating user 'nix'..."
|
||||||
useradd -m -r -g nixbld -s /usr/bin/bash nix
|
# Resolve a valid shell path across distros:
|
||||||
|
# - Debian/Ubuntu: /bin/bash
|
||||||
|
# - Arch: /usr/bin/bash (often symlinked)
|
||||||
|
# Fall back to /bin/sh on ultra-minimal systems.
|
||||||
|
BASH_SHELL="$(command -v bash || true)"
|
||||||
|
if [[ -z "${BASH_SHELL}" ]]; then
|
||||||
|
BASH_SHELL="/bin/sh"
|
||||||
|
fi
|
||||||
|
useradd -m -r -g nixbld -s "${BASH_SHELL}" nix
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ensure /nix exists and is writable by the "nix" user.
|
# Ensure /nix exists and is writable by the "nix" user.
|
||||||
|
|||||||
@@ -3,10 +3,21 @@ set -euo pipefail
|
|||||||
|
|
||||||
echo "[arch/package] Building Arch package (makepkg --nodeps)..."
|
echo "[arch/package] Building Arch package (makepkg --nodeps)..."
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
|
||||||
|
PKG_DIR="${PROJECT_ROOT}/packaging/arch"
|
||||||
|
|
||||||
|
if [[ ! -f "${PKG_DIR}/PKGBUILD" ]]; then
|
||||||
|
echo "[arch/package] ERROR: PKGBUILD not found in ${PKG_DIR}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "${PKG_DIR}"
|
||||||
|
|
||||||
if id aur_builder >/dev/null 2>&1; then
|
if id aur_builder >/dev/null 2>&1; then
|
||||||
echo "[arch/package] Using 'aur_builder' user for makepkg..."
|
echo "[arch/package] Using 'aur_builder' user for makepkg..."
|
||||||
chown -R aur_builder:aur_builder "$(pwd)"
|
chown -R aur_builder:aur_builder "${PKG_DIR}"
|
||||||
su aur_builder -c "cd '$(pwd)' && rm -f package-manager-*.pkg.tar.* && makepkg --noconfirm --clean --nodeps"
|
su aur_builder -c "cd '${PKG_DIR}' && rm -f package-manager-*.pkg.tar.* && makepkg --noconfirm --clean --nodeps"
|
||||||
else
|
else
|
||||||
echo "[arch/package] WARNING: user 'aur_builder' not found, running makepkg as current user..."
|
echo "[arch/package] WARNING: user 'aur_builder' not found, running makepkg as current user..."
|
||||||
rm -f package-manager-*.pkg.tar.*
|
rm -f package-manager-*.pkg.tar.*
|
||||||
|
|||||||
@@ -4,8 +4,17 @@ set -euo pipefail
|
|||||||
echo "[centos/package] Setting up rpmbuild directories..."
|
echo "[centos/package] Setting up rpmbuild directories..."
|
||||||
mkdir -p /root/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
|
mkdir -p /root/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
|
||||||
|
SPEC_PATH="${PROJECT_ROOT}/packaging/fedora/package-manager.spec"
|
||||||
|
|
||||||
|
if [[ ! -f "${SPEC_PATH}" ]]; then
|
||||||
|
echo "[centos/package] ERROR: SPEC file not found: ${SPEC_PATH}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo "[centos/package] Extracting version from package-manager.spec..."
|
echo "[centos/package] Extracting version from package-manager.spec..."
|
||||||
version="$(grep -E '^Version:' package-manager.spec | awk '{print $2}')"
|
version="$(grep -E '^Version:' "${SPEC_PATH}" | awk '{print $2}')"
|
||||||
if [[ -z "${version}" ]]; then
|
if [[ -z "${version}" ]]; then
|
||||||
echo "ERROR: Version missing!"
|
echo "ERROR: Version missing!"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -15,13 +24,13 @@ srcdir="package-manager-${version}"
|
|||||||
echo "[centos/package] Preparing source tree: ${srcdir}"
|
echo "[centos/package] Preparing source tree: ${srcdir}"
|
||||||
rm -rf "/tmp/${srcdir}"
|
rm -rf "/tmp/${srcdir}"
|
||||||
mkdir -p "/tmp/${srcdir}"
|
mkdir -p "/tmp/${srcdir}"
|
||||||
cp -a . "/tmp/${srcdir}/"
|
cp -a "${PROJECT_ROOT}/." "/tmp/${srcdir}/"
|
||||||
|
|
||||||
echo "[centos/package] Creating source tarball..."
|
echo "[centos/package] Creating source tarball..."
|
||||||
tar czf "/root/rpmbuild/SOURCES/${srcdir}.tar.gz" -C /tmp "${srcdir}"
|
tar czf "/root/rpmbuild/SOURCES/${srcdir}.tar.gz" -C /tmp "${srcdir}"
|
||||||
|
|
||||||
echo "[centos/package] Copying SPEC..."
|
echo "[centos/package] Copying SPEC..."
|
||||||
cp package-manager.spec /root/rpmbuild/SPECS/
|
cp "${SPEC_PATH}" /root/rpmbuild/SPECS/
|
||||||
|
|
||||||
echo "[centos/package] Running rpmbuild..."
|
echo "[centos/package] Running rpmbuild..."
|
||||||
cd /root/rpmbuild/SPECS
|
cd /root/rpmbuild/SPECS
|
||||||
|
|||||||
@@ -3,6 +3,25 @@ set -euo pipefail
|
|||||||
|
|
||||||
echo "[debian/package] Building Debian package..."
|
echo "[debian/package] Building Debian package..."
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
|
||||||
|
|
||||||
|
BUILD_ROOT="/tmp/package-manager-debian-build"
|
||||||
|
rm -rf "${BUILD_ROOT}"
|
||||||
|
mkdir -p "${BUILD_ROOT}"
|
||||||
|
|
||||||
|
echo "[debian/package] Syncing project sources to ${BUILD_ROOT}..."
|
||||||
|
rsync -a \
|
||||||
|
--exclude 'packaging/debian' \
|
||||||
|
"${PROJECT_ROOT}/" "${BUILD_ROOT}/"
|
||||||
|
|
||||||
|
echo "[debian/package] Overlaying debian/ metadata from packaging/debian..."
|
||||||
|
mkdir -p "${BUILD_ROOT}/debian"
|
||||||
|
cp -a "${PROJECT_ROOT}/packaging/debian/." "${BUILD_ROOT}/debian/"
|
||||||
|
|
||||||
|
cd "${BUILD_ROOT}"
|
||||||
|
|
||||||
|
echo "[debian/package] Running dpkg-buildpackage..."
|
||||||
dpkg-buildpackage -us -uc -b
|
dpkg-buildpackage -us -uc -b
|
||||||
|
|
||||||
echo "[debian/package] Installing generated DEB package..."
|
echo "[debian/package] Installing generated DEB package..."
|
||||||
|
|||||||
@@ -4,8 +4,17 @@ set -euo pipefail
|
|||||||
echo "[fedora/package] Setting up rpmbuild directories..."
|
echo "[fedora/package] Setting up rpmbuild directories..."
|
||||||
mkdir -p /root/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
|
mkdir -p /root/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
|
||||||
|
SPEC_PATH="${PROJECT_ROOT}/packaging/fedora/package-manager.spec"
|
||||||
|
|
||||||
|
if [[ ! -f "${SPEC_PATH}" ]]; then
|
||||||
|
echo "[fedora/package] ERROR: SPEC file not found: ${SPEC_PATH}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo "[fedora/package] Extracting version from package-manager.spec..."
|
echo "[fedora/package] Extracting version from package-manager.spec..."
|
||||||
version="$(grep -E '^Version:' package-manager.spec | awk '{print $2}')"
|
version="$(grep -E '^Version:' "${SPEC_PATH}" | awk '{print $2}')"
|
||||||
if [[ -z "${version}" ]]; then
|
if [[ -z "${version}" ]]; then
|
||||||
echo "ERROR: Version missing!"
|
echo "ERROR: Version missing!"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -15,13 +24,13 @@ srcdir="package-manager-${version}"
|
|||||||
echo "[fedora/package] Preparing source tree: ${srcdir}"
|
echo "[fedora/package] Preparing source tree: ${srcdir}"
|
||||||
rm -rf "/tmp/${srcdir}"
|
rm -rf "/tmp/${srcdir}"
|
||||||
mkdir -p "/tmp/${srcdir}"
|
mkdir -p "/tmp/${srcdir}"
|
||||||
cp -a . "/tmp/${srcdir}/"
|
cp -a "${PROJECT_ROOT}/." "/tmp/${srcdir}/"
|
||||||
|
|
||||||
echo "[fedora/package] Creating source tarball..."
|
echo "[fedora/package] Creating source tarball..."
|
||||||
tar czf "/root/rpmbuild/SOURCES/${srcdir}.tar.gz" -C /tmp "${srcdir}"
|
tar czf "/root/rpmbuild/SOURCES/${srcdir}.tar.gz" -C /tmp "${srcdir}"
|
||||||
|
|
||||||
echo "[fedora/package] Copying SPEC..."
|
echo "[fedora/package] Copying SPEC..."
|
||||||
cp package-manager.spec /root/rpmbuild/SPECS/
|
cp "${SPEC_PATH}" /root/rpmbuild/SPECS/
|
||||||
|
|
||||||
echo "[fedora/package] Running rpmbuild..."
|
echo "[fedora/package] Running rpmbuild..."
|
||||||
cd /root/rpmbuild/SPECS
|
cd /root/rpmbuild/SPECS
|
||||||
|
|||||||
@@ -4,20 +4,22 @@ set -euo pipefail
|
|||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
# main.sh
|
# main.sh
|
||||||
#
|
#
|
||||||
# Developer setup entrypoint.
|
# Developer / system setup entrypoint.
|
||||||
#
|
#
|
||||||
# Responsibilities:
|
# Responsibilities:
|
||||||
# - If inside a Nix shell (IN_NIX_SHELL=1):
|
# - If inside a Nix shell (IN_NIX_SHELL=1):
|
||||||
# * Skip venv creation and dependency installation
|
# * Skip venv creation and dependency installation
|
||||||
# * Run `python3 main.py install`
|
# * 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
|
# * Create ~/.venvs/pkgmgr virtual environment if missing
|
||||||
# * Install Python dependencies into that venv
|
# * Install Python dependencies into that venv
|
||||||
# * Append auto-activation to ~/.bashrc and ~/.zshrc
|
# * Append auto-activation to ~/.bashrc and ~/.zshrc
|
||||||
# * Run `main.py install` using the venv Python
|
# * 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)"
|
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||||
cd "${PROJECT_ROOT}"
|
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'
|
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
|
if [[ -n "${IN_NIX_SHELL:-}" ]]; then
|
||||||
echo "[installation/main] Nix shell detected (IN_NIX_SHELL=1)."
|
echo "[installation/main] Nix shell detected (IN_NIX_SHELL=1)."
|
||||||
echo "[installation/main] Skipping virtualenv creation and dependency installation."
|
echo "[installation/main] Skipping virtualenv creation and dependency installation."
|
||||||
echo "[installation/main] Running main.py install via system python3..."
|
echo "[installation/main] Running main.py install via system python3..."
|
||||||
python3 main.py install
|
python3 main.py install
|
||||||
echo "[installation/main] Developer setup finished (Nix mode)."
|
echo "[installation/main] Setup finished (Nix mode)."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
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..."
|
echo "[installation/main] Ensuring main.py is executable..."
|
||||||
chmod +x main.py || true
|
chmod +x main.py || true
|
||||||
@@ -47,26 +63,8 @@ chmod +x main.py || true
|
|||||||
echo "[installation/main] Ensuring global virtualenv root: ${HOME}/.venvs"
|
echo "[installation/main] Ensuring global virtualenv root: ${HOME}/.venvs"
|
||||||
mkdir -p "${HOME}/.venvs"
|
mkdir -p "${HOME}/.venvs"
|
||||||
|
|
||||||
if [[ ! -d "${VENV_DIR}" ]]; then
|
echo "[installation/main] Creating/updating virtualenv via helper..."
|
||||||
echo "[installation/main] Creating virtual environment at: ${VENV_DIR}"
|
PKGMGR_VENV_DIR="${VENV_DIR}" bash scripts/installation/venv-create.sh
|
||||||
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] Ensuring ~/.bashrc and ~/.zshrc exist..."
|
echo "[installation/main] Ensuring ~/.bashrc and ~/.zshrc exist..."
|
||||||
touch "${HOME}/.bashrc" "${HOME}/.zshrc"
|
touch "${HOME}/.bashrc" "${HOME}/.zshrc"
|
||||||
|
|||||||
@@ -3,6 +3,25 @@ set -euo pipefail
|
|||||||
|
|
||||||
echo "[ubuntu/package] Building Ubuntu (Debian-style) package..."
|
echo "[ubuntu/package] Building Ubuntu (Debian-style) package..."
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
|
||||||
|
|
||||||
|
BUILD_ROOT="/tmp/package-manager-ubuntu-build"
|
||||||
|
rm -rf "${BUILD_ROOT}"
|
||||||
|
mkdir -p "${BUILD_ROOT}"
|
||||||
|
|
||||||
|
echo "[ubuntu/package] Syncing project sources to ${BUILD_ROOT}..."
|
||||||
|
rsync -a \
|
||||||
|
--exclude 'packaging/debian' \
|
||||||
|
"${PROJECT_ROOT}/" "${BUILD_ROOT}/"
|
||||||
|
|
||||||
|
echo "[ubuntu/package] Overlaying debian/ metadata from packaging/debian..."
|
||||||
|
mkdir -p "${BUILD_ROOT}/debian"
|
||||||
|
cp -a "${PROJECT_ROOT}/packaging/debian/." "${BUILD_ROOT}/debian/"
|
||||||
|
|
||||||
|
cd "${BUILD_ROOT}"
|
||||||
|
|
||||||
|
echo "[ubuntu/package] Running dpkg-buildpackage..."
|
||||||
dpkg-buildpackage -us -uc -b
|
dpkg-buildpackage -us -uc -b
|
||||||
|
|
||||||
echo "[ubuntu/package] Installing generated DEB package..."
|
echo "[ubuntu/package] Installing generated DEB package..."
|
||||||
|
|||||||
44
scripts/installation/venv-create.sh
Normal file
44
scripts/installation/venv-create.sh
Normal file
@@ -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."
|
||||||
@@ -19,9 +19,9 @@ for distro in $DISTROS; do
|
|||||||
# Run the command and capture the output
|
# Run the command and capture the output
|
||||||
if OUTPUT=$(docker run --rm \
|
if OUTPUT=$(docker run --rm \
|
||||||
-e PKGMGR_DEV=1 \
|
-e PKGMGR_DEV=1 \
|
||||||
-v pkgmgr_nix_store:/nix \
|
-v pkgmgr_nix_store_${distro}:/nix \
|
||||||
-v "$(pwd):/src" \
|
-v "$(pwd):/src" \
|
||||||
-v "pkgmgr_nix_cache:/root/.cache/nix" \
|
-v "pkgmgr_nix_cache_${distro}:/root/.cache/nix" \
|
||||||
"$IMAGE" 2>&1); then
|
"$IMAGE" 2>&1); then
|
||||||
echo "$OUTPUT"
|
echo "$OUTPUT"
|
||||||
echo
|
echo
|
||||||
|
|||||||
@@ -10,43 +10,56 @@ for distro in $DISTROS; do
|
|||||||
|
|
||||||
docker run --rm \
|
docker run --rm \
|
||||||
-v "$(pwd):/src" \
|
-v "$(pwd):/src" \
|
||||||
-v pkgmgr_nix_store:/nix \
|
-v "pkgmgr_nix_store_${distro}:/nix" \
|
||||||
-v "pkgmgr_nix_cache:/root/.cache/nix" \
|
-v "pkgmgr_nix_cache_${distro}:/root/.cache/nix" \
|
||||||
-e PKGMGR_DEV=1 \
|
-e PKGMGR_DEV=1 \
|
||||||
-e TEST_PATTERN="${TEST_PATTERN}" \
|
-e TEST_PATTERN="${TEST_PATTERN}" \
|
||||||
--workdir /src \
|
--workdir /src \
|
||||||
--entrypoint bash \
|
--entrypoint bash \
|
||||||
"package-manager-test-$distro" \
|
"package-manager-test-${distro}" \
|
||||||
-c '
|
-c '
|
||||||
set -e;
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Load distro info
|
||||||
if [ -f /etc/os-release ]; then
|
if [ -f /etc/os-release ]; then
|
||||||
. /etc/os-release;
|
. /etc/os-release
|
||||||
fi;
|
fi
|
||||||
|
|
||||||
echo "Running tests inside distro: $ID";
|
echo "Running tests inside distro: ${ID:-unknown}"
|
||||||
|
|
||||||
# Try to load nix environment
|
# Load Nix environment if available
|
||||||
if [ -f "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh" ]; then
|
if [ -f "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh" ]; then
|
||||||
. "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh";
|
. "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f "$HOME/.nix-profile/etc/profile.d/nix.sh" ]; then
|
if [ -f "$HOME/.nix-profile/etc/profile.d/nix.sh" ]; then
|
||||||
. "$HOME/.nix-profile/etc/profile.d/nix.sh";
|
. "$HOME/.nix-profile/etc/profile.d/nix.sh"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PATH="/nix/var/nix/profiles/default/bin:$HOME/.nix-profile/bin:$PATH";
|
PATH="/nix/var/nix/profiles/default/bin:$HOME/.nix-profile/bin:$PATH"
|
||||||
|
|
||||||
command -v nix >/dev/null || {
|
command -v nix >/dev/null || {
|
||||||
echo "ERROR: nix not found.";
|
echo "ERROR: nix not found."
|
||||||
exit 1;
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
git config --global --add safe.directory /src || true;
|
# Mark the mounted repository as safe to avoid Git ownership errors.
|
||||||
|
# Newer Git (e.g. on Ubuntu) complains about the gitdir (/src/.git),
|
||||||
|
# older versions about the worktree (/src). Nix turns "." into the
|
||||||
|
# flake input "git+file:///src", which then uses Git under the hood.
|
||||||
|
if command -v git >/dev/null 2>&1; then
|
||||||
|
# Worktree path
|
||||||
|
git config --global --add safe.directory /src || true
|
||||||
|
# Gitdir path shown in the "dubious ownership" error
|
||||||
|
git config --global --add safe.directory /src/.git || true
|
||||||
|
# Ephemeral CI containers: allow all paths as a last resort
|
||||||
|
git config --global --add safe.directory '*' || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run the E2E tests inside the Nix development shell
|
||||||
nix develop .#default --no-write-lock-file -c \
|
nix develop .#default --no-write-lock-file -c \
|
||||||
python3 -m unittest discover \
|
python3 -m unittest discover \
|
||||||
-s /src/tests/e2e \
|
-s /src/tests/e2e \
|
||||||
-p "$TEST_PATTERN";
|
-p "$TEST_PATTERN"
|
||||||
'
|
'
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -1,24 +1,26 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
: "${distro:=arch}"
|
||||||
|
|
||||||
echo "============================================================"
|
echo "============================================================"
|
||||||
echo ">>> Running INTEGRATION tests in Arch container"
|
echo ">>> Running INTEGRATION tests in ${distro} container"
|
||||||
echo "============================================================"
|
echo "============================================================"
|
||||||
|
|
||||||
docker run --rm \
|
docker run --rm \
|
||||||
-v "$(pwd):/src" \
|
-v "$(pwd):/src" \
|
||||||
-v pkgmgr_nix_store:/nix \
|
-v pkgmgr_nix_store_${distro}:/nix \
|
||||||
-v "pkgmgr_nix_cache:/root/.cache/nix" \
|
-v "pkgmgr_nix_cache_${distro}:/root/.cache/nix" \
|
||||||
--workdir /src \
|
--workdir /src \
|
||||||
-e PKGMGR_DEV=1 \
|
-e PKGMGR_DEV=1 \
|
||||||
-e TEST_PATTERN="${TEST_PATTERN}" \
|
-e TEST_PATTERN="${TEST_PATTERN}" \
|
||||||
--entrypoint bash \
|
--entrypoint bash \
|
||||||
"package-manager-test-arch" \
|
"package-manager-test-${distro}" \
|
||||||
-c '
|
-c '
|
||||||
set -e;
|
set -e;
|
||||||
git config --global --add safe.directory /src || true;
|
git config --global --add safe.directory /src || true;
|
||||||
nix develop .#default --no-write-lock-file -c \
|
nix develop .#default --no-write-lock-file -c \
|
||||||
python -m unittest discover \
|
python3 -m unittest discover \
|
||||||
-s tests/integration \
|
-s tests/integration \
|
||||||
-t /src \
|
-t /src \
|
||||||
-p "$TEST_PATTERN";
|
-p "$TEST_PATTERN";
|
||||||
|
|||||||
@@ -1,24 +1,26 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
: "${distro:=arch}"
|
||||||
|
|
||||||
echo "============================================================"
|
echo "============================================================"
|
||||||
echo ">>> Running UNIT tests in Arch container"
|
echo ">>> Running UNIT tests in ${distro} container"
|
||||||
echo "============================================================"
|
echo "============================================================"
|
||||||
|
|
||||||
docker run --rm \
|
docker run --rm \
|
||||||
-v "$(pwd):/src" \
|
-v "$(pwd):/src" \
|
||||||
-v "pkgmgr_nix_cache:/root/.cache/nix" \
|
-v "pkgmgr_nix_cache_${distro}:/root/.cache/nix" \
|
||||||
-v pkgmgr_nix_store:/nix \
|
-v pkgmgr_nix_store_${distro}:/nix \
|
||||||
--workdir /src \
|
--workdir /src \
|
||||||
-e PKGMGR_DEV=1 \
|
-e PKGMGR_DEV=1 \
|
||||||
-e TEST_PATTERN="${TEST_PATTERN}" \
|
-e TEST_PATTERN="${TEST_PATTERN}" \
|
||||||
--entrypoint bash \
|
--entrypoint bash \
|
||||||
"package-manager-test-arch" \
|
"package-manager-test-${distro}" \
|
||||||
-c '
|
-c '
|
||||||
set -e;
|
set -e;
|
||||||
git config --global --add safe.directory /src || true;
|
git config --global --add safe.directory /src || true;
|
||||||
nix develop .#default --no-write-lock-file -c \
|
nix develop .#default --no-write-lock-file -c \
|
||||||
python -m unittest discover \
|
python3 -m unittest discover \
|
||||||
-s tests/unit \
|
-s tests/unit \
|
||||||
-t /src \
|
-t /src \
|
||||||
-p "$TEST_PATTERN";
|
-p "$TEST_PATTERN";
|
||||||
|
|||||||
36
src/pkgmgr/__init__.py
Normal file
36
src/pkgmgr/__init__.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Top-level pkgmgr package.
|
||||||
|
|
||||||
|
We deliberately avoid importing heavy submodules (like the CLI)
|
||||||
|
on import to keep unit tests fast and to not require optional
|
||||||
|
dependencies (like PyYAML) unless they are actually used.
|
||||||
|
|
||||||
|
Accessing ``pkgmgr.cli`` will load the CLI module lazily via
|
||||||
|
``__getattr__``. This keeps patterns like
|
||||||
|
|
||||||
|
from pkgmgr import cli
|
||||||
|
|
||||||
|
working as expected in tests and entry points.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from importlib import import_module
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
__all__ = ["cli"]
|
||||||
|
|
||||||
|
|
||||||
|
def __getattr__(name: str) -> Any:
|
||||||
|
"""
|
||||||
|
Lazily expose ``pkgmgr.cli`` as attribute on the top-level package.
|
||||||
|
|
||||||
|
This keeps ``import pkgmgr`` lightweight while still allowing
|
||||||
|
``from pkgmgr import cli`` in tests and entry points.
|
||||||
|
"""
|
||||||
|
if name == "cli":
|
||||||
|
return import_module("pkgmgr.cli")
|
||||||
|
raise AttributeError(f"module 'pkgmgr' has no attribute {name!r}")
|
||||||
@@ -34,7 +34,6 @@ dependency formats, including:
|
|||||||
• \033[1;33mNix:\033[0m flake.nix
|
• \033[1;33mNix:\033[0m flake.nix
|
||||||
• \033[1;33mArch Linux:\033[0m PKGBUILD
|
• \033[1;33mArch Linux:\033[0m PKGBUILD
|
||||||
• \033[1;33mAnsible:\033[0m requirements.yml
|
• \033[1;33mAnsible:\033[0m requirements.yml
|
||||||
• \033[1;33mpkgmgr-native:\033[0m pkgmgr.yml
|
|
||||||
|
|
||||||
This allows pkgmgr to perform installation, updates, verification, dependency
|
This allows pkgmgr to perform installation, updates, verification, dependency
|
||||||
resolution, and synchronization across complex multi-repo environments — with a
|
resolution, and synchronization across complex multi-repo environments — with a
|
||||||
@@ -16,10 +16,36 @@ from pkgmgr.actions.repository.list import list_repositories
|
|||||||
from pkgmgr.core.command.run import run_command
|
from pkgmgr.core.command.run import run_command
|
||||||
from pkgmgr.actions.repository.create import create_repo
|
from pkgmgr.actions.repository.create import create_repo
|
||||||
from pkgmgr.core.repository.selected import get_selected_repos
|
from pkgmgr.core.repository.selected import get_selected_repos
|
||||||
|
from pkgmgr.core.repository.dir import get_repo_dir
|
||||||
|
|
||||||
Repository = Dict[str, Any]
|
Repository = Dict[str, Any]
|
||||||
|
|
||||||
|
|
||||||
|
def _resolve_repository_directory(repository: Repository, ctx: CLIContext) -> str:
|
||||||
|
"""
|
||||||
|
Resolve the local filesystem directory for a repository.
|
||||||
|
|
||||||
|
Priority:
|
||||||
|
1. Use repository["directory"] if present.
|
||||||
|
2. Fallback to get_repo_dir(...) using the repositories base directory
|
||||||
|
from the CLI context.
|
||||||
|
"""
|
||||||
|
repo_dir = repository.get("directory")
|
||||||
|
if repo_dir:
|
||||||
|
return repo_dir
|
||||||
|
|
||||||
|
base_dir = (
|
||||||
|
getattr(ctx, "repositories_base_dir", None)
|
||||||
|
or getattr(ctx, "repositories_dir", None)
|
||||||
|
)
|
||||||
|
if not base_dir:
|
||||||
|
raise RuntimeError(
|
||||||
|
"Cannot resolve repositories base directory from context; "
|
||||||
|
"expected ctx.repositories_base_dir or ctx.repositories_dir."
|
||||||
|
)
|
||||||
|
return get_repo_dir(base_dir, repository)
|
||||||
|
|
||||||
|
|
||||||
def handle_repos_command(
|
def handle_repos_command(
|
||||||
args,
|
args,
|
||||||
ctx: CLIContext,
|
ctx: CLIContext,
|
||||||
@@ -108,8 +134,25 @@ def handle_repos_command(
|
|||||||
# path
|
# path
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
if args.command == "path":
|
if args.command == "path":
|
||||||
|
if not selected:
|
||||||
|
print("[pkgmgr] No repositories selected for path.")
|
||||||
|
return
|
||||||
|
|
||||||
for repository in selected:
|
for repository in selected:
|
||||||
print(repository["directory"])
|
try:
|
||||||
|
repo_dir = _resolve_repository_directory(repository, ctx)
|
||||||
|
except Exception as exc:
|
||||||
|
ident = (
|
||||||
|
f"{repository.get('provider', '?')}/"
|
||||||
|
f"{repository.get('account', '?')}/"
|
||||||
|
f"{repository.get('repository', '?')}"
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
f"[WARN] Could not resolve directory for {ident}: {exc}"
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
print(repo_dir)
|
||||||
return
|
return
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
@@ -119,14 +162,14 @@ def handle_repos_command(
|
|||||||
if not args.shell_command:
|
if not args.shell_command:
|
||||||
print("[ERROR] 'shell' requires a command via -c/--command.")
|
print("[ERROR] 'shell' requires a command via -c/--command.")
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
command_to_run = " ".join(args.shell_command)
|
command_to_run = " ".join(args.shell_command)
|
||||||
for repository in selected:
|
for repository in selected:
|
||||||
print(
|
repo_dir = _resolve_repository_directory(repository, ctx)
|
||||||
f"Executing in '{repository['directory']}': {command_to_run}"
|
print(f"Executing in '{repo_dir}': {command_to_run}")
|
||||||
)
|
|
||||||
run_command(
|
run_command(
|
||||||
command_to_run,
|
command_to_run,
|
||||||
cwd=repository["directory"],
|
cwd=repo_dir,
|
||||||
preview=args.preview,
|
preview=args.preview,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
@@ -197,13 +197,8 @@ def _load_layer_dir(
|
|||||||
|
|
||||||
def _load_defaults_from_package_or_project() -> Dict[str, Any]:
|
def _load_defaults_from_package_or_project() -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Fallback: Versuche Defaults aus dem installierten Paket ODER
|
Fallback: load default configs from various possible install or development
|
||||||
aus dem Projekt-Root zu laden:
|
layouts (pip-installed, editable install, source repo with src/ layout).
|
||||||
|
|
||||||
<pkg_root>/config_defaults
|
|
||||||
<pkg_root>/config
|
|
||||||
<project_root>/config_defaults
|
|
||||||
<project_root>/config
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
import pkgmgr # type: ignore
|
import pkgmgr # type: ignore
|
||||||
@@ -211,14 +206,25 @@ def _load_defaults_from_package_or_project() -> Dict[str, Any]:
|
|||||||
return {"directories": {}, "repositories": []}
|
return {"directories": {}, "repositories": []}
|
||||||
|
|
||||||
pkg_root = Path(pkgmgr.__file__).resolve().parent
|
pkg_root = Path(pkgmgr.__file__).resolve().parent
|
||||||
project_root = pkg_root.parent
|
roots = set()
|
||||||
|
|
||||||
candidates = [
|
# Case 1: installed package (site-packages/pkgmgr)
|
||||||
pkg_root / "config_defaults",
|
roots.add(pkg_root)
|
||||||
pkg_root / "config",
|
|
||||||
project_root / "config_defaults",
|
# Case 2: parent directory (site-packages/, src/)
|
||||||
project_root / "config",
|
roots.add(pkg_root.parent)
|
||||||
]
|
|
||||||
|
# Case 3: src-layout during development:
|
||||||
|
# repo_root/src/pkgmgr -> repo_root
|
||||||
|
parent = pkg_root.parent
|
||||||
|
if parent.name == "src":
|
||||||
|
roots.add(parent.parent)
|
||||||
|
|
||||||
|
# Candidate config dirs
|
||||||
|
candidates = []
|
||||||
|
for root in roots:
|
||||||
|
candidates.append(root / "config_defaults")
|
||||||
|
candidates.append(root / "config")
|
||||||
|
|
||||||
for cand in candidates:
|
for cand in candidates:
|
||||||
defaults = _load_layer_dir(cand, skip_filename=None)
|
defaults = _load_layer_dir(cand, skip_filename=None)
|
||||||
@@ -227,7 +233,6 @@ def _load_defaults_from_package_or_project() -> Dict[str, Any]:
|
|||||||
|
|
||||||
return {"directories": {}, "repositories": []}
|
return {"directories": {}, "repositories": []}
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Hauptfunktion
|
# Hauptfunktion
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user