@gjsify/cli 0.17.0 → 0.18.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/dist/cli.gjs.mjs +150 -150
- package/lib/cli-app.js +4 -4
- package/lib/commands/check.js +2 -13
- package/lib/commands/install.js +2 -4
- package/lib/index.js +2 -2
- package/lib/utils/detect-native-packages.js +2 -10
- package/lib/utils/node-version.js +2 -2
- package/lib/utils/oxc-resolve.js +2 -4
- package/lib/utils/pkg-json-edit.d.ts +2 -0
- package/lib/utils/pkg-json.d.ts +6 -0
- package/lib/utils/pkg-json.js +24 -0
- package/lib/utils/run-gjs.js +15 -2
- package/lib/utils/workspace-root.js +2 -9
- package/package.json +17 -17
package/lib/cli-app.js
CHANGED
|
@@ -21,7 +21,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
21
21
|
import yargs from 'yargs';
|
|
22
22
|
import { buildCommand as build, testCommand as test, runCommand as run, infoCommand as info, systemCheckCommand as systemCheck, checkCommand as check, showcaseCommand as showcase, createCommand as create, gresourceCommand as gresource, gettextCommand as gettext, gsettingsCommand as gsettings, flatpakCommand as flatpak, dlxCommand as dlx, installCommand as install, foreachCommand as foreach, workspaceCommand as workspace, packCommand as pack, publishCommand as publish, whoamiCommand as whoami, loginCommand as login, logoutCommand as logout, trustCommand as trust, onboardCommand as onboard, selfUpdateCommand as selfUpdate, generateInstallerCommand as generateInstaller, uninstallCommand as uninstall, formatCommand as format, lintCommand as lint, fixCommand as fix, upgradeCommand as upgrade, barrelsCommand as barrels, tscCommand as tsc, affectedCommand as affected, storybookCommand as storybook, debugCommand as debug, browseCommand as browse, } from './commands/index.js';
|
|
23
23
|
import { APP_NAME } from './constants.js';
|
|
24
|
-
import { isNode } from '@gjsify/rolldown-plugin-gjsify/runtime';
|
|
24
|
+
import { isNode, gjsSystemVersion } from '@gjsify/rolldown-plugin-gjsify/runtime';
|
|
25
25
|
import { ensureGjsifyShimOnPath } from './utils/gjsify-shim.js';
|
|
26
26
|
// Detect which runtime is executing the CLI (GJS or Node.js).
|
|
27
27
|
// GJS MUST be checked first because @gjsify/process sets
|
|
@@ -29,9 +29,9 @@ import { ensureGjsifyShimOnPath } from './utils/gjsify-shim.js';
|
|
|
29
29
|
// `process.versions.node` check would be a false Node positive under GJS.
|
|
30
30
|
function runtimeLabel() {
|
|
31
31
|
try {
|
|
32
|
-
const
|
|
33
|
-
if (
|
|
34
|
-
const v = Number(
|
|
32
|
+
const sysVersion = gjsSystemVersion();
|
|
33
|
+
if (sysVersion !== undefined) {
|
|
34
|
+
const v = Number(sysVersion);
|
|
35
35
|
return `GJS ${Math.floor(v / 10000)}.${Math.floor((v % 10000) / 100)}.${v % 100} (SpiderMonkey)`;
|
|
36
36
|
}
|
|
37
37
|
}
|
package/lib/commands/check.js
CHANGED
|
@@ -16,22 +16,11 @@
|
|
|
16
16
|
// (since the typescript-check binding is positional `[paths..]`).
|
|
17
17
|
import { spawn, spawnSync } from 'node:child_process';
|
|
18
18
|
import { prefixLines } from '../utils/prefixed-output.js';
|
|
19
|
-
import {
|
|
19
|
+
import { readPackageJson } from '../utils/pkg-json.js';
|
|
20
20
|
import { join } from 'node:path';
|
|
21
21
|
import { cpus } from 'node:os';
|
|
22
22
|
import { discoverWorkspaces, filterWorkspaces } from '@gjsify/workspace';
|
|
23
23
|
import { findWorkspaceRoot } from '../utils/workspace-root.js';
|
|
24
|
-
function readPackageJson(dir) {
|
|
25
|
-
const path = join(dir, 'package.json');
|
|
26
|
-
if (!existsSync(path))
|
|
27
|
-
return null;
|
|
28
|
-
try {
|
|
29
|
-
return JSON.parse(readFileSync(path, 'utf-8'));
|
|
30
|
-
}
|
|
31
|
-
catch {
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
24
|
/**
|
|
36
25
|
* Run a single workspace's `check` script. Returns the exit code; non-zero
|
|
37
26
|
* indicates failure. Output is forwarded to the parent's stdout/stderr,
|
|
@@ -108,7 +97,7 @@ export const checkCommand = {
|
|
|
108
97
|
// through gjsify so the command surface stays uniform with format/
|
|
109
98
|
// lint/fix.
|
|
110
99
|
if (workspaceRoot && cwd !== workspaceRoot) {
|
|
111
|
-
const pkg = readPackageJson(cwd);
|
|
100
|
+
const pkg = readPackageJson(join(cwd, 'package.json'));
|
|
112
101
|
if (pkg?.scripts?.check) {
|
|
113
102
|
if (args.verbose) {
|
|
114
103
|
console.log(`[check] cwd=${cwd} → npm run check`);
|
package/lib/commands/install.js
CHANGED
|
@@ -31,6 +31,7 @@ import { chmodSync, existsSync, lstatSync, mkdirSync, readFileSync, rmSync, syml
|
|
|
31
31
|
import { dirname, join, relative, resolve } from 'node:path';
|
|
32
32
|
import { fileURLToPath } from 'node:url';
|
|
33
33
|
import { spawn, spawnSync } from 'node:child_process';
|
|
34
|
+
import { gjsExit } from '@gjsify/rolldown-plugin-gjsify/runtime';
|
|
34
35
|
import { discoverWorkspaces } from '@gjsify/workspace';
|
|
35
36
|
import { buildInstallCommand, detectPackageManager, runMinimalChecks } from '../utils/check-system-deps.js';
|
|
36
37
|
import { detectNativePackages } from '../utils/detect-native-packages.js';
|
|
@@ -247,11 +248,8 @@ function isAbortedFromOverallTimeout(err) {
|
|
|
247
248
|
*/
|
|
248
249
|
function forceExit(code) {
|
|
249
250
|
process.exitCode = code;
|
|
250
|
-
|
|
251
|
-
if (gjs?.system?.exit) {
|
|
252
|
-
gjs.system.exit(code);
|
|
251
|
+
if (gjsExit(code))
|
|
253
252
|
return;
|
|
254
|
-
}
|
|
255
253
|
process.exit(code);
|
|
256
254
|
}
|
|
257
255
|
const CLI_PACKAGE_NAME = '@gjsify/cli';
|
package/lib/index.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
// This file is just the executable wrapper around `runCli`.
|
|
7
7
|
import { hideBin } from 'yargs/helpers';
|
|
8
8
|
import { runCli } from './cli-app.js';
|
|
9
|
+
import { gjsExit } from '@gjsify/rolldown-plugin-gjsify/runtime';
|
|
9
10
|
try {
|
|
10
11
|
await runCli(hideBin(process.argv));
|
|
11
12
|
}
|
|
@@ -23,6 +24,5 @@ catch (err) {
|
|
|
23
24
|
// atexit hook and would exit 0 at natural shutdown, so force a non-zero exit
|
|
24
25
|
// via `imports.system.exit` there (no-op on Node, where `imports` is unset).
|
|
25
26
|
process.exitCode = 1;
|
|
26
|
-
|
|
27
|
-
gjs?.system?.exit?.(1);
|
|
27
|
+
gjsExit(1);
|
|
28
28
|
}
|
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
// their full transitive prebuild set picked up automatically. The
|
|
11
11
|
// transitive walk is what makes `gjsify showcase` / `gjsify dlx` work
|
|
12
12
|
// for packages whose Vala typelibs live in *indirect* deps.
|
|
13
|
-
import { readdirSync, existsSync
|
|
13
|
+
import { readdirSync, existsSync } from 'node:fs';
|
|
14
14
|
import { join, resolve } from 'node:path';
|
|
15
|
+
import { readPackageJson } from './pkg-json.js';
|
|
15
16
|
/** Map Node.js process.arch values to the convention used in prebuilds/ directories. */
|
|
16
17
|
function nodeArchToLinuxArch(arch) {
|
|
17
18
|
const map = {
|
|
@@ -22,15 +23,6 @@ function nodeArchToLinuxArch(arch) {
|
|
|
22
23
|
};
|
|
23
24
|
return map[arch] ?? arch;
|
|
24
25
|
}
|
|
25
|
-
/** Read a package.json file and return its parsed content, or null on error. */
|
|
26
|
-
function readPackageJson(pkgJsonPath) {
|
|
27
|
-
try {
|
|
28
|
-
return JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
26
|
/**
|
|
35
27
|
* Scan all packages in a node_modules directory for gjsify native prebuilds.
|
|
36
28
|
* Handles scoped packages (@scope/name) as well as flat packages.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// confusing crash with no actionable message (observed: Node 22 in a Fedora
|
|
8
8
|
// container segfaults `gjsify install --backend native` during download/extract).
|
|
9
9
|
// This preflight turns that into a clear, actionable error.
|
|
10
|
-
import { isNode } from '@gjsify/rolldown-plugin-gjsify/runtime';
|
|
10
|
+
import { isNode, gjsSystemVersion } from '@gjsify/rolldown-plugin-gjsify/runtime';
|
|
11
11
|
/**
|
|
12
12
|
* Minimum Node.js major the native install backend supports — its prebuilt native
|
|
13
13
|
* modules are ABI-locked to this line (kept in sync with `.nvmrc`).
|
|
@@ -39,7 +39,7 @@ function onRealNode() {
|
|
|
39
39
|
// GJS exposes `imports.system.version`; @gjsify/process fakes
|
|
40
40
|
// `process.versions.node = '20.0.0'` for compat, so check GJS FIRST — a plain
|
|
41
41
|
// `process.versions.node` read would be a false Node positive under GJS.
|
|
42
|
-
const sysVersion =
|
|
42
|
+
const sysVersion = gjsSystemVersion();
|
|
43
43
|
if (sysVersion !== undefined)
|
|
44
44
|
return false;
|
|
45
45
|
return isNode();
|
package/lib/utils/oxc-resolve.js
CHANGED
|
@@ -54,7 +54,7 @@ import { pathToFileURL } from 'node:url';
|
|
|
54
54
|
import { findWorkspaceRoot } from './workspace-root.js';
|
|
55
55
|
import { resolveNpmPackage } from './resolve-npm-package.js';
|
|
56
56
|
import { nodeBinary } from './run-node.js';
|
|
57
|
-
import { isGjs } from '@gjsify/rolldown-plugin-gjsify/runtime';
|
|
57
|
+
import { isGjs, gjsExit } from '@gjsify/rolldown-plugin-gjsify/runtime';
|
|
58
58
|
/**
|
|
59
59
|
* Map Node.js `process.platform` + `arch` (+ musl on Linux) to the
|
|
60
60
|
* napi-rs binding-package suffix oxc uses, e.g. `linux-x64-gnu`,
|
|
@@ -408,9 +408,7 @@ export function setOxcExitCode(code) {
|
|
|
408
408
|
process.exitCode = code;
|
|
409
409
|
if (code === 0)
|
|
410
410
|
return;
|
|
411
|
-
|
|
412
|
-
if (gjs?.system?.exit)
|
|
413
|
-
gjs.system.exit(code);
|
|
411
|
+
gjsExit(code);
|
|
414
412
|
}
|
|
415
413
|
/**
|
|
416
414
|
* Has the given oxc tool's npm package (or its companion) been declared in the
|
|
@@ -11,6 +11,8 @@ export interface PackageJson {
|
|
|
11
11
|
devDependencies?: Record<string, string>;
|
|
12
12
|
peerDependencies?: Record<string, string>;
|
|
13
13
|
optionalDependencies?: Record<string, string>;
|
|
14
|
+
scripts?: Record<string, string>;
|
|
15
|
+
private?: boolean;
|
|
14
16
|
[key: string]: unknown;
|
|
15
17
|
}
|
|
16
18
|
export declare function readPackageJson(pkgPath: string): PackageJson | null;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PackageJson } from './pkg-json-edit.js';
|
|
2
|
+
/**
|
|
3
|
+
* Read + parse a `package.json` at `pkgPath`. Permissive: any error (missing
|
|
4
|
+
* file, unreadable, invalid JSON) yields `null`.
|
|
5
|
+
*/
|
|
6
|
+
export declare function readPackageJson(pkgPath: string): PackageJson | null;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Single permissive reader for `package.json` files, shared by the CLI's
|
|
2
|
+
// workspace- and dependency-discovery paths (`gjsify run`/`workspace`/`foreach`/
|
|
3
|
+
// `check`, native-prebuild scanning). Returns `null` when the file is missing
|
|
4
|
+
// OR unparseable — discovery must degrade gracefully on a stray or corrupt
|
|
5
|
+
// manifest rather than crash the whole command.
|
|
6
|
+
//
|
|
7
|
+
// The install-save path keeps its own STRICTER reader in `pkg-json-edit.ts`
|
|
8
|
+
// (`readPackageJson` there): it returns `null` only when the file is absent but
|
|
9
|
+
// THROWS on invalid JSON, so a corrupt manifest is never silently overwritten
|
|
10
|
+
// during `gjsify install <pkg>`. That contract is intentional and load-bearing
|
|
11
|
+
// — do not fold it into this one.
|
|
12
|
+
import { readFileSync } from 'node:fs';
|
|
13
|
+
/**
|
|
14
|
+
* Read + parse a `package.json` at `pkgPath`. Permissive: any error (missing
|
|
15
|
+
* file, unreadable, invalid JSON) yields `null`.
|
|
16
|
+
*/
|
|
17
|
+
export function readPackageJson(pkgPath) {
|
|
18
|
+
try {
|
|
19
|
+
return JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
package/lib/utils/run-gjs.js
CHANGED
|
@@ -53,6 +53,7 @@ export async function runGjsBundle(bundlePath, extraArgs = [], options = {}) {
|
|
|
53
53
|
const gjsCommand = ['gjs', ...gjsArgs.map((a) => (a.includes(' ') ? `"${a}"` : a))].join(' ');
|
|
54
54
|
console.error(`$ ${envPrefix ? `${envPrefix} ` : ''}${gjsCommand}`);
|
|
55
55
|
const child = spawn('gjs', gjsArgs, { env, stdio: 'inherit' });
|
|
56
|
+
let failed = false;
|
|
56
57
|
await new Promise((resolvePromise, reject) => {
|
|
57
58
|
child.on('close', (code) => {
|
|
58
59
|
if (code !== 0) {
|
|
@@ -65,10 +66,22 @@ export async function runGjsBundle(bundlePath, extraArgs = [], options = {}) {
|
|
|
65
66
|
child.on('error', reject);
|
|
66
67
|
}).catch((err) => {
|
|
67
68
|
console.error(err.message);
|
|
68
|
-
|
|
69
|
+
failed = true;
|
|
69
70
|
});
|
|
71
|
+
if (failed) {
|
|
72
|
+
// Set `process.exitCode` synchronously BEFORE exiting: under GJS
|
|
73
|
+
// `process.exit()` is deferred (the GLib main loop is armed), so when
|
|
74
|
+
// this runs via run.ts's in-process script dispatch, execution returns
|
|
75
|
+
// to the caller, which propagates by reading `process.exitCode`. Without
|
|
76
|
+
// this, `gjsify run <script>` whose body is `gjsify run <bundle>`
|
|
77
|
+
// swallowed a non-zero gjs exit and returned 0 — masking a failing
|
|
78
|
+
// `test:gjs` in the `test` script chain (and, via `gjsify foreach test`,
|
|
79
|
+
// in CI). The `return` guards against a fall-through second `exit`.
|
|
80
|
+
process.exitCode = 1;
|
|
81
|
+
return process.exit(1);
|
|
82
|
+
}
|
|
70
83
|
// See RunGjsBundleOptions.exitOnSuccess — terminal callers opt in,
|
|
71
84
|
// mid-flow callers (test.ts's runtime loop) keep the process alive.
|
|
72
85
|
if (options.exitOnSuccess)
|
|
73
|
-
process.exit(0);
|
|
86
|
+
return process.exit(0);
|
|
74
87
|
}
|
|
@@ -11,17 +11,10 @@
|
|
|
11
11
|
// monorepo must actually contain `start` as one of its workspaces.
|
|
12
12
|
// Without this guard, a grand-parent monorepo unrelated to `start`
|
|
13
13
|
// could be picked up.
|
|
14
|
-
import { existsSync
|
|
14
|
+
import { existsSync } from 'node:fs';
|
|
15
15
|
import { join, resolve } from 'node:path';
|
|
16
16
|
import { discoverWorkspaces } from '@gjsify/workspace';
|
|
17
|
-
|
|
18
|
-
try {
|
|
19
|
-
return JSON.parse(readFileSync(path, 'utf-8'));
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
17
|
+
import { readPackageJson } from './pkg-json.js';
|
|
25
18
|
export function findWorkspaceRoot(start) {
|
|
26
19
|
let dir = start;
|
|
27
20
|
for (let i = 0; i < 12; i++) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "CLI for Gjsify",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -122,19 +122,19 @@
|
|
|
122
122
|
"cli"
|
|
123
123
|
],
|
|
124
124
|
"dependencies": {
|
|
125
|
-
"@gjsify/buffer": "^0.
|
|
126
|
-
"@gjsify/create-app": "^0.
|
|
127
|
-
"@gjsify/node-globals": "^0.
|
|
128
|
-
"@gjsify/node-polyfills": "^0.
|
|
129
|
-
"@gjsify/npm-registry": "^0.
|
|
130
|
-
"@gjsify/resolve-npm": "^0.
|
|
131
|
-
"@gjsify/rolldown-plugin-gjsify": "^0.
|
|
132
|
-
"@gjsify/rolldown-plugin-pnp": "^0.
|
|
133
|
-
"@gjsify/semver": "^0.
|
|
134
|
-
"@gjsify/tar": "^0.
|
|
135
|
-
"@gjsify/tsc": "^0.
|
|
136
|
-
"@gjsify/web-polyfills": "^0.
|
|
137
|
-
"@gjsify/workspace": "^0.
|
|
125
|
+
"@gjsify/buffer": "^0.18.0",
|
|
126
|
+
"@gjsify/create-app": "^0.18.0",
|
|
127
|
+
"@gjsify/node-globals": "^0.18.0",
|
|
128
|
+
"@gjsify/node-polyfills": "^0.18.0",
|
|
129
|
+
"@gjsify/npm-registry": "^0.18.0",
|
|
130
|
+
"@gjsify/resolve-npm": "^0.18.0",
|
|
131
|
+
"@gjsify/rolldown-plugin-gjsify": "^0.18.0",
|
|
132
|
+
"@gjsify/rolldown-plugin-pnp": "^0.18.0",
|
|
133
|
+
"@gjsify/semver": "^0.18.0",
|
|
134
|
+
"@gjsify/tar": "^0.18.0",
|
|
135
|
+
"@gjsify/tsc": "^0.18.0",
|
|
136
|
+
"@gjsify/web-polyfills": "^0.18.0",
|
|
137
|
+
"@gjsify/workspace": "^0.18.0",
|
|
138
138
|
"cosmiconfig": "^9.0.2",
|
|
139
139
|
"get-tsconfig": "^4.14.0",
|
|
140
140
|
"pkg-types": "^2.3.1",
|
|
@@ -142,13 +142,13 @@
|
|
|
142
142
|
"yargs": "^18.0.0"
|
|
143
143
|
},
|
|
144
144
|
"devDependencies": {
|
|
145
|
-
"@gjsify/unit": "^0.
|
|
145
|
+
"@gjsify/unit": "^0.18.0",
|
|
146
146
|
"@types/yargs": "^17.0.35",
|
|
147
147
|
"typescript": "^6.0.3"
|
|
148
148
|
},
|
|
149
149
|
"peerDependencies": {
|
|
150
|
-
"@gjsify/oxfmt-native": "^0.
|
|
151
|
-
"@gjsify/rolldown-native": "^0.
|
|
150
|
+
"@gjsify/oxfmt-native": "^0.18.0",
|
|
151
|
+
"@gjsify/rolldown-native": "^0.18.0"
|
|
152
152
|
},
|
|
153
153
|
"peerDependenciesMeta": {
|
|
154
154
|
"@gjsify/oxfmt-native": {
|