From 95e7af3213a6dfa4dff5c5361a97fa54bfd97c8a Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sun, 12 Apr 2026 05:32:16 +0100 Subject: [PATCH] fix(lint): skip heavy-check lock for explicit oxlint files --- scripts/lib/local-heavy-check-runtime.mjs | 30 ++++++++++++++++ scripts/run-oxlint.mjs | 12 +++++-- .../scripts/local-heavy-check-runtime.test.ts | 34 +++++++++++++++++++ 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/scripts/lib/local-heavy-check-runtime.mjs b/scripts/lib/local-heavy-check-runtime.mjs index 250478a240a..eeed321d057 100644 --- a/scripts/lib/local-heavy-check-runtime.mjs +++ b/scripts/lib/local-heavy-check-runtime.mjs @@ -84,6 +84,36 @@ export function applyLocalOxlintPolicy(args, env, hostResources) { return { env: nextEnv, args: nextArgs }; } +export function shouldAcquireLocalHeavyCheckLockForOxlint( + args, + { cwd = process.cwd(), env = process.env } = {}, +) { + if (env.OPENCLAW_OXLINT_FORCE_LOCK === "1") { + return true; + } + + const separatorIndex = args.indexOf("--"); + const candidateArgs = (() => { + if (separatorIndex !== -1) { + return args.slice(separatorIndex + 1); + } + const firstFlagIndex = args.findIndex((arg) => arg.startsWith("-")); + return firstFlagIndex === -1 ? args : args.slice(0, firstFlagIndex); + })(); + const explicitTargets = candidateArgs.filter((arg) => arg.length > 0 && !arg.startsWith("-")); + if (explicitTargets.length === 0) { + return true; + } + + return !explicitTargets.every((target) => { + try { + return fs.statSync(path.resolve(cwd, target)).isFile(); + } catch { + return false; + } + }); +} + export function shouldThrottleLocalHeavyChecks(env, hostResources) { if (!isLocalCheckEnabled(env)) { return false; diff --git a/scripts/run-oxlint.mjs b/scripts/run-oxlint.mjs index 5a8b3b8e14c..2abe1b39a73 100644 --- a/scripts/run-oxlint.mjs +++ b/scripts/run-oxlint.mjs @@ -3,16 +3,22 @@ import path from "node:path"; import { acquireLocalHeavyCheckLockSync, applyLocalOxlintPolicy, + shouldAcquireLocalHeavyCheckLockForOxlint, } from "./lib/local-heavy-check-runtime.mjs"; const { args: finalArgs, env } = applyLocalOxlintPolicy(process.argv.slice(2), process.env); const oxlintPath = path.resolve("node_modules", ".bin", "oxlint"); -const releaseLock = acquireLocalHeavyCheckLockSync({ +const releaseLock = shouldAcquireLocalHeavyCheckLockForOxlint(finalArgs, { cwd: process.cwd(), env, - toolName: "oxlint", -}); +}) + ? acquireLocalHeavyCheckLockSync({ + cwd: process.cwd(), + env, + toolName: "oxlint", + }) + : () => {}; try { const result = spawnSync(oxlintPath, finalArgs, { diff --git a/test/scripts/local-heavy-check-runtime.test.ts b/test/scripts/local-heavy-check-runtime.test.ts index c23685cb22e..cb655f8cd3c 100644 --- a/test/scripts/local-heavy-check-runtime.test.ts +++ b/test/scripts/local-heavy-check-runtime.test.ts @@ -5,6 +5,7 @@ import { acquireLocalHeavyCheckLockSync, applyLocalOxlintPolicy, applyLocalTsgoPolicy, + shouldAcquireLocalHeavyCheckLockForOxlint, } from "../../scripts/lib/local-heavy-check-runtime.mjs"; import { createScriptTestHarness } from "./test-helpers.js"; @@ -217,6 +218,39 @@ describe("local-heavy-check-runtime", () => { ]); }); + it("skips the heavy-check lock for explicit oxlint file targets", () => { + const cwd = createTempDir("openclaw-oxlint-lock-skip-"); + const target = path.join(cwd, "sample.ts"); + fs.writeFileSync(target, "export const ok = true;\n", "utf8"); + + expect( + shouldAcquireLocalHeavyCheckLockForOxlint(["--type-aware", "--", "sample.ts"], { cwd }), + ).toBe(false); + }); + + it("keeps the heavy-check lock for directory targets and broad oxlint runs", () => { + const cwd = createTempDir("openclaw-oxlint-lock-keep-"); + fs.mkdirSync(path.join(cwd, "src"), { recursive: true }); + fs.writeFileSync(path.join(cwd, "src", "sample.ts"), "export const ok = true;\n", "utf8"); + + expect(shouldAcquireLocalHeavyCheckLockForOxlint(["--type-aware", "--", "src"], { cwd })).toBe( + true, + ); + expect(shouldAcquireLocalHeavyCheckLockForOxlint(["--type-aware"], { cwd })).toBe(true); + }); + + it("allows forcing the oxlint lock back on", () => { + const cwd = createTempDir("openclaw-oxlint-lock-force-"); + fs.writeFileSync(path.join(cwd, "sample.ts"), "export const ok = true;\n", "utf8"); + + expect( + shouldAcquireLocalHeavyCheckLockForOxlint(["--type-aware", "--", "sample.ts"], { + cwd, + env: makeEnv({ OPENCLAW_OXLINT_FORCE_LOCK: "1" }), + }), + ).toBe(true); + }); + it("reclaims stale local heavy-check locks from dead pids", () => { const cwd = createTempDir("openclaw-local-heavy-check-"); const commonDir = path.join(cwd, ".git");