mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(lint): reject malformed oxlint shard env
This commit is contained in:
@@ -102,15 +102,11 @@ export function createWindowsExtensionShards({
|
||||
}
|
||||
|
||||
export function resolveWindowsExtensionChunkSize(env = process.env) {
|
||||
const rawValue = env.OPENCLAW_OXLINT_WINDOWS_EXTENSION_CHUNK_SIZE;
|
||||
if (rawValue === undefined) {
|
||||
return DEFAULT_WINDOWS_EXTENSION_CHUNK_SIZE;
|
||||
}
|
||||
|
||||
const parsedValue = Number.parseInt(rawValue, 10);
|
||||
return Number.isFinite(parsedValue) && parsedValue > 0
|
||||
? parsedValue
|
||||
: DEFAULT_WINDOWS_EXTENSION_CHUNK_SIZE;
|
||||
return resolvePositiveEnvIntWithFallback(
|
||||
env,
|
||||
"OPENCLAW_OXLINT_WINDOWS_EXTENSION_CHUNK_SIZE",
|
||||
DEFAULT_WINDOWS_EXTENSION_CHUNK_SIZE,
|
||||
);
|
||||
}
|
||||
|
||||
export function shouldRunOxlintShardsSerial({
|
||||
@@ -505,22 +501,49 @@ export function resolveShardKillGraceMs(env) {
|
||||
|
||||
function resolveNonNegativeEnvInt(env, key, defaultValue) {
|
||||
const rawValue = env[key];
|
||||
if (rawValue === undefined) {
|
||||
if (rawValue === undefined || rawValue === "") {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
const parsedValue = Number.parseInt(rawValue, 10);
|
||||
return Number.isFinite(parsedValue) && parsedValue >= 0 ? parsedValue : defaultValue;
|
||||
const text = String(rawValue).trim();
|
||||
if (!/^\d+$/u.test(text)) {
|
||||
throw new Error(`${key} must be a non-negative integer; got: ${rawValue}`);
|
||||
}
|
||||
const parsedValue = Number(text);
|
||||
if (!Number.isSafeInteger(parsedValue)) {
|
||||
throw new Error(`${key} must be a non-negative integer; got: ${rawValue}`);
|
||||
}
|
||||
return parsedValue;
|
||||
}
|
||||
|
||||
function resolvePositiveEnvInt(env, key) {
|
||||
const rawValue = env[key];
|
||||
if (rawValue === undefined) {
|
||||
if (rawValue === undefined || rawValue === "") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const parsedValue = Number.parseInt(rawValue, 10);
|
||||
return Number.isFinite(parsedValue) && parsedValue > 0 ? parsedValue : null;
|
||||
return parsePositiveEnvInt(rawValue, key);
|
||||
}
|
||||
|
||||
function resolvePositiveEnvIntWithFallback(env, key, defaultValue) {
|
||||
const rawValue = env[key];
|
||||
if (rawValue === undefined || rawValue === "") {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return parsePositiveEnvInt(rawValue, key);
|
||||
}
|
||||
|
||||
function parsePositiveEnvInt(rawValue, key) {
|
||||
const text = String(rawValue).trim();
|
||||
if (!/^\d+$/u.test(text)) {
|
||||
throw new Error(`${key} must be a positive integer; got: ${rawValue}`);
|
||||
}
|
||||
const parsedValue = Number(text);
|
||||
if (!Number.isSafeInteger(parsedValue) || parsedValue <= 0) {
|
||||
throw new Error(`${key} must be a positive integer; got: ${rawValue}`);
|
||||
}
|
||||
return parsedValue;
|
||||
}
|
||||
|
||||
function signalChildProcess({ child, signal, useProcessGroup }) {
|
||||
|
||||
@@ -197,22 +197,38 @@ describe("run-oxlint", () => {
|
||||
splitCore: true,
|
||||
}),
|
||||
).toBe(2);
|
||||
|
||||
expect(() =>
|
||||
resolveOxlintShardConcurrency({
|
||||
env: { CI: "true", OPENCLAW_OXLINT_SHARD_CONCURRENCY: "2x" },
|
||||
platform: "linux",
|
||||
hostResources: roomyHost,
|
||||
splitCore: true,
|
||||
}),
|
||||
).toThrow("OPENCLAW_OXLINT_SHARD_CONCURRENCY must be a positive integer; got: 2x");
|
||||
});
|
||||
|
||||
it("uses a bounded oxlint shard heartbeat by default", () => {
|
||||
expect(resolveShardHeartbeatMs({})).toBe(30_000);
|
||||
expect(resolveShardHeartbeatMs({ OPENCLAW_OXLINT_SHARD_HEARTBEAT_MS: "0" })).toBe(0);
|
||||
expect(resolveShardHeartbeatMs({ OPENCLAW_OXLINT_SHARD_HEARTBEAT_MS: "5000" })).toBe(5000);
|
||||
expect(resolveShardHeartbeatMs({ OPENCLAW_OXLINT_SHARD_HEARTBEAT_MS: "bad" })).toBe(30_000);
|
||||
expect(() => resolveShardHeartbeatMs({ OPENCLAW_OXLINT_SHARD_HEARTBEAT_MS: "5000ms" })).toThrow(
|
||||
"OPENCLAW_OXLINT_SHARD_HEARTBEAT_MS must be a non-negative integer; got: 5000ms",
|
||||
);
|
||||
});
|
||||
|
||||
it("uses a bounded oxlint shard timeout by default", () => {
|
||||
expect(resolveShardTimeoutMs({})).toBe(900_000);
|
||||
expect(resolveShardTimeoutMs({ OPENCLAW_OXLINT_SHARD_TIMEOUT_MS: "0" })).toBe(0);
|
||||
expect(resolveShardTimeoutMs({ OPENCLAW_OXLINT_SHARD_TIMEOUT_MS: "5000" })).toBe(5000);
|
||||
expect(resolveShardTimeoutMs({ OPENCLAW_OXLINT_SHARD_TIMEOUT_MS: "bad" })).toBe(900_000);
|
||||
expect(() => resolveShardTimeoutMs({ OPENCLAW_OXLINT_SHARD_TIMEOUT_MS: "1e3" })).toThrow(
|
||||
"OPENCLAW_OXLINT_SHARD_TIMEOUT_MS must be a non-negative integer; got: 1e3",
|
||||
);
|
||||
expect(resolveShardKillGraceMs({})).toBe(5_000);
|
||||
expect(resolveShardKillGraceMs({ OPENCLAW_OXLINT_SHARD_KILL_GRACE_MS: "0" })).toBe(0);
|
||||
expect(() => resolveShardKillGraceMs({ OPENCLAW_OXLINT_SHARD_KILL_GRACE_MS: "-1" })).toThrow(
|
||||
"OPENCLAW_OXLINT_SHARD_KILL_GRACE_MS must be a non-negative integer; got: -1",
|
||||
);
|
||||
});
|
||||
|
||||
it("fails a stuck oxlint shard instead of waiting forever", async () => {
|
||||
@@ -518,14 +534,19 @@ describe("run-oxlint", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("keeps the default Windows oxlint extension chunk size for invalid overrides", () => {
|
||||
it("rejects invalid Windows oxlint extension chunk size overrides", () => {
|
||||
expect(resolveWindowsExtensionChunkSize({})).toBe(8);
|
||||
expect(
|
||||
resolveWindowsExtensionChunkSize({ OPENCLAW_OXLINT_WINDOWS_EXTENSION_CHUNK_SIZE: "0" }),
|
||||
).toBe(8);
|
||||
() => resolveWindowsExtensionChunkSize({ OPENCLAW_OXLINT_WINDOWS_EXTENSION_CHUNK_SIZE: "0" }),
|
||||
).toThrow("OPENCLAW_OXLINT_WINDOWS_EXTENSION_CHUNK_SIZE must be a positive integer; got: 0");
|
||||
expect(
|
||||
resolveWindowsExtensionChunkSize({ OPENCLAW_OXLINT_WINDOWS_EXTENSION_CHUNK_SIZE: "abc" }),
|
||||
).toBe(8);
|
||||
() =>
|
||||
resolveWindowsExtensionChunkSize({
|
||||
OPENCLAW_OXLINT_WINDOWS_EXTENSION_CHUNK_SIZE: "8 chunks",
|
||||
}),
|
||||
).toThrow(
|
||||
"OPENCLAW_OXLINT_WINDOWS_EXTENSION_CHUNK_SIZE must be a positive integer; got: 8 chunks",
|
||||
);
|
||||
});
|
||||
|
||||
it("filters tracked targets missing from sparse checkouts", () => {
|
||||
|
||||
Reference in New Issue
Block a user