Skip to content

Commit 1d219b5

Browse files
committed
feat(cli): rework build / test environment handling
Adds an explicit environment (env) subcommand which allows users to list and interact with existing build / test environments. Additionally contains extensive internal refactoring to make the environment tracking and cleanup more robust.
1 parent b75bc8d commit 1d219b5

34 files changed

Lines changed: 3746 additions & 714 deletions

‎.github/workflows/ci.yaml‎

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ jobs:
141141
contents: read
142142
# Push of the pre-built CI image is additionally gated to main below.
143143
packages: write
144+
env:
145+
# Registry and Environment Host roots together, so the cached build
146+
# tree stays registered under the same Environment id.
147+
DEBMAGIC_DATA_DIR: /tmp/debmagic-data
144148
steps:
145149
- uses: actions/checkout@v5
146150
- uses: Swatinem/rust-cache@v2
@@ -149,16 +153,18 @@ jobs:
149153
- name: Cache the debmagic build tree
150154
uses: actions/cache@v4
151155
with:
152-
path: /tmp/debmagic
153-
key: debmagic-build-${{ hashFiles('Cargo.lock', 'debian/changelog', 'debian/control', 'debian/rules') }}
154-
restore-keys: debmagic-build-
155-
- name: Prune stale build trees from the restored cache
156+
path: /tmp/debmagic-data
157+
key: debmagic-data-${{ hashFiles('Cargo.lock', 'debian/changelog', 'debian/control', 'debian/rules') }}
158+
restore-keys: debmagic-data-
159+
- name: Prune Environments of other package versions from the restored cache
156160
run: |
157-
mkdir -p /tmp/debmagic
158161
current="$(dpkg-parsechangelog -SSource)-$(dpkg-parsechangelog -SVersion)"
159-
find /tmp/debmagic -mindepth 1 -maxdepth 1 -type d \
160-
! -name "$current" ! -name "${current}-test" \
161-
-exec rm -rf {} +
162+
cargo run --locked -q -p debmagic -- env list \
163+
| awk -v current="$current" 'NR > 1 && $4 != current { print $1 }' \
164+
| while read -r id; do
165+
cargo run --locked -q -p debmagic -- env clean "$id" \
166+
|| echo "::warning::could not prune Environment $id"
167+
done
162168
- name: Resolve CI image tag
163169
id: image
164170
run: |

‎Cargo.lock‎

Lines changed: 102 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ ignore = { version = ">=0.4.25" }
3232
md-5 = { version = ">=0.11" }
3333
sha1 = { version = ">=0.11" }
3434
sha2 = { version = ">=0.11" }
35+
rusqlite = { version = ">=0.32" }
3536

