feat: compile-check detects build settings that moved since the last Unity build
Merged
HA
4d ago+1275+1275+0123456789012345678901234567890123456789-44-44-01234567890123456789
Summary
uloop compile-checknow refuses withCOMPILE_CHECK_UNITY_BUILD_REQUIREDwhen a build setting moved since the last Unity build - a scripting define, acsc.rsp, an asmdef'sdefineConstraints/versionDefines,Packages/packages-lock.jsonorPackages/manifest.json- instead of replaying the old settings and missing errors.
User Impact
- Before: these changes were invisible; the run reused what the last build recorded and could report a clean result for code that no longer compiles with the new settings.
- After: the run stops with
scripting define <NAME> is not in the last Unity buildor<setting> changed since the last Unity build;uloop compileclears it.
Changes
- Every run reads the active build target group from the response files' platform define and that group's
scriptingDefineSymbolsfromProjectSettings/ProjectSettings.asset. When the asset was saved after the last build (or there is no build-trace file), it refuses a define some response file lacks (added since the build). This runs before any record, so the first run sees it too. An asset older than the build is left to the record: its defines were in force when Unity built, so a missing one was left out on purpose - a Unity 6 build profile overriding Player Settings is the known case - and refusing it would never clear. - The first run after a Unity build records the build settings in
Library/uloop/compile-check/<dag>/build-settings.json, keyed to the build-trace file Bee rewrites on every build (Library/Bee/tundra.log.json,TundraBuildState.state,fullprofile.json, newest wins). A later run with the same stamp refuses any recorded setting that moved; a new stamp means Unity built again, so the record is replaced, which clears the refusal. csc.rspis compared against the record only: Unity reads the asmdef folder's copy instead ofAssets/csc.rspand copies it unsplit, so reading defines back out of response files would refuse projects Unity builds.- A binary ProjectSettings, an unknown platform, or a Dedicated Server build (
UNITY_SERVER) leaves the defines out of the comparison. - The record is written through the result store's atomic writer, now exported as
resultstore.WriteFileAtomically. - The CLI VibeLog complete entry carries
build_settings(stamp_found,record,refused_part,defines_checked), on refused runs too. docs/compile-check.md,docs/vibe-logs.md, the skill and ADR 0018 (new item (h): build profile overrides) describe the comparison, its refusals and what stays unseen.
Verification
cli/dispatcher:gofmt -l .empty,go vet ./...,golangci-lint run ./...0 issues,go test ./... -count=1pass.- New tests cover the input-space table: refuse an added define; leave
Assets/csc.rspto the record; ignore thecsc.rspof an unbuilt asmdef; no stamp → no record; new / replaced / kept records; seven moved-setting cases; a refusal clears once the stamp moves; a record of another format version or not JSON is replaced; a define of a ProjectSettings older than the build is left to the record; the define scan stops at the next map; the report reachesBuildCompilePlanon a refusal and on success, andRun's result; binary ProjectSettings; group selection including Dedicated Server; separator splitting; an emptyscriptingDefineSymbolsmap. VibeLog tests cover completed, refused, and early-failed runs. - Mutations (each reverted):
- (a)
defineTheBuildLacksalways returns""→TestDetectBuildSettingsChangeRefusesADefineTheLastBuildLacksfails. - (b) compare against any record regardless of stamp →
...ReplacesTheRecordAfterAnotherUnityBuildand...ClearsARefusalOnceUnityBuildsAgainfail. - (c)
firstDifferenceignores the defines → thea removed definesubtest fails. - (d)
readBuildStampalways reports none → the new/replaced/kept/moved/clears/binary tests fail. - (e)
loadBuildSettingsRecordignores the format version →TestDetectBuildSettingsChangeReplacesARecordItCannotRead/another_format_versionfails. - (f) always run the define check (drop the ProjectSettings mtime gate) → only
...LeavesADefineOfAnOlderProjectSettingsToTheRecordfails. - (g) drop the indent stop in
scriptingDefinesValue→TestReadProjectDefinesStopsAtTheNextMapfails ("1"found for Android). - (h) drop
withBuildSettingsReporton the refusal →TestBuildCompilePlanCarriesTheBuildSettingsReportOfARefusalfails; emptyBuildPlan.BuildSettings→ the plan and Run tests fail; emptyResult.BuildSettings→TestRunReportsTheBuildSettingsComparisonfails.
- (a)
- Live run on this repository's Unity project with the Editor closed, using a
distbinary built from this branch:- Editor open,
uloop compiletwice: the three build-trace files moved from 03:30:22 to 03:30:32 while the newest dll stayed at its earlier time. This is what the stamp relies on. They stayed put after quitting the Editor. compile-check: exit 0, VibeLogbuild_settings={record: new, stamp_found: true}.;CC_PROBE_ADDEDappended to the Standalone defines: exit 1,scripting define CC_PROBE_ADDED is not in the last Unity build(measured before the stamp was moved ahead of the check; the log then showedstamp_found: false, which now readstrue). Reverted.- One existing Standalone define removed: exit 1,
scripting defines of Standalone (removed: <DEFINE>) changed since the last Unity build,refused_partthe same. Reverted → exit 0,record: kept. Assets/csc.rspcreated with-nowarn:CS0168: exit 1,Assets/csc.rsp changed since the last Unity build. Removed → exit 0.git status --porcelainmatched the state before the run.
- Editor open,