perf: compile-check reads the project's directories once per run
Merged
HA
2d ago+831+831+012345678901234567890123456789-106-106-012345678901234567890123456789
Summary
uloop compile-checkreads the project's directories once per run instead of three times, which shortens every run on a large project, including the runs where nothing changed.- Which assemblies it selects, which sources it compiles, and which errors stop it do not change.
User Impact
- Before: on a project of about 28,000 sources and 680 assembly definitions, planning took about 1.6 s of a 1.7 s no-change run, almost all of it file-system calls. The assembly definition index, the assembly reference index, and every assembly's source re-glob each walked the same directories again, and every recorded source was checked with its own
stat. - After: one walk lists Assets, Packages, the package cache, and local packages at the start of the run, and the indexes and source re-globs read that listing. Measurements on a large project are pending.
Changes
- A new listing of the index roots (
project_tree.go), taken by onefilepath.WalkDirper root in root order. It keeps the rules the separate walks had: names Unity ignores are left out, symbolic links are listed but not followed, and the walk stops at the first root that fails, keeping what that root listed before the error. A failed root's directories are not used for lookups. - The
.asmdefindex reads each root's.asmdeffiles in walk order, then reports that root's walk error, so a duplicate assembly name still resolves to the first file in root and walk order (not path order), and errors come in the same order as before. The.asmrefindex is still sorted by path. - The source re-glob (in the source rebuild and in the
.asmrefcheck), the check for a nested.asmdef, and the check that a recorded source still exists read the listing, which the owner index carries. - The listing only answers yes. A name it lacks, a path outside it, or an entry that is a symbolic link is checked on the disk as before, because a file system that ignores case or Unicode normalization finds a differently spelled name, and a dangling link is not a file. A directory outside the listing is globbed from the disk.
Verification
cli/dispatcher:golangci-lint fmt --diff,go vet ./...,golangci-lint run(0 issues), the complexity config (0 issues), andgo test ./...pass. Coverage with the CI exclusions: 94.24% (baseline 94.2).cli/release-automation:go test ./...passes, including the architecture test on file length. The file-length check passes.- Existing tests keep their expectations; only their calls changed to pass the listing, and the source rebuild tests now go through it.
- New tests pin: duplicate names across siblings, a directory beside a same-named
.asmdef, and across roots; error order between a broken.asmdefand an unreadable directory in either root order and within one root; package-cache and.asmdef-less assemblies; sources behind a linked directory, a dangling link, a case-only rename (with and without an.asmdef), another Unicode normalization (macOS), and sources outside the roots; ignored files; that the disk glob and the listing glob agree, including on a directory named like an.asmdef; and that recording an entry whose parent was never listed does not panic. - Mutation checks, each restored afterwards: answering a missing name from the listing fails the dangling-link, case-rename, and normalization tests; sorting
.asmdefpaths before indexing and reversing the root order each fail the duplicate test; reporting walk errors before reads and walking on past a failed root, and returning a root's walk error before its reads each fail an error-order test; counting a directory named like an.asmdefas one fails the glob agreement test.