fix: compile-check detects a reference the assembly definition lost

Merged
HA
4d ago
+178-24

Summary

  • uloop compile-check now refuses with COMPILE_CHECK_UNITY_BUILD_REQUIRED when an assembly definition lost a project reference since the last Unity build, instead of replaying the old reference and missing the error.

User Impact

  • Before: removing a reference from an .asmdef was invisible; the run compiled against the reference the last build recorded and could report a clean result for code that no longer compiles.
  • After: the run stops with assembly definition <A> no longer references <B>; uloop compile clears it.

Changes

  • New lostProjectReference, called last from the contract check: a project reference in the response file that the .asmdef does not declare is reported, except the four Unity adds on its own (UnityEngine.UI, UnityEditor.UI, UnityEngine.TestRunner, UnityEditor.TestRunner).
  • An .asmdef with a reference that cannot be resolved is not judged (its declared set is incomplete); a miss is preferred over refusing a healthy project.
  • A name reference now resolves only when an .asmdef in the project declares that name. Unity rewrites the old Unity.RenderPipelines.Lightweight.* names to Unity.RenderPipelines.Universal.* when it reads an .asmdef, so without this a healthy .asmdef using the old name was refused with a refusal no Unity build could clear. The other callers of the resolver already skipped names the build never produced.
  • A gained reference is still reported before a lost one.
  • SKILL.md and docs/compile-check.md: removed the "removed reference is not detected" limitation and described the new refusal in How it works, Limitations and Troubleshooting.

Part of the detection scope ADR 0018 lists.

Verification

  • go test ./internal/compilecheck/ -run 'TestDetectContractDisagreement' -count=1: pass (6 new tests).
  • cli/dispatcher: gofmt -l . empty, go vet ./..., golangci-lint run ./... 0 issues, go test ./... -count=1 pass.
  • A throwaway probe (not committed) ran the check over every assembly of this repository's own Unity project build: 102 assemblies judged, 0 refused, 10 not judged because a reference matches no .asmdef in the project (5 before the name-resolution change).
  • Mutations (each reverted):
    • (a) empty unityInjectedProjectReferences → TestDetectContractDisagreementAcceptsTheReferencesUnityInjects fails.
    • (b) remove the early return on an unresolved reference → TestDetectContractDisagreementSkipsTheLostReferenceCheckWhenAReferenceGUIDIsUnresolvable fails.
    • (c) disable the lostProjectReference call → TestDetectContractDisagreementRefusesAReferenceTheAssemblyDefinitionLost fails.
    • (d) resolve a name reference unconditionally again → only TestDetectContractDisagreementSkipsTheLostReferenceCheckWhenAReferenceNamesNoAssemblyDefinition fails in the whole package.
  • check-skill-size passes; scripts/sync-tool-docs.sh --check reports no drift.