Generate the third-party notices from the module table a binary carries - #134
Merged
iderex merged 1 commit intoAug 13, 2026
Merged
Conversation
A binary this repository publishes owes whoever downloads it the licence of everything inside it, and most licences ask for the text rather than for a name. Nothing here produced that text, so the obligation was met by a list nobody had written yet. internal/notices renders the document from the module set the toolchain records inside the binary, and reads each module's licence text out of the module cache the build already populated. cmd/notices is the entry point the release build calls: it takes the binary and the cache root as arguments, opens no connection and asks no environment variable, so what it produced can be reproduced by hand from the two paths in its command line. The failure it prevents is a notices file that names a module and does not carry its text. A module whose licence cannot be read is refused under dependency-has-no-licence-text and named in a section of the document that says the document is incomplete by exactly those entries, rather than being dropped from a file that then reads as finished. The second failure is drift: a maintained list is correct on the day it is written and wrong once a dependency arrives, so there is no second list here for anything to drift against. The render carries no clock and sorts by module path, so two runs from one build produce one file and a checksum over it still separates a release built from different source from one built twice. Refs #37 Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #37
What this changes
A binary this repository publishes owes whoever downloads it the licence of
everything inside it, and most licences ask for the text rather than for a
name. Nothing here produced that text.
internal/noticesrenders the document from the module set the toolchainrecords inside a binary, and reads each module's licence text out of the module
cache the build already populated.
cmd/noticesis the entry point: it takesthe binary and the cache root as two arguments, opens no connection and reads no
environment variable, so what it produced can be reproduced by hand from the two
paths in its command line. That is the shape
cmd/contextsalready argued forkeeping a live lookup out of a command whose output has to be checkable.
The means is Go, in this module, with nothing added to
go.mod. The moduletable is written by the toolchain and read by
debug/buildinfoin the standardlibrary, so the data source is the build itself. Reaching for a generator from
outside would add the first dependency this tree has ever carried in order to
list the dependencies this tree carries, and the suites that already exist would
not reach it.
What failure it prevents
A notices file that names a module and does not carry its text. A module whose
licence cannot be read is refused under
dependency-has-no-licence-textandnamed in a section that says the document is incomplete by exactly those
entries, rather than dropped from a file that then reads as finished.
Drift is the second one. A maintained list is correct on the day it is written
and wrong once a dependency arrives, and wrong in the direction that matters: a
module in the binary and absent from the list. There is no second list here for
anything to drift against.
The render carries no clock and sorts by module path, so two runs from one build
produce one file. A document carrying the time it was made would differ between
two runs of the same tag, and a checksum over it could then no longer separate a
release built from different source from one built twice.
What was run
The gate
CONTRIBUTING.mdnames, at74762af04541029f0916fca904e1ccd6bdd35a92:go buildandgo vetprinted nothing, andgofmt -lprinted nothing, whichis its passing result.
The runner over this tree:
The guard was proved by deleting it. Replacing the refusing arm of
Renderwitha silent
continue, so an unreadable module is dropped instead of refused, andrunning the package:
Exactly the three refusing cases went red and the neighbour they name stayed
green, so the rule bites for the reason it names rather than refusing whatever
it reads. The arm was restored and the suite is green above.
The size, and it is above the bound this repository notes at:
Of that, 232 lines are the seven fixture cases and 1008 are Go, of which 585 are
statements and the rest are the comments this tree is written with. It was not
split, because the two halves a split would produce are the render with no caller
and the caller with no render, and neither is reviewable alone. The property a
reader can check instead of the diff is that every module the build records
either appears with the text it shipped or appears in the section saying it did
not.
What this does not do
It does not close #37. Two of that issue's three legs are that both artefacts are
generated by the release build and attached to the release, and this repository
has no release workflow and no release. Those legs belong to #41, which is where
the attaching happens, and the bill of materials belongs there with them, because
#37 places it where the artefact is built.
It does not identify a licence. It reproduces the file a module shipped under a
conventional licence filename and takes no view on which licence that is or on
whether reproducing it satisfies that licence. A label guessed by reading the
text would be a claim nothing here can support, and the document says so where a
reader will see it.
Nothing runs it yet. The command exists and its suite exercises it against a
binary it builds, and no workflow calls it, because the workflow that would is
#41.
The seven cases construct a module set rather than compiling one. Building a
module with a real dependency would need a fetch, and this suite runs with no
network. What compiles a binary and reads a real module table out of it is
cmd/notices' own test, and that binary has no third-party dependency, so thetwo together prove the render and the reading rather than the two at once.
This board had no second reader for this change and the evidence above stands in
place of one.