fatou-cli 0.10.0 → 0.11.1
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.
- package/bin/fatou.js +122 -63
- package/package.json +9 -9
package/bin/fatou.js
CHANGED
|
@@ -1,81 +1,140 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const { execFileSync } = require("node:child_process");
|
|
3
|
+
const { execFileSync, spawnSync } = require("node:child_process");
|
|
4
|
+
|
|
5
|
+
const PACKAGES = {
|
|
6
|
+
"linux-x64-gnu": "@fatou-cli/linux-x64-gnu",
|
|
7
|
+
"linux-arm64-gnu": "@fatou-cli/linux-arm64-gnu",
|
|
8
|
+
"linux-x64-musl": "@fatou-cli/linux-x64-musl",
|
|
9
|
+
"linux-arm64-musl": "@fatou-cli/linux-arm64-musl",
|
|
10
|
+
"darwin-x64": "@fatou-cli/darwin-x64",
|
|
11
|
+
"darwin-arm64": "@fatou-cli/darwin-arm64",
|
|
12
|
+
"win32-x64": "@fatou-cli/win32-x64",
|
|
13
|
+
"win32-arm64": "@fatou-cli/win32-arm64",
|
|
14
|
+
};
|
|
4
15
|
|
|
5
16
|
function detectLibc() {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
17
|
+
if (process.platform !== "linux") return null;
|
|
18
|
+
try {
|
|
19
|
+
const report = process.report.getReport();
|
|
20
|
+
return report.header.glibcVersionRuntime ? "gnu" : "musl";
|
|
21
|
+
} catch {
|
|
22
|
+
return "gnu";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Candidate platform keys in preference order. On linux the other libc
|
|
27
|
+
// flavor is kept as a fallback: a host can report glibc yet be unable to
|
|
28
|
+
// run generic glibc binaries (NixOS has no loader at the standard path),
|
|
29
|
+
// while the musl build is statically linked and runs anywhere.
|
|
30
|
+
function candidateKeys() {
|
|
31
|
+
const { platform, arch } = process;
|
|
32
|
+
const libc = detectLibc();
|
|
33
|
+
if (!libc) return [`${platform}-${arch}`];
|
|
34
|
+
const other = libc === "gnu" ? "musl" : "gnu";
|
|
35
|
+
return [`${platform}-${arch}-${libc}`, `${platform}-${arch}-${other}`];
|
|
13
36
|
}
|
|
14
37
|
|
|
15
|
-
function
|
|
16
|
-
|
|
17
|
-
|
|
38
|
+
function resolveCandidates() {
|
|
39
|
+
const keys = candidateKeys();
|
|
40
|
+
if (!PACKAGES[keys[0]]) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`fatou-cli does not ship a prebuilt binary for ${keys[0]}.\n` +
|
|
43
|
+
`Supported platforms: linux (x64/arm64, gnu+musl), darwin (x64/arm64), win32 (x64/arm64).\n` +
|
|
44
|
+
`See https://github.com/jolars/fatou for alternative install methods.`,
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
const binaryName = process.platform === "win32" ? "fatou.exe" : "fatou";
|
|
48
|
+
const candidates = [];
|
|
49
|
+
let firstError;
|
|
50
|
+
for (const key of keys) {
|
|
51
|
+
try {
|
|
52
|
+
candidates.push(require.resolve(`${PACKAGES[key]}/${binaryName}`));
|
|
53
|
+
} catch (err) {
|
|
54
|
+
firstError = firstError ?? err;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (candidates.length === 0) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`fatou-cli expected the optional dependency ${PACKAGES[keys[0]]} to be installed, ` +
|
|
60
|
+
`but it could not be resolved.\n` +
|
|
61
|
+
`This usually means npm skipped it (e.g. \`--no-optional\` or a registry/network issue ` +
|
|
62
|
+
`during install). Try reinstalling with optional dependencies enabled.\n` +
|
|
63
|
+
`Original error: ${firstError.message}`,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
return candidates;
|
|
67
|
+
}
|
|
18
68
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
69
|
+
function runnable(binary) {
|
|
70
|
+
const probe = spawnSync(binary, ["--version"], { stdio: "ignore" });
|
|
71
|
+
return probe.error == null && probe.status === 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// With a single candidate, trust it: probing every invocation would cost an
|
|
75
|
+
// extra process spawn in the common case. Probing is reserved for the
|
|
76
|
+
// unusual setup where both libc flavors are installed side by side.
|
|
77
|
+
function pickBinary(candidates) {
|
|
78
|
+
if (candidates.length === 1) return candidates[0];
|
|
79
|
+
for (const binary of candidates) {
|
|
80
|
+
if (runnable(binary)) return binary;
|
|
81
|
+
}
|
|
82
|
+
return candidates[0];
|
|
83
|
+
}
|
|
29
84
|
|
|
30
|
-
|
|
31
|
-
|
|
85
|
+
function loaderHint() {
|
|
86
|
+
const libc = detectLibc();
|
|
87
|
+
if (libc !== "gnu") return;
|
|
88
|
+
const muslPackage = PACKAGES[`${process.platform}-${process.arch}-musl`];
|
|
89
|
+
process.stderr.write(
|
|
90
|
+
`The glibc build of fatou cannot run on this system (no standard glibc loader; ` +
|
|
91
|
+
`on NixOS this is expected).\n` +
|
|
92
|
+
`The statically linked musl build works anywhere. Package managers skip it on ` +
|
|
93
|
+
`glibc hosts, so add it explicitly:\n` +
|
|
94
|
+
` npm: npm install --force ${muslPackage}\n` +
|
|
95
|
+
` pnpm: pnpm config set supportedArchitectures.libc '["glibc","musl"]' && pnpm install\n` +
|
|
96
|
+
`Or install fatou via other means; ` +
|
|
97
|
+
`see https://github.com/jolars/fatou.\n`,
|
|
98
|
+
);
|
|
32
99
|
}
|
|
33
100
|
|
|
34
101
|
function resolveBinary() {
|
|
35
|
-
|
|
36
|
-
if (!name) {
|
|
37
|
-
throw new Error(
|
|
38
|
-
`fatou-cli does not ship a prebuilt binary for ${key}.\n` +
|
|
39
|
-
`Supported platforms: linux (x64/arm64, gnu+musl), darwin (x64/arm64), win32 (x64/arm64).\n` +
|
|
40
|
-
`See https://github.com/jolars/fatou for alternative install methods.`,
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
const binaryName = process.platform === "win32" ? "fatou.exe" : "fatou";
|
|
44
|
-
try {
|
|
45
|
-
return require.resolve(`${name}/${binaryName}`);
|
|
46
|
-
} catch (err) {
|
|
47
|
-
throw new Error(
|
|
48
|
-
`fatou-cli expected the optional dependency ${name} to be installed, ` +
|
|
49
|
-
`but it could not be resolved.\n` +
|
|
50
|
-
`This usually means npm skipped it (e.g. \`--no-optional\` or a registry/network issue ` +
|
|
51
|
-
`during install). Try reinstalling with optional dependencies enabled.\n` +
|
|
52
|
-
`Original error: ${err.message}`,
|
|
53
|
-
);
|
|
54
|
-
}
|
|
102
|
+
return pickBinary(resolveCandidates());
|
|
55
103
|
}
|
|
56
104
|
|
|
57
105
|
function main() {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
106
|
+
let binary;
|
|
107
|
+
try {
|
|
108
|
+
binary = resolveBinary();
|
|
109
|
+
} catch (err) {
|
|
110
|
+
process.stderr.write(`${err.message}\n`);
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
65
113
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
114
|
+
try {
|
|
115
|
+
execFileSync(binary, process.argv.slice(2), { stdio: "inherit" });
|
|
116
|
+
} catch (err) {
|
|
117
|
+
if (typeof err.status === "number") {
|
|
118
|
+
// 127 is the loader stub's exit code on hosts that cannot run the
|
|
119
|
+
// glibc build; probe to distinguish that from fatou itself
|
|
120
|
+
// exiting 127 before hinting.
|
|
121
|
+
if (err.status === 127 && !runnable(binary)) {
|
|
122
|
+
loaderHint();
|
|
123
|
+
}
|
|
124
|
+
process.exit(err.status);
|
|
125
|
+
}
|
|
126
|
+
if (err.signal) {
|
|
127
|
+
process.kill(process.pid, err.signal);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
// The binary resolved but could not be spawned; a missing dynamic
|
|
131
|
+
// loader surfaces as ENOENT on hosts without NixOS's stub.
|
|
132
|
+
if (err.code === "ENOENT") {
|
|
133
|
+
loaderHint();
|
|
134
|
+
}
|
|
135
|
+
process.stderr.write(`Failed to execute fatou: ${err.message}\n`);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
79
138
|
}
|
|
80
139
|
|
|
81
140
|
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fatou-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "A language server, formatter, and linter for Julia",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"julia",
|
|
@@ -28,13 +28,13 @@
|
|
|
28
28
|
"node": ">=20"
|
|
29
29
|
},
|
|
30
30
|
"optionalDependencies": {
|
|
31
|
-
"@fatou-cli/linux-x64-gnu": "0.
|
|
32
|
-
"@fatou-cli/linux-arm64-gnu": "0.
|
|
33
|
-
"@fatou-cli/linux-x64-musl": "0.
|
|
34
|
-
"@fatou-cli/linux-arm64-musl": "0.
|
|
35
|
-
"@fatou-cli/darwin-x64": "0.
|
|
36
|
-
"@fatou-cli/darwin-arm64": "0.
|
|
37
|
-
"@fatou-cli/win32-x64": "0.
|
|
38
|
-
"@fatou-cli/win32-arm64": "0.
|
|
31
|
+
"@fatou-cli/linux-x64-gnu": "0.11.1",
|
|
32
|
+
"@fatou-cli/linux-arm64-gnu": "0.11.1",
|
|
33
|
+
"@fatou-cli/linux-x64-musl": "0.11.1",
|
|
34
|
+
"@fatou-cli/linux-arm64-musl": "0.11.1",
|
|
35
|
+
"@fatou-cli/darwin-x64": "0.11.1",
|
|
36
|
+
"@fatou-cli/darwin-arm64": "0.11.1",
|
|
37
|
+
"@fatou-cli/win32-x64": "0.11.1",
|
|
38
|
+
"@fatou-cli/win32-arm64": "0.11.1"
|
|
39
39
|
}
|
|
40
40
|
}
|