mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
fix(lint): shard core lint checks
This commit is contained in:
@@ -1486,7 +1486,7 @@
|
||||
"lint:apps": "pnpm lint:swift",
|
||||
"lint:auth:no-pairing-store-group": "node scripts/check-no-pairing-store-group-auth.mjs",
|
||||
"lint:auth:pairing-account-scope": "node scripts/check-pairing-account-scope.mjs",
|
||||
"lint:core": "node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.core.json src ui packages",
|
||||
"lint:core": "node scripts/run-oxlint-shards.mjs --only=core --split-core",
|
||||
"lint:docker-e2e": "node scripts/check-docker-e2e-boundaries.mjs",
|
||||
"lint:docs": "pnpm dlx --config.resolution-mode=highest markdownlint-cli2 --config config/markdownlint-cli2.jsonc",
|
||||
"lint:docs:fix": "pnpm dlx --config.resolution-mode=highest markdownlint-cli2 --config config/markdownlint-cli2.jsonc --fix",
|
||||
|
||||
@@ -19,6 +19,7 @@ const CORE_SHARD = {
|
||||
name: "core",
|
||||
args: ["--tsconfig", "config/tsconfig/oxlint.core.json", "src", "ui", "packages"],
|
||||
};
|
||||
const CORE_SPLIT_TARGETS = ["src", "ui", "packages"];
|
||||
const EXTENSIONS_SHARD = {
|
||||
name: "extensions",
|
||||
args: ["--tsconfig", EXTENSION_TS_CONFIG, EXTENSIONS_DIR],
|
||||
@@ -33,11 +34,20 @@ export function createOxlintShards({
|
||||
env = process.env,
|
||||
platform = process.platform,
|
||||
readDir = fs.readdirSync,
|
||||
splitCore = false,
|
||||
} = {}) {
|
||||
const coreShards = splitCore ? createCoreOxlintShards() : [CORE_SHARD];
|
||||
const extensionShards =
|
||||
platform === "win32" ? createWindowsExtensionShards({ cwd, env, readDir }) : [EXTENSIONS_SHARD];
|
||||
|
||||
return [CORE_SHARD, ...extensionShards, SCRIPTS_SHARD];
|
||||
return [...coreShards, ...extensionShards, SCRIPTS_SHARD];
|
||||
}
|
||||
|
||||
export function createCoreOxlintShards() {
|
||||
return CORE_SPLIT_TARGETS.map((target) => ({
|
||||
name: `core:${target}`,
|
||||
args: ["--tsconfig", "config/tsconfig/oxlint.core.json", target],
|
||||
}));
|
||||
}
|
||||
|
||||
export function createWindowsExtensionShards({
|
||||
@@ -143,13 +153,14 @@ function listExtensionEntries({ cwd, readDir }) {
|
||||
|
||||
export async function main(extraArgs = process.argv.slice(2), runtimeEnv = process.env) {
|
||||
const runner = path.resolve("scripts", "run-oxlint.mjs");
|
||||
const shardArgs = parseShardRunnerArgs(extraArgs);
|
||||
const env = resolveLocalHeavyCheckEnv(runtimeEnv);
|
||||
const hasMetadataOnlyFlag = extraArgs.some((arg) =>
|
||||
const hasMetadataOnlyFlag = shardArgs.oxlintArgs.some((arg) =>
|
||||
["--help", "-h", "--version", "-V", "--rules", "--print-config", "--init"].includes(arg),
|
||||
);
|
||||
const shouldAcquireParentLock =
|
||||
!hasMetadataOnlyFlag ||
|
||||
shouldAcquireLocalHeavyCheckLockForOxlint(extraArgs, {
|
||||
shouldAcquireLocalHeavyCheckLockForOxlint(shardArgs.oxlintArgs, {
|
||||
cwd: process.cwd(),
|
||||
env,
|
||||
});
|
||||
@@ -168,7 +179,9 @@ export async function main(extraArgs = process.argv.slice(2), runtimeEnv = proce
|
||||
cwd: process.cwd(),
|
||||
env,
|
||||
platform: process.platform,
|
||||
splitCore: shardArgs.splitCore,
|
||||
});
|
||||
const selectedShards = filterOxlintShards(shards, shardArgs.only);
|
||||
|
||||
try {
|
||||
const prepareResult = spawnSync(
|
||||
@@ -186,13 +199,24 @@ export async function main(extraArgs = process.argv.slice(2), runtimeEnv = proce
|
||||
if ((prepareResult.status ?? 1) !== 0) {
|
||||
process.exitCode = prepareResult.status ?? 1;
|
||||
} else {
|
||||
const runSerial = shouldRunOxlintShardsSerial({
|
||||
env,
|
||||
platform: process.platform,
|
||||
});
|
||||
const runSerial =
|
||||
shardArgs.splitCore ||
|
||||
shouldRunOxlintShardsSerial({
|
||||
env,
|
||||
platform: process.platform,
|
||||
});
|
||||
const results = runSerial
|
||||
? await runShardsSerial({ entries: shards, env, extraArgs, runner })
|
||||
: await Promise.all(shards.map((shard) => runShard({ env, extraArgs, runner, shard })));
|
||||
? await runShardsSerial({
|
||||
entries: selectedShards,
|
||||
env,
|
||||
extraArgs: shardArgs.oxlintArgs,
|
||||
runner,
|
||||
})
|
||||
: await Promise.all(
|
||||
selectedShards.map((shard) =>
|
||||
runShard({ env, extraArgs: shardArgs.oxlintArgs, runner, shard }),
|
||||
),
|
||||
);
|
||||
process.exitCode = results.find((status) => status !== 0) ?? 0;
|
||||
}
|
||||
} finally {
|
||||
@@ -216,6 +240,46 @@ function resolveHostResources(hostResources) {
|
||||
};
|
||||
}
|
||||
|
||||
export function parseShardRunnerArgs(args) {
|
||||
const only = new Set();
|
||||
const oxlintArgs = [];
|
||||
let splitCore = false;
|
||||
|
||||
for (let index = 0; index < args.length; index += 1) {
|
||||
const arg = args[index];
|
||||
if (arg === "--split-core") {
|
||||
splitCore = true;
|
||||
continue;
|
||||
}
|
||||
if (arg === "--only") {
|
||||
const value = args[index + 1];
|
||||
if (value) {
|
||||
only.add(value);
|
||||
index += 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (arg.startsWith("--only=")) {
|
||||
const value = arg.slice("--only=".length);
|
||||
if (value) {
|
||||
only.add(value);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
oxlintArgs.push(arg);
|
||||
}
|
||||
|
||||
return { only, oxlintArgs, splitCore };
|
||||
}
|
||||
|
||||
export function filterOxlintShards(shards, only) {
|
||||
if (only.size === 0) {
|
||||
return shards;
|
||||
}
|
||||
|
||||
return shards.filter((shard) => only.has(shard.name) || only.has(shard.name.split(":")[0]));
|
||||
}
|
||||
|
||||
async function runShardsSerial({ entries, env, extraArgs, runner }) {
|
||||
const results = [];
|
||||
for (const shard of entries) {
|
||||
|
||||
@@ -2,6 +2,8 @@ import { readFileSync } from "node:fs";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
createOxlintShards,
|
||||
filterOxlintShards,
|
||||
parseShardRunnerArgs,
|
||||
createWindowsExtensionShards,
|
||||
resolveWindowsExtensionChunkSize,
|
||||
shouldRunOxlintShardsSerial,
|
||||
@@ -33,6 +35,9 @@ describe("run-oxlint", () => {
|
||||
|
||||
expect(packageJson.scripts.check).toBe("node scripts/check.mjs");
|
||||
expect(packageJson.scripts.lint).toBe("node scripts/run-oxlint-shards.mjs");
|
||||
expect(packageJson.scripts["lint:core"]).toBe(
|
||||
"node scripts/run-oxlint-shards.mjs --only=core --split-core",
|
||||
);
|
||||
expect(packageJson.scripts.check).not.toContain(
|
||||
"node scripts/prepare-extension-package-boundary-artifacts.mjs",
|
||||
);
|
||||
@@ -168,6 +173,42 @@ describe("run-oxlint", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("splits core oxlint shards when requested", () => {
|
||||
expect(createOxlintShards({ splitCore: true }).slice(0, 3)).toEqual([
|
||||
{
|
||||
name: "core:src",
|
||||
args: ["--tsconfig", "config/tsconfig/oxlint.core.json", "src"],
|
||||
},
|
||||
{
|
||||
name: "core:ui",
|
||||
args: ["--tsconfig", "config/tsconfig/oxlint.core.json", "ui"],
|
||||
},
|
||||
{
|
||||
name: "core:packages",
|
||||
args: ["--tsconfig", "config/tsconfig/oxlint.core.json", "packages"],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("parses shard runner flags without forwarding them to oxlint", () => {
|
||||
const parsed = parseShardRunnerArgs([
|
||||
"--only=core",
|
||||
"--split-core",
|
||||
"--max-warnings",
|
||||
"0",
|
||||
]);
|
||||
|
||||
expect([...parsed.only]).toEqual(["core"]);
|
||||
expect(parsed.splitCore).toBe(true);
|
||||
expect(parsed.oxlintArgs).toEqual(["--max-warnings", "0"]);
|
||||
});
|
||||
|
||||
it("filters split core shards by shard family", () => {
|
||||
const shards = filterOxlintShards(createOxlintShards({ splitCore: true }), new Set(["core"]));
|
||||
|
||||
expect(shards.map((shard) => shard.name)).toEqual(["core:src", "core:ui", "core:packages"]);
|
||||
});
|
||||
|
||||
it("falls back to the full extension shard when Windows extension dirs are unavailable", () => {
|
||||
const shards = createWindowsExtensionShards({
|
||||
cwd: "/repo",
|
||||
|
||||
Reference in New Issue
Block a user