3637
# dev dependencies
3738
test-case = { version = ">=3.3.1" }

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Unified and future-proof developer tooling for increased productivity in the [De
1010
Debmagic has two independent parts:
1111
- tooling to [**build** and **test**](#debmagic-building) packages
1212
- in isolated container environments (lxd, docker, ...)
13-
- `debmagic build`, `debmagic check`, `debmagic test`, `debmagic shell`, ...
13+
- `debmagic build`, `debmagic check`, `debmagic test`, `debmagic env`, ...
1414
- create package [**build instructions**](#debmagic-packaging)
1515
- using Python with `debian/rules.py` (instead of shell & Makefiles)
1616

‎debian/control‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ Build-Depends:
3434
librust-ignore-dev (>=0.4.25),
3535
librust-md-5-dev (>= 0.11),
3636
librust-sha1-dev (>= 0.11),
37-
librust-sha2-dev (>= 0.11)
37+
librust-sha2-dev (>= 0.11),
38+
librust-rusqlite-dev (>= 0.32),
39+
libsqlite3-dev,
40+
pkg-config
3841
Rules-Requires-Root: no
3942
X-Style: black
4043
Standards-Version: 4.7.2

‎debian/rules‎

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,36 @@ os.environ.update({
2222
"CARGO": "/usr/share/cargo/bin/cargo",
2323
"CARGO_HOME": f"{pkg.base_dir}/debian/cargo_home",
2424
"CARGO_REGISTRY": f"{pkg.base_dir}/debian/cargo_registry",
25-
"DEB_CARGO_CRATE": f"{pkg.build_env.DEB_SOURCE}_{pkg.build_env.DEB_VERSION_UPSTREAM}"
25+
"DEB_CARGO_CRATE": f"{pkg.build_env.DEB_SOURCE}_{pkg.build_env.DEB_VERSION_UPSTREAM}",
26+
# debmagic-pkg is setuptools and ignores this. The rewrite below is what
27+
# makes resolution succeed; this only keeps maturin from enabling the
28+
# (now empty) default feature.
29+
"MATURIN_PEP517_ARGS": "--no-default-features",
2630
})
2731

32+
# Cargo resolves every feature name in the table, including ones that are not
33+
# enabled, so `--no-default-features` still requires rusqlite to advertise
34+
# `bundled`. Debian's librust-rusqlite-dev deletes that feature and links the
35+
# system libsqlite3. Drop the reference for this build, then put the manifest
36+
# back so a host or incremental tree is not left edited.
37+
cargo_toml = Path("packages/debmagic/Cargo.toml")
38+
bundled_sqlite = 'bundled-sqlite = ["rusqlite/bundled"]'
39+
system_sqlite = "bundled-sqlite = []"
40+
41+
42+
def use_system_sqlite() -> str:
43+
original = cargo_toml.read_text()
44+
if bundled_sqlite in original:
45+
cargo_toml.write_text(original.replace(bundled_sqlite, system_sqlite, 1))
46+
return original
47+
if system_sqlite in original:
48+
restored = original.replace(system_sqlite, bundled_sqlite, 1)
49+
return restored
50+
raise SystemExit(
51+
f"{cargo_toml}: expected {bundled_sqlite!r} so the Debian build can drop "
52+
"the rusqlite bundled feature that librust-rusqlite-dev removes"
53+
)
54+
2855
packages = {
2956
"debmagic": ("packages/debmagic", "debmagic"),
3057
"debmagic-pkg": ("packages/debmagic-pkg", "debmagic-pkg"),
@@ -68,4 +95,8 @@ def dh_auto_clean(build: Build):
6895
dh_auto(build, "dh_auto_clean")
6996

7097

71-
pkg.pack()
98+
cargo_toml_original = use_system_sqlite()
99+
try:
100+
pkg.pack()
101+
finally:
102+
cargo_toml.write_text(cargo_toml_original)

‎docs/index.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
usage/getting-started.md
1010
usage/build.md
1111
usage/test.md
12+
usage/env.md
1213
usage/source.md
1314
usage/config.md
1415
usage/modules/index.md

‎docs/usage/build.md‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ debmagic build binary --driver lxd \
3434
| `--output-dir <dir>` | Directory to put the resulting build artifacts |
3535
| `--shell-on-failure` | On build failure, drop into an interactive shell in the build environment when stdout is a TTY |
3636

37-
[`debmagic shell`](#inspecting-a-failed-build) — attach an interactive shell to a build environment
37+
[`debmagic env shell`](#inspecting-a-failed-build) — attach an interactive shell to an Environment
3838

3939
## Picking a driver
4040

@@ -52,13 +52,14 @@ There's no auto-detection; pick one and pass it explicitly every time (or config
5252

5353
On failure the build environment is torn down by default. Pass `--shell-on-failure` to drop into an interactive shell inside the build environment when stdout is a TTY (destroyed on shell exit unless `--persistent` was used).
5454

55-
To inspect after the run finishes, pass `--persistent` up front, then:
55+
To inspect after the run finishes, pass `--persistent` up front, then use [`debmagic env shell`](env.md).
5656

5757
```shell
58-
# if you're in the package still
59-
debmagic shell
60-
# from the outside:
61-
debmagic shell --source-dir /path/to/parent/of/debian/dir
58+
# if you're in the package still and exactly one Environment exists for it
59+
debmagic env shell
60+
# from anywhere:
61+
debmagic env list
62+
debmagic env shell <id>
6263
```
6364

6465
This attaches an interactive shell inside the still-running (or restartable) build environment, at the package's build directory.
@@ -188,4 +189,4 @@ Instead of repeating CLI flags on every invocation, drop a [config file](config.
188189

189190
## Internals
190191

191-
- Container/device names are derived and sanitized internally (alphanumeric + hyphen, ≤63 chars for LXD/Incus) — don't try to predict or construct them yourself; use `debmagic shell` instead of `lxc`/`docker` commands directly.
192+
- Container/device names are derived and sanitized internally (alphanumeric + hyphen, ≤63 chars for LXD/Incus) — don't try to predict or construct them yourself; use `debmagic env shell` instead of `lxc`/`docker` commands directly.

‎docs/usage/config.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Config files are merged in order of increasing precedence, so later files overri
1414
Only files that exist are read; missing ones are skipped.
1515
Command-line flags override whatever the merged config resolves to.
1616

17+
`DEBMAGIC_DATA_DIR` relocates the Environment registry (`db.sqlite`) and the default `environments_dir` together. A relative value is resolved to an absolute path against the current working directory. It is not a config file key.
18+
1719
## Options
1820

1921
All keys are optional.
@@ -27,7 +29,7 @@ All keys are optional.
2729
| `driver.docker.base_images` | map | — | — | Base image per distro, keyed by `"<distro>:<codename>"` (e.g. `"debian:trixie"`). Falls back to `docker.io/<distro>:<codename>`. For non-Debian/Ubuntu suites (e.g. `"yocto:kirkstone"`), the map entry is what makes the suite a known DistroVersion for Docker builds. |
2830
| `driver.lxd.project` | string | — | — | LXD/Incus project to use. |
2931
| `driver.lxd.base_images` | map | — | — | Base image per distro, keyed by `"<distro>:<codename>"`. Falls back to the driver's default remote image. Same custom-suite registry role as Docker's map for LXD/Incus. |
30-
| `temp_build_dir` | path | `/tmp/debmagic` | — | Where build trees are staged. |
32+
| `environments_dir` | path | `$XDG_DATA_HOME/debmagic/environments` | — | Parent directory of Environment Host roots. Must be absolute or start with `~/`. The Environment registry is always `$XDG_DATA_HOME/debmagic/db.sqlite` (override both with `DEBMAGIC_DATA_DIR`). |
3133
| `output_dir` | path | `build` | `-o`/`--output-dir` | Where build artifacts are exported; relative paths resolve against the package root. |
3234
| `incremental` | bool | `false` | `--incremental` | Retain the environment and sync only source changes, preserving generated files. Binary-only; implies `persistent`; incompatible with `clean`. |
3335
| `source_sync_mode` | enum | `tracked` | `--source-sync` | Which source files are staged (see below). |

0 commit comments

Comments
 (0)