From 3829bbe80b40ee188a78cd5e7f3c2b880d218a3d Mon Sep 17 00:00:00 2001 From: Softer Date: Sun, 26 Apr 2026 14:20:15 +0300 Subject: [PATCH] Move dev_vm.sh under scripts/ and split out Python helper Address svartkanin's review on #4470. Two related changes: - Move dev_vm.sh to scripts/dev_vm.sh and split SCRIPT_DIR (where the script lives) from PROJECT_DIR (project root, parent of scripts/). All .dev-* artifact paths now anchor on PROJECT_DIR so they still land in the repo root where .gitignore matches them. Both invocations work: ./scripts/dev_vm.sh from project root and ./dev_vm.sh from inside scripts/. - Extract the inline pyproject.toml parser from a bash heredoc into scripts/derive_packages.py. Same logic, less mixed-language noise. The whole-script bash -> Python question is left open until @Torxed weighs in on principled inclusion of dev tooling in archinstall. --- scripts/derive_packages.py | 33 +++++++++++++++++++++++ dev_vm.sh => scripts/dev_vm.sh | 48 +++++++++++++--------------------- 2 files changed, 51 insertions(+), 30 deletions(-) create mode 100755 scripts/derive_packages.py rename dev_vm.sh => scripts/dev_vm.sh (86%) diff --git a/scripts/derive_packages.py b/scripts/derive_packages.py new file mode 100755 index 00000000..1f84774d --- /dev/null +++ b/scripts/derive_packages.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +"""Parse pyproject.toml runtime dependencies and emit Arch package names. + +Assumes the python- convention, which holds for every archinstall +dependency today. If a future dep breaks the convention, fix here. +""" + +import re +import sys +import tomllib + + +def main() -> int: + if len(sys.argv) != 2: + print(f'usage: {sys.argv[0]} ', file=sys.stderr) + return 1 + + with open(sys.argv[1], 'rb') as f: + data = tomllib.load(f) + + for dep in data['project']['dependencies']: + name = re.split(r'[<>=!~;\[\s]', dep, maxsplit=1)[0].strip() + if name: + # PEP 503: lowercase, any run of [-_.] becomes '-'. Arch mirrors this + # naming, so normalize before prepending the python- prefix. + name = re.sub(r'[-_.]+', '-', name).lower() + print(f'python-{name}') + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/dev_vm.sh b/scripts/dev_vm.sh similarity index 86% rename from dev_vm.sh rename to scripts/dev_vm.sh index 9ce5bdc4..5a5dc7df 100755 --- a/dev_vm.sh +++ b/scripts/dev_vm.sh @@ -15,13 +15,16 @@ # /root/cfg .dev-configs share (9p rw, mounted only if folder exists) # archinstall alias for `python -m archinstall` # -# Usage: -# ./dev_vm.sh - build ISO if missing, fresh disk, boot -# ./dev_vm.sh rebuild | r - force rebuild ISO, fresh disk, boot -# ./dev_vm.sh keep | k - reuse disk, boot ISO -# ./dev_vm.sh boot | b - boot from installed disk (no ISO) -# ./dev_vm.sh clean | c - remove disk, NVRAM, ISO -# ./dev_vm.sh -h - show this help +# Run from the project root or from inside scripts/ - both work, the script +# resolves the project root from its own location. +# +# Usage (from project root): +# ./scripts/dev_vm.sh - build ISO if missing, fresh disk, boot +# ./scripts/dev_vm.sh rebuild | r - force rebuild ISO, fresh disk, boot +# ./scripts/dev_vm.sh keep | k - reuse disk, boot ISO +# ./scripts/dev_vm.sh boot | b - boot from installed disk (no ISO) +# ./scripts/dev_vm.sh clean | c - remove disk, NVRAM, ISO +# ./scripts/dev_vm.sh -h - show this help # # Env overrides: # SCREEN_W, SCREEN_H - virtio-vga resolution (default 1280x720) @@ -32,11 +35,11 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -PROJECT_DIR="$SCRIPT_DIR" -CONFIGS_DIR="$SCRIPT_DIR/.dev-configs" -ISO_DIR="$SCRIPT_DIR/.dev-iso" -DISK="$SCRIPT_DIR/.dev-disk.qcow2" -OVMF_VARS="$SCRIPT_DIR/.dev-ovmf-vars.fd" +PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +CONFIGS_DIR="$PROJECT_DIR/.dev-configs" +ISO_DIR="$PROJECT_DIR/.dev-iso" +DISK="$PROJECT_DIR/.dev-disk.qcow2" +OVMF_VARS="$PROJECT_DIR/.dev-ovmf-vars.fd" DISK_SIZE="30G" RAM="4G" CPUS="4" @@ -97,27 +100,12 @@ check_arch_host() { } # Parse runtime deps from pyproject.toml and map to Arch package names. -# Assumes the `python-` convention, which holds for every archinstall -# dependency today. If a future dep breaks the convention, fix here. +# Delegates to derive_packages.py so the Python logic lives in a real .py file. derive_packages() { command -v python3 >/dev/null 2>&1 || err "python3 not found on host (needed to parse pyproject.toml)" local result - result=$(python3 - "$PROJECT_DIR/pyproject.toml" <<'PY' -import re -import sys -import tomllib - -with open(sys.argv[1], 'rb') as f: - data = tomllib.load(f) -for dep in data['project']['dependencies']: - name = re.split(r'[<>=!~;\[\s]', dep, maxsplit=1)[0].strip() - if name: - # PEP 503: lowercase, any run of [-_.] becomes '-'. Arch mirrors this - # naming, so normalize before prepending the python- prefix. - name = re.sub(r'[-_.]+', '-', name).lower() - print(f'python-{name}') -PY -) || err "failed to parse $PROJECT_DIR/pyproject.toml" + result=$(python3 "$SCRIPT_DIR/derive_packages.py" "$PROJECT_DIR/pyproject.toml") \ + || err "failed to parse $PROJECT_DIR/pyproject.toml" [ -n "$result" ] || err "pyproject.toml has no [project.dependencies]" printf '%s\n' "$result" }