Skip to content

Commit 216575c

Browse files
committed
feat: enhance build scripts for cross-platform compatibility and improve command execution handling
1 parent dec8d2d commit 216575c

File tree

2 files changed

+96
-48
lines changed

2 files changed

+96
-48
lines changed

scripts/build-native.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This replaces the bash-only prebuildify-wrapper.sh for Windows compatibility
55
*/
66

7-
import { execFileSync } from "node:child_process";
7+
import { execFileSync, execSync } from "node:child_process";
88
import { existsSync, readdirSync, statSync } from "node:fs";
99
import { join } from "node:path";
1010

@@ -55,13 +55,24 @@ console.log("Building native module...");
5555
try {
5656
// Pass through any command line arguments
5757
const args = process.argv.slice(2);
58-
execFileSync(
59-
"npx",
60-
["prebuildify", "--napi", "--tag-libc", "--strip", ...args],
61-
{
62-
stdio: "inherit",
63-
},
64-
);
58+
const prebuildifyArgs = [
59+
"prebuildify",
60+
"--napi",
61+
"--tag-libc",
62+
"--strip",
63+
...args,
64+
];
65+
66+
if (process.platform === "win32") {
67+
// On Windows, npx is actually npx.cmd. execSync uses a shell by default,
68+
// which resolves .cmd files. We build the command string safely since
69+
// these are controlled arguments (not user input).
70+
const cmd = `npx ${prebuildifyArgs.join(" ")}`;
71+
execSync(cmd, { stdio: "inherit" });
72+
} else {
73+
// On Unix, we can use execFileSync directly
74+
execFileSync("npx", prebuildifyArgs, { stdio: "inherit" });
75+
}
6576

6677
// Verify the build succeeded
6778
if (!findValidNativeModule("prebuilds")) {

scripts/precommit.ts

Lines changed: 77 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,107 @@
11
import { execFileSync } from "node:child_process";
22
import { platform } from "node:os";
33

4+
const isWin = platform() === "win32";
45
const isLinux = platform() === "linux";
56
const isMacOS = platform() === "darwin";
67

7-
function run(command: string, description: string) {
8-
console.log(`\n▶ ${description || command}`);
8+
function run({
9+
cmd,
10+
desc,
11+
optional,
12+
}: {
13+
cmd: string;
14+
desc: string;
15+
/** If true, failure is non-fatal and just logs a warning */
16+
optional?: boolean;
17+
}) {
18+
console.log(`\n▶ ${desc || cmd}${optional ? " (optional)" : ""}`);
919
try {
1020
// Use npm to run the commands for better cross-platform compatibility
11-
const [cmd, ...args] = command.split(" ");
12-
execFileSync(cmd, args, { stdio: "inherit", shell: true });
21+
const [arg0, ...args] = cmd.split(" ");
22+
execFileSync(arg0, args, { stdio: "inherit", shell: true });
1323
} catch (error) {
14-
console.error(`✗ Failed`, { description, command, error });
15-
process.exit(1);
24+
if (optional) {
25+
console.log(`⚠ Skipped (command not available)`);
26+
} else {
27+
console.error(`✗ Failed`, { description: desc, command: cmd, error });
28+
process.exit(1);
29+
}
1630
}
1731
}
1832

1933
// Always run these
20-
run("npm install", "Installing dependencies");
21-
run("npm run update:actions", "Updating GitHub Actions");
22-
run(
23-
"npm-check-updates --upgrade --errorLevel 2 || npx snyk test --dev",
24-
"Updating dependencies (security check if updates found)",
25-
);
26-
run("npm install --ignore-scripts=false", "Installing dependencies");
27-
run("npm run clean", "Start fresh");
28-
run("npm run sync:node", "Fetching upstream from Node.js");
29-
run("npm run sync:sqlite", "Fetching upstream from SQLite.org");
30-
run("npm run fmt", "Formatting code");
31-
run("npm run docs", "Generating documentation");
32-
run("npm run lint", "Running TypeScript, eslint, and clang-tidy");
33-
run("npm run security", "Running security checks");
34-
run("npm run build:dist", "Building project");
35-
run(
36-
"npm run build:" + (isLinux ? "linux-glibc" : "native"),
37-
"Building native project for " +
34+
run({ cmd: "npm install", desc: "Installing dependencies" });
35+
run({
36+
cmd: "npm run update:actions",
37+
desc: "Updating GitHub Actions",
38+
optional: isWin,
39+
});
40+
run({
41+
cmd: "npm-check-updates --upgrade --errorLevel 2 || npx snyk test --dev",
42+
desc: "Updating dependencies (security check if updates found)",
43+
});
44+
run({
45+
cmd: "npm install --ignore-scripts=false",
46+
desc: "Installing dependencies",
47+
});
48+
run({ cmd: "npm run clean", desc: "Start fresh" });
49+
run({
50+
cmd: "npm run sync:node",
51+
desc: "Fetching upstream from Node.js",
52+
});
53+
run({
54+
cmd: "npm run sync:sqlite",
55+
desc: "Fetching upstream from SQLite.org",
56+
});
57+
run({ cmd: "npm run fmt", desc: "Formatting code" });
58+
run({ cmd: "npm run docs", desc: "Generating documentation" });
59+
run({
60+
cmd: "npm run lint",
61+
desc: "Running TypeScript, eslint, and clang-tidy",
62+
});
63+
run({ cmd: "npm run security", desc: "Running security checks" });
64+
run({ cmd: "npm run build:dist", desc: "Building project" });
65+
run({
66+
cmd: "npm run build:" + (isLinux ? "linux-glibc" : "native"),
67+
desc:
68+
"Building native project for " +
3869
(isLinux ? "Linux with portable GLIBC" : platform()),
39-
);
40-
run("npm run tests", "Running tests in CJS and ESM mode");
70+
});
71+
run({
72+
cmd: "npm run tests",
73+
desc: "Running tests in CJS and ESM mode",
74+
});
4175

4276
// Check Node.js version for API compatibility tests
4377
const nodeVersion = process.version;
4478
const majorVersion = parseInt(nodeVersion.split(".")[0].substring(1), 10);
4579
if (majorVersion >= 22) {
46-
run(
47-
"npm run lint:api-compat",
48-
"Check API compatibility types (TypeScript compile-time validation)",
49-
);
50-
run(
51-
"npm run test:api-compat",
52-
"Run API type compatibility tests (ensures our TypeScript types match node:sqlite)",
53-
);
54-
run(
55-
"npm run test:node-compat",
56-
"Run behavioral compatibility tests (validates runtime behavior matches node:sqlite)",
57-
);
80+
run({
81+
cmd: "npm run lint:api-compat",
82+
desc: "Check API compatibility types (TypeScript compile-time validation)",
83+
});
84+
run({
85+
cmd: "npm run test:api-compat",
86+
desc: "Run API type compatibility tests (ensures our TypeScript types match node:sqlite)",
87+
});
88+
run({
89+
cmd: "npm run test:node-compat",
90+
desc: "Run behavioral compatibility tests (validates runtime behavior matches node:sqlite)",
91+
});
5892
} else {
5993
console.log("\n⚠ Skipping API compatibility checks (requires Node.js 22+)");
6094
}
6195

6296
// Platform-specific checks
6397
if (isLinux || isMacOS) {
64-
run("npm run lint:native", "Running clang-tidy");
98+
run({ cmd: "npm run lint:native", desc: "Running clang-tidy" });
6599
}
66100

67101
// Run comprehensive memory tests (cross-platform)
68-
run("npm run check:memory", "Comprehensive memory tests");
102+
run({
103+
cmd: "npm run check:memory",
104+
desc: "Comprehensive memory tests",
105+
});
69106

70107
console.log("\n✅ All precommit checks passed!");

0 commit comments

Comments
 (0)