feat: compile-check records whether a compile may still apply while its references are compiling
Summary
- compile-check now records, with each compile result, enough of its input key to tell whether that result may still be replayed while some of the project assemblies it references are still compiling.
- No behavior change; the next PR consults the new predicate.
User Impact
None yet. The next pull request lets an assembly start compiling before the dependents it references finish. Such a compile overwrites the assembly's record, so it must not start when the record could still be replayed once those references finish; otherwise a run over the same inputs would compile that assembly twice every time. This PR adds what that decision needs.
The first run after updating compiles again every assembly it would otherwise have replayed, because the compile result format changes.
Changes
- The input key also reports:
- a shape: the same parts in the same order, except that references to project assemblies (
<dag dir>/<name>.ref.dll) are left out. The sources are written from the hashes the key read, not read again. - the identity of each project assembly reference: the sha256 of the very line the key holds for it, produced by the same function, and whether that line reads this run's output (
produced) or Unity's build (unity). - Which references are split out depends only on whether they name a project assembly, never on whether this run compiles them. A reference entering or leaving the plan leaves the bytes of the key as they were, so it leaves the shape and the identities as they were too.
- The key itself is computed byte for byte as before.
- a shape: the same parts in the same order, except that references to project assemblies (
- Compile results keep the shape and the identities, in format version 3. A version 2 result is neither replayed nor treated as a baseline's compile.
MayStillApplyanswers whether a record may still apply when the references named as unknown finish. It checks, in order, and stops at the first that fails:- the same project assemblies are referenced;
- every known reference has its recorded kind and hash;
- every unknown reference the record read from Unity's build still matches Unity's file. Whatever such a reference finishes as, a rebuilt Unity file can never give the recorded line back. An unknown reference the record read from this run's output is not compared;
- the outputs still hold what was written;
- the shape matches. The shape is a function asked for last, so a difference before it answers without reading any source.
recordMayStillApplyon the compiler computes only the reference lines itself and hashes the sources inside the shape function. It answers no for--all(which never replays) and when the key cannot be computed.
Verification
-
New tests:
- the shape ignores the content of a produced reference and the timestamp of a kept one, which move the key and that reference's identity instead;
- the key, shape and identities do not depend on whether a kept reference is in the plan;
- the shape follows the sources and a reference outside the project; the identities do not;
- the identities name every project reference and nothing else, each with the kind of file its line reads;
MayStillApply:- an unknown reference recorded from this run's output differs (yes);
- an unknown reference recorded from Unity's build still matches (yes) or has moved (no);
- a known reference changed (no, and the shape is never asked for);
- a known reference of another kind (no);
- the shape is asked for exactly once when everything else matches, and decides the answer;
- a shape that cannot be computed (no);
- another set of references, either way (no);
- changed outputs (no, and the shape is not asked for);
- a version 2 record (no, and not reused);
- on a compiled project:
- a dependent of a changed reference may still apply while that reference is unknown, whatever its output holds, and not after its own source changed;
- a dependent that read a kept reference from Unity's build stops applying once Unity's file is rebuilt;
- a kept reference leaving the plan still applies;
--alland an unreadable source answer no.
Each new test failed to compile before the implementation.
-
Mutations, each restored afterwards:
Mutation Fails Write project references into the shape too produced / kept reference shape tests, names every project reference Split references by whether the plan compiles them does not depend on the plan, names every project reference, a reference left the plan Compare unknown references recorded from this run's output too only unknown references differ, and the four compiler-level tests that leave such a reference unknown Leave every unknown reference uncompared an unknown reference whose Unity file moved, at the store and on a compiled project Compare the hash only, not the kind a known reference of another kind Record every reference as read from Unity's build names every project reference, and the compiler-level tests that leave a produced reference unknown Drop the check that the sets have the same size another set of references Ask the store's shape function before comparing references a changed known reference, changed outputs, the shape asked for once Ignore an error computing the shape a shape that cannot be computed Ignore --all--allanswers noDrop the outputs check changed outputs Ignore the shape the shape asked for once (another shape), and the compiled project test whose own source changed The order of computation is pinned by the store's tests, which count calls to the shape function. Whether
recordMayStillApplyhashes the sources only inside that function cannot be seen from its answer, so no compiler-level test claims it. -
In
cli/dispatcher:gofmt -lis empty;go vet ./...andgolangci-lint run ./...(0 issues) pass;go test -racepasses oninternal/compilecheck/...andinternal/dispatcher/...;- statement coverage from
go test -coverprofile ./...is not below the base branch measured the same way.
-
scripts/check-code-complexity.shandscripts/check-file-length.shpass. -
Repository CI does not run on pull requests into this branch; the checks above were run locally.