Apply the units before the common removelists, and let a build select them #4

Merged
marcos-mendez merged 1 commit from feat/unit-order into master 2026-09-27 00:30:18 -03:00
marcos-mendez commented 2026-09-27 00:11:31 -03:00 (Migrated from github.com)

share/product.mk already resolves and applies fab units, and the Keel decision 0010 experiment showed a layer built from a unit is the same layer. Two things about the loop stood in the way of using one as a component.

Position. The loop ran after the common removelists and after the product-local overlay. A common removelist could not remove a file a unit brought in, and a recipe's own overlay stopped winning over the component's. The loop now runs after the common overlays, conf scripts and patches and before the common removelists, with all unit overlays applied before any unit conf script, mirroring the two phases the common inputs go through.

Selection. Every directory under unit.d was applied, with no way to leave one out. A layered build must not re-run the conf script of a component its parent already applied: conf/mysql does ln -s /etc/init.d/mysql under bash -e and fails the second time. The new UNITS variable names the units to apply and defaults to all of them. Plans are still resolved from UNIT_DIRS whatever UNITS says, since a plan only names packages.

Each command in the loops gets || exit: a phase is one shell line, so a unit failing in the middle of it was swallowed.

Test plan

  • tests/units.sh: 38 checks. It builds a fake product with three units against this product.mk with fab-apply-overlay, fab-chroot, fab-apply-removelist, fab-apply-patch and fab-plan-resolve replaced by stubs that log their arguments, then asserts on the log. Covers each unit input, each position, UNITS default, one unit, empty, no unit.d, and both failure paths.
  • tests/coverage.sh runs both suites: 57 of 57 checks, 100 percent, gate 100.
  • tests/source-date-epoch.sh unchanged and passing.
  • A real layered build of the mariadb component, in the buildtasks change that consumes UNITS.
`share/product.mk` already resolves and applies fab units, and the Keel decision 0010 experiment showed a layer built from a unit is the same layer. Two things about the loop stood in the way of using one as a component. **Position.** The loop ran after the common removelists and after the product-local overlay. A common removelist could not remove a file a unit brought in, and a recipe's own overlay stopped winning over the component's. The loop now runs after the common overlays, conf scripts and patches and before the common removelists, with all unit overlays applied before any unit conf script, mirroring the two phases the common inputs go through. **Selection.** Every directory under `unit.d` was applied, with no way to leave one out. A layered build must not re-run the conf script of a component its parent already applied: `conf/mysql` does `ln -s /etc/init.d/mysql` under `bash -e` and fails the second time. The new `UNITS` variable names the units to apply and defaults to all of them. Plans are still resolved from `UNIT_DIRS` whatever `UNITS` says, since a plan only names packages. Each command in the loops gets `|| exit`: a phase is one shell line, so a unit failing in the middle of it was swallowed. ## Test plan - [x] `tests/units.sh`: 38 checks. It builds a fake product with three units against this `product.mk` with `fab-apply-overlay`, `fab-chroot`, `fab-apply-removelist`, `fab-apply-patch` and `fab-plan-resolve` replaced by stubs that log their arguments, then asserts on the log. Covers each unit input, each position, `UNITS` default, one unit, empty, no `unit.d`, and both failure paths. - [x] `tests/coverage.sh` runs both suites: 57 of 57 checks, 100 percent, gate 100. - [x] `tests/source-date-epoch.sh` unchanged and passing. - [ ] A real layered build of the mariadb component, in the buildtasks change that consumes `UNITS`.
Sign in to join this conversation.
No description provided.