From a20d73abff295ae44a12cc4a2e90ca3f9ba5f575 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 18 Sep 2026 04:53:42 -0700 Subject: [PATCH] fix: line-cap checks skip files in ignored temporary directories (#151748) --- scripts/check-line-cap-ratchet.mts | 2 ++ test/scripts/check-line-cap-ratchet.test.ts | 34 +++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/scripts/check-line-cap-ratchet.mts b/scripts/check-line-cap-ratchet.mts index d0e384d20e23..7df73a9dc60f 100644 --- a/scripts/check-line-cap-ratchet.mts +++ b/scripts/check-line-cap-ratchet.mts @@ -173,6 +173,8 @@ export function main(root = process.cwd(), argv = process.argv.slice(2)) { throw new Error("No max-lines overrides found in .oxlintrc.json"); } scratch = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-line-cap-")); + // Stop ancestor Git ignores at the snapshot; explicit lint exclusions still apply. + fs.mkdirSync(path.join(scratch, ".git")); const after = collectViolations(path.join(scratch, "head"), headSources, config); // Only over-cap head files need an inherited allowance. A broken base must // not block a valid repair that already satisfies the current cap. diff --git a/test/scripts/check-line-cap-ratchet.test.ts b/test/scripts/check-line-cap-ratchet.test.ts index 3b8e7c93dcc1..655d460d9294 100644 --- a/test/scripts/check-line-cap-ratchet.test.ts +++ b/test/scripts/check-line-cap-ratchet.test.ts @@ -6,7 +6,10 @@ import { compareLineCapViolations, main } from "../../scripts/check-line-cap-rat import { useAutoCleanupTempDirTracker } from "../helpers/temp-dir.js"; const tempDirs = useAutoCleanupTempDirTracker(afterEach); -afterEach(() => vi.restoreAllMocks()); +afterEach(() => { + vi.restoreAllMocks(); + vi.unstubAllEnvs(); +}); function git(root: string, ...args: string[]) { return execFileSync( @@ -28,12 +31,13 @@ function source(lines: number) { ); } -function fixture(lines = 5, severity = "warn") { +function fixture(lines = 5, severity = "warn", ignorePatterns: string[] = []) { const root = tempDirs.make("openclaw-line-cap-test-"); fs.mkdirSync(path.join(root, "src")); fs.writeFileSync( path.join(root, ".oxlintrc.json"), JSON.stringify({ + ignorePatterns, overrides: [ { files: ["src/**/*.ts"], @@ -53,6 +57,32 @@ function fixture(lines = 5, severity = "warn") { } describe("line-cap growth ratchet", () => { + it("measures ignored repository-contained scratch while preserving explicit exclusions", () => { + const root = fixture(5, "warn", ["src/ignored/**"]); + fs.writeFileSync(path.join(root, ".gitignore"), ".artifacts/\n"); + const scratch = path.join(root, ".artifacts", "scratch"); + fs.mkdirSync(scratch, { recursive: true }); + vi.stubEnv("TMPDIR", scratch); + vi.stubEnv("TMP", scratch); + vi.stubEnv("TEMP", scratch); + const errors = vi.spyOn(console, "error").mockImplementation(() => {}); + vi.spyOn(console, "log").mockImplementation(() => {}); + const target = path.join(root, "src/file.ts"); + fs.writeFileSync(target, source(6)); + expect(main(root, ["--base", "HEAD"])).toBe(1); + expect(errors).toHaveBeenCalledWith( + expect.stringContaining("src/file.ts: 5 -> 6 counted lines (cap 3)"), + ); + fs.writeFileSync(target, source(4)); + for (const directory of ["ignored", "generated"]) { + fs.mkdirSync(path.join(root, "src", directory)); + fs.writeFileSync(path.join(root, "src", directory, "excluded.ts"), source(8)); + } + errors.mockClear(); + expect(main(root, ["--base", "HEAD"])).toBe(0); + expect(errors).not.toHaveBeenCalled(); + }); + it.each([ { label: "over-cap shrinking", before: 705, after: 703, fails: false }, { label: "over-cap growing", before: 705, after: 706, fails: true },