@gjsify/cli 0.16.4 → 0.16.5

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.
@@ -2,6 +2,7 @@ import type { Command } from '../types/index.js';
2
2
  interface RunOptions {
3
3
  target: string;
4
4
  args: string[];
5
+ workspace?: string;
5
6
  }
6
7
  export declare const runCommand: Command<unknown, RunOptions>;
7
8
  export {};
@@ -14,11 +14,12 @@
14
14
  // as a bundle file. Everything else is a script name. Users who want
15
15
  // to disambiguate can pass `./<file>` explicitly.
16
16
  import { statSync } from 'node:fs';
17
- import { delimiter, join, resolve } from 'node:path';
17
+ import { basename, delimiter, join, resolve } from 'node:path';
18
18
  import { spawn } from 'node:child_process';
19
19
  import { runGjsBundle } from '../utils/run-gjs.js';
20
20
  import { readPackageJson } from '../utils/pkg-json-edit.js';
21
21
  import { findWorkspaceRoot } from '../utils/workspace-root.js';
22
+ import { discoverWorkspaces } from '@gjsify/workspace';
22
23
  import { isGjs } from '@gjsify/rolldown-plugin-gjsify/runtime';
23
24
  export const runCommand = {
24
25
  command: 'run <target> [args..]',
@@ -34,6 +35,16 @@ export const runCommand = {
34
35
  type: 'string',
35
36
  array: true,
36
37
  default: [],
38
+ })
39
+ .option('workspace', {
40
+ // npm/yarn-style `-w <name>`: run <target> as a SCRIPT in the
41
+ // named workspace instead of the current directory. The name
42
+ // matches the package.json `name`, the workspace-relative path
43
+ // (e.g. `cli`), or the directory basename — so both
44
+ // `-w eco-retrofit-cli` and `-w cli` resolve, matching npm.
45
+ alias: 'w',
46
+ type: 'string',
47
+ description: 'Run <target> as a script in the named workspace (by name or path), like `npm run <script> -w <name>`.',
37
48
  })
