Skip to content

Emit Depends and the 8 other dropped control fields - #10

Merged
dkijania merged 1 commit into
mainfrom
fix/emit-all-control-fields
Jul 22, 2026
Merged

dkijania merged 1 commit into
mainfrom
fix/emit-all-control-fields

Conversation

@dkijania

Copy link
Copy Markdown
Member

Fixes #9

What

format_control_file emitted a hardcoded 12 fields, silently discarding Depends, Pre-Depends, Recommends, Suggests, Conflicts, Replaces, Provides, Vendor and Authors — even though the CLI accepts all nine, the values reach DebianControl, and content_verifier parses them back out of dpkg-deb -I in order to check them. build could not produce a package its own verify content was written to validate.

The failure was silent: build exited 0 and produced a well-formed .deb that installed fine wherever the dependencies happened to already be present, failing only on a clean target.

All the data already reached DebianControl, so the change is confined to the renderer.

Design calls

Optional fields are omitted when unset or empty, not emitted blank — dpkg has no use for a valueless Depends:.

The original twelve stay unconditional, blank or not, so packages built before this change keep byte-identical stanzas (Installed-Size: and Source: are routinely empty in practice). I deliberately left their empty-handling alone; changing it is unrelated scope with real breakage risk.

Lists join with ", ", which round-trips through content_verifier's split-on-comma-and-trim. One test pins exactly that, so the writer and reader can't drift apart again.

Field order follows Debian convention — Vendor/Authors after Maintainer, relationship fields after Installed-Size. Order is not semantically significant, and existing tests assert with contains.

Verification

7 new unit tests (this function had none): emission, omission when unset, empty-and-blank-only lists, entry trimming, the original twelve still unconditional, and the verifier round-trip.

Full CI gate green locally: cargo fmt --check, cargo clippy --all-targets -D warnings, cargo test --all-targets (51 lib + 9 integration), cargo test --doc.

Before/after on a real .deb, identical flags both times:

BEFORE (main)                    AFTER
  Package: mina-daemon             Package: mina-daemon
  Version: 1.2.3                   Version: 1.2.3
  Architecture: amd64              Architecture: amd64
  Maintainer: O(1)Labs ...         Maintainer: O(1)Labs ...
                                   Vendor: O(1)Labs
                                   Authors: O(1)Labs ...
  Section: base                    Section: base
  Priority: optional               Priority: optional
  Homepage: ...                    Homepage: ...
  Installed-Size:                  Installed-Size:
                                   Depends: libssl3, libgmp10, libgomp1
                                   Suggests: postgresql
                                   Conflicts: mina-devnet
                                   Replaces: mina-old
                                   Provides: mina
  Source:                          Source:
  Suite: stable                    Suite: stable
  Codename: bookworm               Codename: bookworm
  License: Apache-2.0              License: Apache-2.0

The BEFORE run exited 0 and produced a package with none of them.

Not in scope

Origin, Label and Breaks are not modelled at all (absent from DebianControl, not merely unemitted). mina emits all three, so they block a full migration of its build path — but they're additive features rather than this bug. The README's "Known limitation" section now names exactly those three.

format_control_file emitted a hardcoded 12 fields, silently discarding
Depends, Pre-Depends, Recommends, Suggests, Conflicts, Replaces,
Provides, Vendor and Authors even though the CLI accepts them, the
values reach DebianControl, and content_verifier parses them back out
of dpkg-deb -I to check them. build could not produce a package its
own verifier was written to validate.

The failure was silent: build exited 0 and emitted a well-formed .deb
that installed fine wherever the dependencies happened to already be
present, and only failed on a clean target.

Optional fields are omitted when unset or empty rather than emitted
blank, since dpkg has no use for a valueless relationship field. The
original twelve stay unconditional so existing packages keep
byte-identical stanzas. Lists join with ", ", which round-trips
through the verifier's split-on-comma-and-trim.

Fixes #9
@dkijania
dkijania merged commit 9ed6624 into main Jul 22, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

build silently drops Depends and 8 other control fields

1 participant