@stll/oxlint-config 1.2.5 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -298,7 +298,9 @@ network_run() (
|
|
|
298
298
|
trap 'exit 143' TERM
|
|
299
299
|
# Output goes to a file, never a pipe: package scripts may leave processes that keep
|
|
300
300
|
# inherited descriptors open, and a pipe reader would wait for them past the command.
|
|
301
|
-
|
|
301
|
+
# Input is never the terminal: timeout runs the command outside the foreground process
|
|
302
|
+
# group, where apt restoring terminal settings on a terminal stdin stops it for good.
|
|
303
|
+
timeout --signal=TERM --kill-after=5s "$seconds"s "$@" < /dev/null > "$network_log" 2>&1 || status=$?
|
|
302
304
|
release_log_holders "$network_log"
|
|
303
305
|
cat -- "$network_log" || fail 'Cannot capture network command output'
|
|
304
306
|
[[ "$status" != 0 ]] || return 0
|
|
@@ -530,16 +532,32 @@ const parseEnvFile = (input) => {
|
|
|
530
532
|
if (envFile.startsWith("/") || /^[A-Za-z]:/.test(envFile) || envFile.includes("\\") || /\p{Cc}/u.test(envFile) || envFile.split("/").some((part) => part === "" || part === "." || part === "..")) throw new Error("cloud.envFile must be a canonical repository-relative path");
|
|
531
533
|
return envFile;
|
|
532
534
|
};
|
|
535
|
+
const cloudPrepareScript = /^[a-z0-9][a-z0-9:._-]*$/;
|
|
536
|
+
const parsePrepare = (input) => {
|
|
537
|
+
if (input === void 0) return void 0;
|
|
538
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) throw new Error("cloud.prepare must be an object");
|
|
539
|
+
for (const key of Object.keys(input)) if (key !== "script" && key !== "seconds") throw new Error(`unsupported cloud.prepare key: ${key}`);
|
|
540
|
+
const script = "script" in input ? input.script : void 0;
|
|
541
|
+
if (typeof script !== "string" || !cloudPrepareScript.test(script)) throw new Error("cloud.prepare.script must name a package script");
|
|
542
|
+
const seconds = "seconds" in input ? input.seconds : void 0;
|
|
543
|
+
if (typeof seconds !== "number" || !Number.isInteger(seconds) || seconds < 1 || seconds > 900) throw new Error(`cloud.prepare.seconds must be an integer from 1 to 900`);
|
|
544
|
+
return {
|
|
545
|
+
script,
|
|
546
|
+
seconds
|
|
547
|
+
};
|
|
548
|
+
};
|
|
533
549
|
/** Parse an explicit declaration without assuming services for undeclared repositories. */
|
|
534
550
|
const parseCloudSetup = (input) => {
|
|
535
551
|
if (input === void 0) return void 0;
|
|
536
552
|
if (typeof input !== "object" || input === null || Array.isArray(input)) throw new Error("cloud must be an object");
|
|
537
|
-
for (const key of Object.keys(input)) if (key !== "services" && key !== "install" && key !== "envFile" && key !== "rust" && key !== "tools") throw new Error(`unsupported cloud key: ${key}`);
|
|
553
|
+
for (const key of Object.keys(input)) if (key !== "services" && key !== "install" && key !== "envFile" && key !== "rust" && key !== "tools" && key !== "prepare") throw new Error(`unsupported cloud key: ${key}`);
|
|
538
554
|
const rust = parseRust("rust" in input ? input.rust : void 0);
|
|
539
555
|
const tools = parseTools("tools" in input ? input.tools : void 0);
|
|
556
|
+
const prepare = parsePrepare("prepare" in input ? input.prepare : void 0);
|
|
540
557
|
const extensions = {
|
|
541
558
|
...rust === void 0 ? {} : { rust },
|
|
542
|
-
...tools === void 0 ? {} : { tools }
|
|
559
|
+
...tools === void 0 ? {} : { tools },
|
|
560
|
+
...prepare === void 0 ? {} : { prepare }
|
|
543
561
|
};
|
|
544
562
|
const selected = "services" in input ? input.services : [];
|
|
545
563
|
if (!Array.isArray(selected)) throw new Error("cloud.services must be an array when provided");
|
|
@@ -594,7 +612,9 @@ service_process_matches() {
|
|
|
594
612
|
owner="$(stat -c '%u' "/proc/$pid" 2>/dev/null)" || return 2
|
|
595
613
|
[[ "$owner" =~ ^[0-9]+$ ]] || return 2
|
|
596
614
|
[[ "$owner" == "$SERVICE_UID" ]] || return 1
|
|
597
|
-
|
|
615
|
+
# Read the executable link as its verified owner: container root may lack the ptrace
|
|
616
|
+
# capability that reading another user's /proc/<pid>/exe requires.
|
|
617
|
+
actual="$(service_run readlink -f "/proc/$pid/exe" 2>/dev/null)" || return 2
|
|
598
618
|
expected="$(readlink -f "$executable")" || return 2
|
|
599
619
|
[[ -n "$actual" && -n "$expected" && "$actual" != *' (deleted)' ]] || return 2
|
|
600
620
|
[[ "$actual" == "$expected" ]]
|
|
@@ -1169,12 +1189,15 @@ process.stdout.write([...hosts].sort().join(","));
|
|
|
1169
1189
|
|
|
1170
1190
|
@ENV_FUNCTIONS@
|
|
1171
1191
|
|
|
1192
|
+
@PREPARE_FUNCTION@
|
|
1193
|
+
|
|
1172
1194
|
if [[ "$MODE" == install ]]; then
|
|
1173
1195
|
step runtimes install_runtimes
|
|
1174
1196
|
step services install_services
|
|
1175
1197
|
step tools install_tools
|
|
1176
1198
|
step shell install_shell_environment
|
|
1177
1199
|
step dependencies dependency_install
|
|
1200
|
+
@PREPARE_STEP@
|
|
1178
1201
|
exit 0
|
|
1179
1202
|
fi
|
|
1180
1203
|
step runtime-check runtime_ready
|
|
@@ -1215,6 +1238,24 @@ write_environment() {
|
|
|
1215
1238
|
}
|
|
1216
1239
|
`;
|
|
1217
1240
|
const shellQuote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
1241
|
+
const renderPrepare = (prepare, files) => {
|
|
1242
|
+
if (prepare === void 0) return "";
|
|
1243
|
+
const manifest = files["package.json"];
|
|
1244
|
+
if (manifest === void 0) throw new Error("cloud.prepare requires a tracked root package.json");
|
|
1245
|
+
const parsed = JSON.parse(manifest);
|
|
1246
|
+
const scripts = typeof parsed === "object" && parsed !== null && "scripts" in parsed ? parsed.scripts : void 0;
|
|
1247
|
+
if (typeof scripts !== "object" || scripts === null || !Object.hasOwn(scripts, prepare.script) || typeof Reflect.get(scripts, prepare.script) !== "string") throw new Error(`cloud.prepare.script ${prepare.script} is not a root package script`);
|
|
1248
|
+
return [
|
|
1249
|
+
"prepare_sources() {",
|
|
1250
|
+
" local leader status=0",
|
|
1251
|
+
` timeout --kill-after=10 ${prepare.seconds} runuser -u "$OUTPUT_USER" -- env HOME="$OUTPUT_HOME" PATH="$PATH" "$BUN_DIR/bun" run ${shellQuote(prepare.script)} </dev/null &`,
|
|
1252
|
+
" leader=$!",
|
|
1253
|
+
" wait \"$leader\" || status=$?",
|
|
1254
|
+
" kill -KILL -- \"-$leader\" 2>/dev/null || true",
|
|
1255
|
+
" return \"$status\"",
|
|
1256
|
+
"}"
|
|
1257
|
+
].join("\n");
|
|
1258
|
+
};
|
|
1218
1259
|
const generateCloudSetup = ({ policy, cloud, nodeVersion, files = {}, rustExceptions = [] }) => {
|
|
1219
1260
|
const selected = parseCloudSetup(cloud);
|
|
1220
1261
|
if (selected === void 0) throw new Error("cloud declaration is required");
|
|
@@ -1251,6 +1292,8 @@ const generateCloudSetup = ({ policy, cloud, nodeVersion, files = {}, rustExcept
|
|
|
1251
1292
|
["@ENV_FUNCTIONS@", selected.envFile === void 0 ? "" : environmentFunctions],
|
|
1252
1293
|
["@ENV_VALIDATE@", selected.envFile === void 0 ? "" : "DATABASE_URL=''\nREDIS_URL=''\nvalidate_environment"],
|
|
1253
1294
|
["@ENV_WRITE@", selected.envFile === void 0 ? "" : "write_environment"],
|
|
1295
|
+
["@PREPARE_FUNCTION@", renderPrepare(selected.prepare, files)],
|
|
1296
|
+
["@PREPARE_STEP@", selected.prepare === void 0 ? "" : " step prepare prepare_sources"],
|
|
1254
1297
|
["@SERVICE_INSTALL@", renderCloudServiceInstall({
|
|
1255
1298
|
services,
|
|
1256
1299
|
postgres: policy.postgres,
|