38
49
  .parserConfiguration({
39
50
  // Preserve `--` as args['--'] so callers can write
@@ -61,6 +72,12 @@ export const runCommand = {
61
72
  const positionalArgs = args.args ?? [];
62
73
  const doubleDashArgs = (args['--'] ?? []).filter((v) => typeof v === 'string');
63
74
  const extraArgs = [...positionalArgs, ...doubleDashArgs];
75
+ // `-w <name>` (npm/yarn parity): run <target> as a script in the named
76
+ // workspace's directory rather than the current one. Never file mode.
77
+ if (typeof args.workspace === 'string' && args.workspace.length > 0) {
78
+ await runScriptInWorkspace(args.workspace, target, extraArgs);
79
+ return;
80
+ }
64
81
  // Script lookup wins over file detection. Without this, a bare
65
82
  // `gjsify run build` would resolve to a file when a `./build`
66
83
  // directory exists in cwd (e.g. meson's build dir from a Vala
@@ -97,6 +114,31 @@ function looksLikeFile(target) {
97
114
  return false;
98
115
  }
99
116
  }
117
+ /**
118
+ * Resolve a workspace by npm/yarn `--workspace` semantics — matching the
119
+ * package.json `name`, the workspace-relative path (`packages/infra/cli` or
120
+ * `cli`), or the directory basename — then run `script` in that workspace's
121
+ * directory. Mirrors `npm run <script> --workspace <name>`.
122
+ */
123
+ async function runScriptInWorkspace(name, script, extraArgs) {
124
+ const root = findWorkspaceRoot(process.cwd()) ?? process.cwd();
125
+ let workspaces;
126
+ try {
127
+ workspaces = discoverWorkspaces(root);
128
+ }
129
+ catch (err) {
130
+ console.error(`gjsify run: could not read workspaces at ${root}: ${err.message}`);
131
+ return process.exit(1);
132
+ }
133
+ const ws = workspaces.find((w) => w.name === name || w.relativeLocation === name || basename(w.location) === name);
134
+ if (!ws) {
135
+ const available = workspaces.map((w) => w.relativeLocation).join(', ') || '<none>';
136
+ console.error(`gjsify run: no workspace "${name}" under ${root} (available: ${available})`);
137
+ // `return process.exit` — a bare exit falls through under GJS (see runScript).
138
+ return process.exit(1);
139
+ }
140
+ await runScript(script, extraArgs, ws.location);
141
+ }
100
142
  /**
101
143
  * Run a script declared in the current workspace's `package.json#scripts`.
102
144
  * Mirrors `yarn run <script>` semantics:
@@ -107,20 +149,29 @@ function looksLikeFile(target) {
107
149
  * - executed through `shell: true` so `&&` / `|` / env-var refs work
108
150
  * exactly as in package.json scripts (matches npm/yarn)
109
151
  */
110
- async function runScript(script, extraArgs) {
111
- const cwd = process.cwd();
152
+ async function runScript(script, extraArgs, cwd = process.cwd()) {
112
153
  const pkgPath = join(cwd, 'package.json');
113
154
  const pkg = readPackageJson(pkgPath);
114
155
  if (!pkg) {
115
156
  console.error(`gjsify run: no package.json in ${cwd}`);
116
- process.exit(1);
157
+ // `return process.exit` — under GJS `process.exit` cannot terminate
158
+ // synchronously (a parked GLib.MainLoop owns the thread): it SCHEDULES
159
+ // the exit and returns, so a bare call falls through. Here that reached
160
+ // `tokenizeSimpleCommand(literal)` with `literal === undefined` →
161
+ // `cannot access property "length"` → the throw raced the scheduled
162
+ // exit into a second `system.exit` → `m_should_exit assertion failed`
163
+ // → core dump. The `return` halts the handler so exactly one exit is
164
+ // scheduled (same discipline as commands/workspace.ts). No-op on Node.
165
+ return process.exit(1);
117
166
  }
118
167
  const scripts = pkg.scripts ?? {};
119
168
  const literal = scripts[script];
120
169
  if (typeof literal !== 'string') {
121
170
  const available = Object.keys(scripts).join(', ') || '<none>';
122
171
  console.error(`gjsify run: no script "${script}" in ${pkgPath} (available: ${available})`);
123
- process.exit(1);
172
+ // See the `no package.json` branch above — a bare `process.exit` under
173
+ // GJS falls through to `tokenizeSimpleCommand(undefined)` and core-dumps.
174
+ return process.exit(1);
124
175
  }
125
176
  const monorepoRoot = findWorkspaceRoot(cwd);
126
177
  const binDirs = [join(cwd, 'node_modules', '.bin')];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/cli",
3
- "version": "0.16.4",
3
+ "version": "0.16.5",
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.16.4",
126
- "@gjsify/create-app": "^0.16.4",
127
- "@gjsify/node-globals": "^0.16.4",
128
- "@gjsify/node-polyfills": "^0.16.4",
129
- "@gjsify/npm-registry": "^0.16.4",
130
- "@gjsify/resolve-npm": "^0.16.4",
131
- "@gjsify/rolldown-plugin-gjsify": "^0.16.4",
132
- "@gjsify/rolldown-plugin-pnp": "^0.16.4",
133
- "@gjsify/semver": "^0.16.4",
134
- "@gjsify/tar": "^0.16.4",
135
- "@gjsify/tsc": "^0.16.4",
136
- "@gjsify/web-polyfills": "^0.16.4",
137
- "@gjsify/workspace": "^0.16.4",
125
+ "@gjsify/buffer": "^0.16.5",
126
+ "@gjsify/create-app": "^0.16.5",
127
+ "@gjsify/node-globals": "^0.16.5",
128
+ "@gjsify/node-polyfills": "^0.16.5",
129
+ "@gjsify/npm-registry": "^0.16.5",
130
+ "@gjsify/resolve-npm": "^0.16.5",
131
+ "@gjsify/rolldown-plugin-gjsify": "^0.16.5",
132
+ "@gjsify/rolldown-plugin-pnp": "^0.16.5",
133
+ "@gjsify/semver": "^0.16.5",
134
+ "@gjsify/tar": "^0.16.5",
135
+ "@gjsify/tsc": "^0.16.5",
136
+ "@gjsify/web-polyfills": "^0.16.5",
137
+ "@gjsify/workspace": "^0.16.5",
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.16.4",
145
+ "@gjsify/unit": "^0.16.5",
146
146
  "@types/yargs": "^17.0.35",
147
147
  "typescript": "^6.0.3"
148
148
  },
149
149
  "peerDependencies": {
150
- "@gjsify/oxfmt-native": "^0.16.4",
151
- "@gjsify/rolldown-native": "^0.16.4"
150
+ "@gjsify/oxfmt-native": "^0.16.5",
151
+ "@gjsify/rolldown-native": "^0.16.5"
152
152
  },
153
153
  "peerDependenciesMeta": {
154
154
  "@gjsify/oxfmt-native": {