fulmine.js 5.19.9 → 5.20.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.
- package/README.md +115 -985
- package/package.json +16 -4
- package/src/adopt.js +116 -5
- package/src/application.js +3 -0
- package/src/cli.js +22 -2
- package/src/create.js +248 -0
- package/src/index.js +22 -0
- package/src/verify.js +108 -7
package/src/verify.js
CHANGED
|
@@ -29,6 +29,7 @@ limitations under the License.
|
|
|
29
29
|
|
|
30
30
|
const fs = require("fs");
|
|
31
31
|
const path = require("path");
|
|
32
|
+
const { detectManager, UWS_SPEC, UWS_OVERRIDE } = require("./adopt.js");
|
|
32
33
|
|
|
33
34
|
// The oldest glibc the pinned uWS binaries are built against. A runtime older than this loads the
|
|
34
35
|
// file and then fails on a symbol, which is a worse error than not finding it at all.
|
|
@@ -251,6 +252,20 @@ function checkDockerfiles(dir) {
|
|
|
251
252
|
return results;
|
|
252
253
|
}
|
|
253
254
|
|
|
255
|
+
/**
|
|
256
|
+
* The project's package.json, or nothing where there is none to read.
|
|
257
|
+
*
|
|
258
|
+
* @param {string} dir
|
|
259
|
+
* @returns {any}
|
|
260
|
+
*/
|
|
261
|
+
function readPackage(dir) {
|
|
262
|
+
try {
|
|
263
|
+
return JSON.parse(fs.readFileSync(path.join(dir, "package.json"), "utf8"));
|
|
264
|
+
} catch {
|
|
265
|
+
return undefined;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
254
269
|
/**
|
|
255
270
|
* The dependencies that need a different API here. Read from package.json rather than from
|
|
256
271
|
* node_modules, so a project is answered before it installs anything.
|
|
@@ -261,12 +276,8 @@ function checkDockerfiles(dir) {
|
|
|
261
276
|
function checkDependencies(dir) {
|
|
262
277
|
/** @type {ReturnType<typeof result>[]} */
|
|
263
278
|
const results = [];
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
pkg = JSON.parse(fs.readFileSync(path.join(dir, "package.json"), "utf8"));
|
|
267
|
-
} catch {
|
|
268
|
-
return results;
|
|
269
|
-
}
|
|
279
|
+
const pkg = readPackage(dir);
|
|
280
|
+
if (!pkg) return results;
|
|
270
281
|
const installed = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
271
282
|
for (const name of Object.keys(NEEDS_A_LOOK)) {
|
|
272
283
|
if (installed[name]) {
|
|
@@ -276,6 +287,83 @@ function checkDependencies(dir) {
|
|
|
276
287
|
return results;
|
|
277
288
|
}
|
|
278
289
|
|
|
290
|
+
// pnpm refuses a git dependency of a dependency since this version, and µWebSockets.js is one
|
|
291
|
+
const PNPM_BLOCKS_GIT_SUBDEPS = [10, 26];
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Whether the package manager will install this at all. pnpm 10.26 and later refuse a dependency
|
|
295
|
+
* of a dependency that comes from git, which µWebSockets.js does, so `pnpm add fulmine.js` fails
|
|
296
|
+
* before anything runs. What lets it through is readable from the project: the two lines
|
|
297
|
+
* `npx fulmine.js pnpm` writes, the setting turned off, or an override taking µWebSockets.js from
|
|
298
|
+
* a registry. pnpm 11 reads its settings from pnpm-workspace.yaml only, so that is what is read.
|
|
299
|
+
*
|
|
300
|
+
* @param {string} dir
|
|
301
|
+
* @param {any} pkg the parsed package.json
|
|
302
|
+
* @returns {ReturnType<typeof result>|undefined} nothing to say for npm and yarn
|
|
303
|
+
*/
|
|
304
|
+
function checkPackageManager(dir, pkg) {
|
|
305
|
+
const { manager, why } = detectManager(dir, pkg);
|
|
306
|
+
if (manager !== "pnpm") return undefined;
|
|
307
|
+
|
|
308
|
+
const declared = /^pnpm@(\d+)\.(\d+)/.exec(pkg.packageManager ?? "");
|
|
309
|
+
if (declared) {
|
|
310
|
+
const [major, minor] = [Number(declared[1]), Number(declared[2])];
|
|
311
|
+
const [blockMajor, blockMinor] = PNPM_BLOCKS_GIT_SUBDEPS;
|
|
312
|
+
if (major < blockMajor || (major === blockMajor && minor < blockMinor)) {
|
|
313
|
+
return result("ok", `pnpm ${declared[1]}.${declared[2]} installs a git dependency of a dependency`);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
let workspace = "";
|
|
318
|
+
try {
|
|
319
|
+
workspace = fs.readFileSync(path.join(dir, "pnpm-workspace.yaml"), "utf8");
|
|
320
|
+
} catch {
|
|
321
|
+
// no workspace file, so every setting is at its default
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// the recipe: the project owns the git dependency, and the copy this package asks for is dropped
|
|
325
|
+
const dropped = new RegExp(`^\\s*["']?${UWS_OVERRIDE.replace(/\./g, "\\.")}["']?:\\s*["']?-["']?\\s*$`, "m").test(
|
|
326
|
+
workspace
|
|
327
|
+
);
|
|
328
|
+
const own = pkg.dependencies?.["uWebSockets.js"];
|
|
329
|
+
if (dropped && typeof own === "string") {
|
|
330
|
+
if (own === UWS_SPEC) {
|
|
331
|
+
return result(
|
|
332
|
+
"ok",
|
|
333
|
+
"pnpm, with µWebSockets.js as the project's own dependency at the pin this package uses"
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
return result(
|
|
337
|
+
"note",
|
|
338
|
+
`pnpm, with µWebSockets.js as the project's own dependency at ${own}`,
|
|
339
|
+
`this package pins ${UWS_SPEC} and was tested against it. \`npx fulmine.js pnpm\` writes the pin.`
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
if (dropped) {
|
|
343
|
+
return result(
|
|
344
|
+
"no",
|
|
345
|
+
"pnpm-workspace.yaml drops µWebSockets.js from this package, and the project does not declare it",
|
|
346
|
+
`nothing would install it. \`npx fulmine.js pnpm\` adds "uWebSockets.js": "${UWS_SPEC}" to dependencies.`
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (/^\s*blockExoticSubdeps:\s*false\s*$/m.test(workspace)) {
|
|
351
|
+
return result("ok", "pnpm, with blockExoticSubdeps off in pnpm-workspace.yaml");
|
|
352
|
+
}
|
|
353
|
+
const registry = /^\s*["']?uWebSockets\.js["']?:\s*["']?([~^]?\d[^"'\s]*)/m.exec(workspace);
|
|
354
|
+
if (registry) {
|
|
355
|
+
return result("ok", `pnpm, with µWebSockets.js overridden to ${registry[1]} from a registry`);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return result(
|
|
359
|
+
"no",
|
|
360
|
+
`pnpm (${why}) will refuse to install this`,
|
|
361
|
+
"pnpm 10.26 and later block a git dependency of a dependency, and µWebSockets.js is one:\n" +
|
|
362
|
+
" pnpm add fulmine.js fails with ERR_PNPM_EXOTIC_SUBDEP. `npx fulmine.js pnpm` writes the two\n" +
|
|
363
|
+
" lines that let it through, see docs/deployment.md."
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
|
|
279
367
|
/**
|
|
280
368
|
* Runs every check and prints the report. Anything that would stop the application from starting
|
|
281
369
|
* is a failure and the command exits non-zero, so it can be a step in a pipeline.
|
|
@@ -292,6 +380,10 @@ function verify(argv) {
|
|
|
292
380
|
results.push(libc);
|
|
293
381
|
}
|
|
294
382
|
results.push(checkBinary(), ...checkDockerfiles(dir), ...checkDependencies(dir));
|
|
383
|
+
const manager = checkPackageManager(dir, readPackage(dir) ?? {});
|
|
384
|
+
if (manager) {
|
|
385
|
+
results.push(manager);
|
|
386
|
+
}
|
|
295
387
|
|
|
296
388
|
console.log(`\nWhether this machine and this project can run fulmine.js\n`);
|
|
297
389
|
const label = { ok: "ok ", note: "note", no: "NO " };
|
|
@@ -312,4 +404,13 @@ function verify(argv) {
|
|
|
312
404
|
return blocking === 0 ? 0 : 1;
|
|
313
405
|
}
|
|
314
406
|
|
|
315
|
-
module.exports = {
|
|
407
|
+
module.exports = {
|
|
408
|
+
verify,
|
|
409
|
+
checkNode,
|
|
410
|
+
checkLibc,
|
|
411
|
+
currentGlibc,
|
|
412
|
+
checkBinary,
|
|
413
|
+
checkDockerfiles,
|
|
414
|
+
checkDependencies,
|
|
415
|
+
checkPackageManager
|
|
416
|
+
};
|