@gjsify/cli 0.64.21 → 0.64.23
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 +80 -80
- package/lib/types/config-data.d.ts +4 -2
- package/lib/utils/oxc-resolve.d.ts +43 -7
- package/lib/utils/oxc-resolve.js +79 -24
- package/lib/utils/ship/layout.d.ts +5 -3
- package/lib/utils/ship/nested-bundles.js +4 -4
- package/lib/utils/ship/settings.d.ts +11 -5
- package/lib/utils/ship/settings.js +45 -30
- package/package.json +20 -20
|
@@ -762,8 +762,10 @@ export interface ConfigDataShip extends AppMetadata {
|
|
|
762
762
|
*
|
|
763
763
|
* `Contents/PlugIns` is Apple's own nested-code location (`codesign(1)`'s
|
|
764
764
|
* bundle format, beside `Frameworks`/`Helpers`/`XPCServices`); no other
|
|
765
|
-
* layout has an equivalent slot, so this is refused outside
|
|
766
|
-
* `gjsify ship darwin
|
|
765
|
+
* layout has an equivalent slot, so this is IGNORED (not refused) outside
|
|
766
|
+
* `gjsify ship darwin` — one notice on stderr, exit 0 (ADR 0024 amendment,
|
|
767
|
+
* 2026-11-06 addendum, beifahrer#203). The shape is still validated on
|
|
768
|
+
* every layout.
|
|
767
769
|
*/
|
|
768
770
|
nestedBundles?: ShipNestedBundleOptions[];
|
|
769
771
|
/**
|
|
@@ -51,15 +51,51 @@ export interface RunOxcOptions {
|
|
|
51
51
|
cwd?: string;
|
|
52
52
|
verbose?: boolean;
|
|
53
53
|
}
|
|
54
|
+
export interface OxfmtEngineInputs {
|
|
55
|
+
isGjs: boolean;
|
|
56
|
+
/** The `@gjsify/oxfmt-native` bridge loaded and its library opened. */
|
|
57
|
+
nativeLoadable: boolean;
|
|
58
|
+
/** The oxfmt release the bridge embeds; `undefined` when the bridge does not say. */
|
|
59
|
+
embeddedVersion?: string;
|
|
60
|
+
/** Version of the oxfmt npm package the project resolves; `undefined` when it has none. */
|
|
61
|
+
projectVersion?: string;
|
|
62
|
+
/** `GJSIFY_OXFMT`. */
|
|
63
|
+
override?: string;
|
|
64
|
+
}
|
|
65
|
+
export interface OxfmtEngineDecision {
|
|
66
|
+
engine: 'native' | 'npm';
|
|
67
|
+
/** The forced `native` engine runs a different oxfmt than the project's lock. */
|
|
68
|
+
warning?: string;
|
|
69
|
+
/** The forced `native` engine cannot be loaded. */
|
|
70
|
+
error?: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The engine pick as a pure function. Two engines that are not the same build of
|
|
74
|
+
* oxfmt format some inputs differently (`for (…; cond;) {` vs `for (…; cond; ) {`
|
|
75
|
+
* between 0.61 and 0.56), so a project that pins its own `oxfmt` must get THAT
|
|
76
|
+
* build, or `format:check` is green under GJS locally and red under Node in CI.
|
|
77
|
+
*
|
|
78
|
+
* - `npm` override → npm launcher.
|
|
79
|
+
* - `native` override → the bridge, an error when it is not loadable, a warning
|
|
80
|
+
* when it differs from the project's pinned version.
|
|
81
|
+
* - Not GJS, or bridge not loadable → npm launcher.
|
|
82
|
+
* - Project resolves no `oxfmt`, or either version is unknown → native (the
|
|
83
|
+
* Node-free default; there is nothing to disagree with).
|
|
84
|
+
* - Both known → native only when equal, else the project's npm `oxfmt` wins.
|
|
85
|
+
*/
|
|
86
|
+
export declare function decideOxfmtEngine(input: OxfmtEngineInputs): OxfmtEngineDecision;
|
|
87
|
+
/**
|
|
88
|
+
* Version of the `oxfmt` npm package the project resolves (same walk as
|
|
89
|
+
* {@link findOxcLauncher}), or `undefined` when there is none.
|
|
90
|
+
*/
|
|
91
|
+
export declare function findProjectOxfmtVersion(cwd?: string): string | undefined;
|
|
54
92
|
/**
|
|
55
|
-
* Engine pick for oxfmt —
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* - Default: native under GJS when loadable (the Node launcher cannot run
|
|
60
|
-
* without a Node host), npm launcher on Node.
|
|
93
|
+
* Engine pick for oxfmt — see {@link decideOxfmtEngine} for the rule. This wrapper
|
|
94
|
+
* gathers the inputs (bridge probe, project version) and applies the outcome:
|
|
95
|
+
* a forced `native` that cannot load throws, a forced `native` on another version
|
|
96
|
+
* than the project's warns once per process.
|
|
61
97
|
*/
|
|
62
|
-
export declare function shouldUseNativeOxfmt(): Promise<boolean>;
|
|
98
|
+
export declare function shouldUseNativeOxfmt(cwd?: string): Promise<boolean>;
|
|
63
99
|
/**
|
|
64
100
|
* Run an oxc tool (oxlint / oxfmt).
|
|
65
101
|
*
|
package/lib/utils/oxc-resolve.js
CHANGED
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
// Rust rule subset. Lint stays Node-spawned until that trade-off is decided
|
|
48
48
|
// (tracked in status/open-todos/README.md).
|
|
49
49
|
import { existsSync, readFileSync } from 'node:fs';
|
|
50
|
-
import { join, resolve } from 'node:path';
|
|
50
|
+
import { dirname, join, resolve } from 'node:path';
|
|
51
51
|
import { createRequire } from 'node:module';
|
|
52
52
|
import { pathToFileURL } from 'node:url';
|
|
53
53
|
import { hostLibc } from './platform-check.js';
|
|
@@ -297,38 +297,93 @@ async function tryLoadNativeOxfmt() {
|
|
|
297
297
|
})();
|
|
298
298
|
return _nativeOxfmtProbe;
|
|
299
299
|
}
|
|
300
|
+
const normalizeVersion = (v) => v.trim().replace(/^v/, '');
|
|
300
301
|
/**
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
302
|
+
* The engine pick as a pure function. Two engines that are not the same build of
|
|
303
|
+
* oxfmt format some inputs differently (`for (…; cond;) {` vs `for (…; cond; ) {`
|
|
304
|
+
* between 0.61 and 0.56), so a project that pins its own `oxfmt` must get THAT
|
|
305
|
+
* build, or `format:check` is green under GJS locally and red under Node in CI.
|
|
306
|
+
*
|
|
307
|
+
* - `npm` override → npm launcher.
|
|
308
|
+
* - `native` override → the bridge, an error when it is not loadable, a warning
|
|
309
|
+
* when it differs from the project's pinned version.
|
|
310
|
+
* - Not GJS, or bridge not loadable → npm launcher.
|
|
311
|
+
* - Project resolves no `oxfmt`, or either version is unknown → native (the
|
|
312
|
+
* Node-free default; there is nothing to disagree with).
|
|
313
|
+
* - Both known → native only when equal, else the project's npm `oxfmt` wins.
|
|
307
314
|
*/
|
|
308
|
-
export
|
|
309
|
-
const
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
if (!
|
|
316
|
-
|
|
317
|
-
|
|
315
|
+
export function decideOxfmtEngine(input) {
|
|
316
|
+
const { isGjs: gjs, nativeLoadable, embeddedVersion, projectVersion, override } = input;
|
|
317
|
+
const known = embeddedVersion !== undefined && projectVersion !== undefined;
|
|
318
|
+
const differs = known && normalizeVersion(embeddedVersion) !== normalizeVersion(projectVersion);
|
|
319
|
+
if (override === 'npm')
|
|
320
|
+
return { engine: 'npm' };
|
|
321
|
+
if (override === 'native') {
|
|
322
|
+
if (!nativeLoadable) {
|
|
323
|
+
return {
|
|
324
|
+
engine: 'native',
|
|
325
|
+
error: 'GJSIFY_OXFMT=native but @gjsify/oxfmt-native is not loadable (no prebuild for this architecture, or not running under GJS).',
|
|
326
|
+
};
|
|
318
327
|
}
|
|
319
|
-
return
|
|
328
|
+
return differs
|
|
329
|
+
? {
|
|
330
|
+
engine: 'native',
|
|
331
|
+
warning: `GJSIFY_OXFMT=native: @gjsify/oxfmt-native embeds oxfmt ${embeddedVersion} but this project ` +
|
|
332
|
+
`pins oxfmt ${projectVersion}; output can differ from the project's own oxfmt (and from CI).`,
|
|
333
|
+
}
|
|
334
|
+
: { engine: 'native' };
|
|
320
335
|
}
|
|
321
|
-
if (!
|
|
336
|
+
if (!gjs || !nativeLoadable)
|
|
337
|
+
return { engine: 'npm' };
|
|
338
|
+
return { engine: differs ? 'npm' : 'native' };
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Version of the `oxfmt` npm package the project resolves (same walk as
|
|
342
|
+
* {@link findOxcLauncher}), or `undefined` when there is none.
|
|
343
|
+
*/
|
|
344
|
+
export function findProjectOxfmtVersion(cwd = process.cwd()) {
|
|
345
|
+
try {
|
|
346
|
+
const launcher = findOxcLauncher('oxfmt', cwd);
|
|
347
|
+
const pkg = JSON.parse(readFileSync(join(dirname(launcher), '..', 'package.json'), 'utf-8'));
|
|
348
|
+
return typeof pkg?.version === 'string' ? pkg.version : undefined;
|
|
349
|
+
}
|
|
350
|
+
catch {
|
|
351
|
+
return undefined;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
let _engineWarned = false;
|
|
355
|
+
/**
|
|
356
|
+
* Engine pick for oxfmt — see {@link decideOxfmtEngine} for the rule. This wrapper
|
|
357
|
+
* gathers the inputs (bridge probe, project version) and applies the outcome:
|
|
358
|
+
* a forced `native` that cannot load throws, a forced `native` on another version
|
|
359
|
+
* than the project's warns once per process.
|
|
360
|
+
*/
|
|
361
|
+
export async function shouldUseNativeOxfmt(cwd = process.cwd()) {
|
|
362
|
+
const env = globalThis.process?.env ?? {};
|
|
363
|
+
const override = env.GJSIFY_OXFMT;
|
|
364
|
+
// Nothing to probe when npm is forced or there is no GJS host (and no native override).
|
|
365
|
+
if (override === 'npm' || (!isGjs() && override !== 'native'))
|
|
322
366
|
return false;
|
|
323
|
-
const native =
|
|
367
|
+
const native = await tryLoadNativeOxfmt();
|
|
368
|
+
const decision = decideOxfmtEngine({
|
|
369
|
+
isGjs: isGjs(),
|
|
370
|
+
nativeLoadable: native !== null,
|
|
371
|
+
embeddedVersion: native?.EMBEDDED_OXFMT_VERSION,
|
|
372
|
+
projectVersion: findProjectOxfmtVersion(cwd),
|
|
373
|
+
override,
|
|
374
|
+
});
|
|
375
|
+
if (decision.error)
|
|
376
|
+
throw new Error(decision.error + (_nativeOxfmtLoadError ? `\n${_nativeOxfmtLoadError.message}` : ''));
|
|
377
|
+
if (decision.warning && !_engineWarned) {
|
|
378
|
+
_engineWarned = true;
|
|
379
|
+
console.warn(`[gjsify oxc] ${decision.warning}`);
|
|
380
|
+
}
|
|
324
381
|
// Falling back to the npm launcher is not an error, so the default path is
|
|
325
382
|
// quiet — but a MEASURED reason why the native bridge would not load is the
|
|
326
383
|
// only place the user hears it, and it is the whole point of measuring.
|
|
327
|
-
|
|
328
|
-
// same answer for free.
|
|
329
|
-
if (!native && _nativeOxfmtLoadError)
|
|
384
|
+
if (!native && _nativeOxfmtLoadError && decision.engine === 'npm')
|
|
330
385
|
console.debug(_nativeOxfmtLoadError.message);
|
|
331
|
-
return native;
|
|
386
|
+
return decision.engine === 'native';
|
|
332
387
|
}
|
|
333
388
|
/**
|
|
334
389
|
* Run an oxc tool (oxlint / oxfmt).
|
|
@@ -151,9 +151,11 @@ export interface LayoutDirs {
|
|
|
151
151
|
* `Helpers`, `XPCServices`). `''` on linux and windows, where neither a
|
|
152
152
|
* prefix nor a program directory has an equivalent: a Flatpak sandbox has no
|
|
153
153
|
* App Extension model and a Windows program directory has nothing Apple's
|
|
154
|
-
* extension points name. `gjsify.ship.nestedBundles` is
|
|
155
|
-
* any layout where this is `''`
|
|
156
|
-
*
|
|
154
|
+
* extension points name. `gjsify.ship.nestedBundles` is IGNORED (not
|
|
155
|
+
* refused) on any layout where this is `''` — `resolveShipNestedBundles`
|
|
156
|
+
* resolves it to `[]` before `stageSubordinates` ever sees it (ADR 0024
|
|
157
|
+
* amendment, "nested bundles and helper executables", 2026-11-06 addendum;
|
|
158
|
+
* the beifahrer ADR this answers: 0026 § 6).
|
|
157
159
|
*/
|
|
158
160
|
plugins: string;
|
|
159
161
|
}
|
|
@@ -36,8 +36,8 @@ export function stageSubordinates(input) {
|
|
|
36
36
|
if (dirs.plugins === '') {
|
|
37
37
|
throw new Error(`gjsify ship: the ${input.layout.name} layout has no \`Contents/PlugIns\` equivalent, so ` +
|
|
38
38
|
`the nested bundle "${bundle.name}" has nowhere to go. ` +
|
|
39
|
-
'`gjsify.ship.nestedBundles` is darwin-only; `
|
|
40
|
-
'this already — report this as a gjsify bug if it did not.');
|
|
39
|
+
'`gjsify.ship.nestedBundles` is darwin-only; `resolveShipNestedBundles` should have ' +
|
|
40
|
+
'resolved this to `[]` already — report this as a gjsify bug if it did not.');
|
|
41
41
|
}
|
|
42
42
|
const bundleRoot = posix.join(dirs.plugins, bundle.name);
|
|
43
43
|
for (const rel of listFilesRecursive(bundle.source)) {
|
|
@@ -54,8 +54,8 @@ export function stageSubordinates(input) {
|
|
|
54
54
|
if (dirs.helpers === '') {
|
|
55
55
|
throw new Error(`gjsify ship: the ${input.layout.name} layout has no \`Contents/Helpers\` equivalent, so ` +
|
|
56
56
|
`the helper executable "${helper.name}" has nowhere to go. ` +
|
|
57
|
-
'`gjsify.ship.helperExecutables` is darwin-only; `
|
|
58
|
-
'this already — report this as a gjsify bug if it did not.');
|
|
57
|
+
'`gjsify.ship.helperExecutables` is darwin-only; `resolveShipHelperExecutables` should have ' +
|
|
58
|
+
'resolved this to `[]` already — report this as a gjsify bug if it did not.');
|
|
59
59
|
}
|
|
60
60
|
const path = posix.join(dirs.helpers, helper.name);
|
|
61
61
|
files.push({ path, mode: 0o755, source: { kind: 'file', path: helper.source } });
|
|
@@ -181,10 +181,15 @@ export declare function resolveShipExecutables(input: {
|
|
|
181
181
|
* `gjsify.ship.nestedBundles` → the further bundles the darwin container embeds
|
|
182
182
|
* under `Contents/PlugIns/` — e.g. a Safari Web Extension `.appex`.
|
|
183
183
|
*
|
|
184
|
-
* Darwin-only
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
184
|
+
* Darwin-only in EFFECT, not in form (ADR 0024 amendment, 2026-11-06,
|
|
185
|
+
* beifahrer#203): the declaration describes what the darwin `.app` carries and
|
|
186
|
+
* is not an error on another layout, so a non-empty list on `linux`/`windows`
|
|
187
|
+
* resolves to `[]` rather than throwing — a project with a Mac extension must
|
|
188
|
+
* still ship for Linux and Windows. The SHAPE check (schema, leaf names, `..`,
|
|
189
|
+
* duplicates, unknown keys) still runs on every layout, so a typo is caught on
|
|
190
|
+
* a Linux build too; only the SOURCE's existence is darwin-only, because a
|
|
191
|
+
* Linux runner never built the `.appex` to check. The caller
|
|
192
|
+
* ({@link resolveShipSettings}) prints the one-line notice this silence needs.
|
|
188
193
|
*/
|
|
189
194
|
export declare function resolveShipNestedBundles(input: {
|
|
190
195
|
declared: unknown;
|
|
@@ -194,7 +199,8 @@ export declare function resolveShipNestedBundles(input: {
|
|
|
194
199
|
/**
|
|
195
200
|
* `gjsify.ship.helperExecutables` → prebuilt executables staged into
|
|
196
201
|
* `Contents/Helpers/` beside the carried interpreter — e.g. a small Swift
|
|
197
|
-
* helper with no GI binding. Darwin-only,
|
|
202
|
+
* helper with no GI binding. Darwin-only in EFFECT, not in form — same reason
|
|
203
|
+
* and same split (shape always, source existence darwin-only) as
|
|
198
204
|
* {@link resolveShipNestedBundles}.
|
|
199
205
|
*/
|
|
200
206
|
export declare function resolveShipHelperExecutables(input: {
|
|
@@ -192,6 +192,26 @@ export function resolveShipSettings(input) {
|
|
|
192
192
|
// finish-args default depends on `kind`, which is a project fact.
|
|
193
193
|
const flatpakSettings = resolveShipFlatpakSettings({ ship, flatpak, kind });
|
|
194
194
|
warnings.push(...flatpakSettings.warnings);
|
|
195
|
+
// `gjsify.ship.nestedBundles`/`helperExecutables` describe what the DARWIN
|
|
196
|
+
// `.app` carries — on any other layout they are IGNORED, with one combined
|
|
197
|
+
// notice (ADR 0024 amendment, 2026-11-06, beifahrer#203), never refused: a
|
|
198
|
+
// project with a Mac extension must still be able to ship for Linux and
|
|
199
|
+
// Windows. Shape is still validated on every layout inside each resolver.
|
|
200
|
+
const nestedBundlesResolved = resolveShipNestedBundles({
|
|
201
|
+
declared: ship.nestedBundles,
|
|
202
|
+
projectDir: input.projectDir,
|
|
203
|
+
layoutOs: input.cli.layoutOs,
|
|
204
|
+
});
|
|
205
|
+
const helperExecutablesResolved = resolveShipHelperExecutables({
|
|
206
|
+
declared: ship.helperExecutables,
|
|
207
|
+
projectDir: input.projectDir,
|
|
208
|
+
layoutOs: input.cli.layoutOs,
|
|
209
|
+
});
|
|
210
|
+
if (input.cli.layoutOs !== 'darwin' &&
|
|
211
|
+
((Array.isArray(ship.nestedBundles) && ship.nestedBundles.length > 0) ||
|
|
212
|
+
(Array.isArray(ship.helperExecutables) && ship.helperExecutables.length > 0))) {
|
|
213
|
+
warnings.push(`gjsify ship: nestedBundles/helperExecutables apply to darwin only — not staged for ${input.cli.layoutOs}`);
|
|
214
|
+
}
|
|
195
215
|
const settings = {
|
|
196
216
|
projectDir: input.projectDir,
|
|
197
217
|
appId,
|
|
@@ -228,16 +248,8 @@ export function resolveShipSettings(input) {
|
|
|
228
248
|
projectDir: input.projectDir,
|
|
229
249
|
bundleDir: discovered.bundleDir,
|
|
230
250
|
}),
|
|
231
|
-
nestedBundles:
|
|
232
|
-
|
|
233
|
-
projectDir: input.projectDir,
|
|
234
|
-
layoutOs: input.cli.layoutOs,
|
|
235
|
-
}),
|
|
236
|
-
helperExecutables: resolveShipHelperExecutables({
|
|
237
|
-
declared: ship.helperExecutables,
|
|
238
|
-
projectDir: input.projectDir,
|
|
239
|
-
layoutOs: input.cli.layoutOs,
|
|
240
|
-
}),
|
|
251
|
+
nestedBundles: nestedBundlesResolved,
|
|
252
|
+
helperExecutables: helperExecutablesResolved,
|
|
241
253
|
outDir: input.cli.outDir ?? ship.outDir ?? 'ship',
|
|
242
254
|
arch: input.cli.arch ?? process.arch,
|
|
243
255
|
app,
|
|
@@ -320,10 +332,15 @@ function assertUsableBundleLeaf(name, at, under) {
|
|
|
320
332
|
* `gjsify.ship.nestedBundles` → the further bundles the darwin container embeds
|
|
321
333
|
* under `Contents/PlugIns/` — e.g. a Safari Web Extension `.appex`.
|
|
322
334
|
*
|
|
323
|
-
* Darwin-only
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
335
|
+
* Darwin-only in EFFECT, not in form (ADR 0024 amendment, 2026-11-06,
|
|
336
|
+
* beifahrer#203): the declaration describes what the darwin `.app` carries and
|
|
337
|
+
* is not an error on another layout, so a non-empty list on `linux`/`windows`
|
|
338
|
+
* resolves to `[]` rather than throwing — a project with a Mac extension must
|
|
339
|
+
* still ship for Linux and Windows. The SHAPE check (schema, leaf names, `..`,
|
|
340
|
+
* duplicates, unknown keys) still runs on every layout, so a typo is caught on
|
|
341
|
+
* a Linux build too; only the SOURCE's existence is darwin-only, because a
|
|
342
|
+
* Linux runner never built the `.appex` to check. The caller
|
|
343
|
+
* ({@link resolveShipSettings}) prints the one-line notice this silence needs.
|
|
327
344
|
*/
|
|
328
345
|
export function resolveShipNestedBundles(input) {
|
|
329
346
|
const { declared } = input;
|
|
@@ -333,14 +350,8 @@ export function resolveShipNestedBundles(input) {
|
|
|
333
350
|
throw new Error('gjsify ship: `gjsify.ship.nestedBundles` must be a list of `{ "source", "name", "entitlements"? }` ' +
|
|
334
351
|
'objects.');
|
|
335
352
|
}
|
|
336
|
-
if (declared.length > 0 && input.layoutOs !== 'darwin') {
|
|
337
|
-
throw new Error(`gjsify ship: \`gjsify.ship.nestedBundles\` is set and this run assembles the ${input.layoutOs} ` +
|
|
338
|
-
'layout, which has no `Contents/PlugIns` or equivalent — a Flatpak sandbox has no App ' +
|
|
339
|
-
"Extension model and a Windows program directory has nothing Apple's extension points name. " +
|
|
340
|
-
'Nested bundles are staged only for `gjsify ship darwin`.');
|
|
341
|
-
}
|
|
342
353
|
const seen = new Set();
|
|
343
|
-
|
|
354
|
+
const resolved = declared.map((row, index) => {
|
|
344
355
|
const at = `gjsify.ship.nestedBundles[${index}]`;
|
|
345
356
|
if (typeof row !== 'object' || row === null || Array.isArray(row)) {
|
|
346
357
|
throw new Error(`gjsify ship: \`${at}\` must be an object with \`source\` and \`name\`.`);
|
|
@@ -362,7 +373,10 @@ export function resolveShipNestedBundles(input) {
|
|
|
362
373
|
}
|
|
363
374
|
seen.add(name);
|
|
364
375
|
const abs = isAbsolute(source) ? source : resolve(input.projectDir, source);
|
|
365
|
-
|
|
376
|
+
// Existence is checked for darwin alone: on linux/windows this bundle is
|
|
377
|
+
// ignored outright (see below), and a CI runner assembling those layouts
|
|
378
|
+
// never built the `.appex` in the first place.
|
|
379
|
+
if (input.layoutOs === 'darwin' && !existsSync(abs)) {
|
|
366
380
|
throw new Error(`gjsify ship: \`${at}.source\` ${source} does not exist.`);
|
|
367
381
|
}
|
|
368
382
|
if (entitlements !== undefined && !Array.isArray(entitlements)) {
|
|
@@ -379,11 +393,13 @@ export function resolveShipNestedBundles(input) {
|
|
|
379
393
|
}),
|
|
380
394
|
};
|
|
381
395
|
});
|
|
396
|
+
return input.layoutOs === 'darwin' ? resolved : [];
|
|
382
397
|
}
|
|
383
398
|
/**
|
|
384
399
|
* `gjsify.ship.helperExecutables` → prebuilt executables staged into
|
|
385
400
|
* `Contents/Helpers/` beside the carried interpreter — e.g. a small Swift
|
|
386
|
-
* helper with no GI binding. Darwin-only,
|
|
401
|
+
* helper with no GI binding. Darwin-only in EFFECT, not in form — same reason
|
|
402
|
+
* and same split (shape always, source existence darwin-only) as
|
|
387
403
|
* {@link resolveShipNestedBundles}.
|
|
388
404
|
*/
|
|
389
405
|
export function resolveShipHelperExecutables(input) {
|
|
@@ -394,13 +410,8 @@ export function resolveShipHelperExecutables(input) {
|
|
|
394
410
|
throw new Error('gjsify ship: `gjsify.ship.helperExecutables` must be a list of `{ "source", "name", ' +
|
|
395
411
|
'"entitlements"? }` objects.');
|
|
396
412
|
}
|
|
397
|
-
if (declared.length > 0 && input.layoutOs !== 'darwin') {
|
|
398
|
-
throw new Error(`gjsify ship: \`gjsify.ship.helperExecutables\` is set and this run assembles the ` +
|
|
399
|
-
`${input.layoutOs} layout, which has no \`Contents/Helpers\` or equivalent. Helper ` +
|
|
400
|
-
'executables are staged only for `gjsify ship darwin`.');
|
|
401
|
-
}
|
|
402
413
|
const seen = new Set();
|
|
403
|
-
|
|
414
|
+
const resolved = declared.map((row, index) => {
|
|
404
415
|
const at = `gjsify.ship.helperExecutables[${index}]`;
|
|
405
416
|
if (typeof row !== 'object' || row === null || Array.isArray(row)) {
|
|
406
417
|
throw new Error(`gjsify ship: \`${at}\` must be an object with \`source\` and \`name\`.`);
|
|
@@ -422,7 +433,10 @@ export function resolveShipHelperExecutables(input) {
|
|
|
422
433
|
}
|
|
423
434
|
seen.add(name);
|
|
424
435
|
const abs = isAbsolute(source) ? source : resolve(input.projectDir, source);
|
|
425
|
-
|
|
436
|
+
// Existence is checked for darwin alone — on linux/windows this helper is
|
|
437
|
+
// ignored outright (see below), and a CI runner assembling those layouts
|
|
438
|
+
// never built it in the first place.
|
|
439
|
+
if (input.layoutOs === 'darwin' && !existsSync(abs)) {
|
|
426
440
|
throw new Error(`gjsify ship: \`${at}.source\` ${source} does not exist.`);
|
|
427
441
|
}
|
|
428
442
|
if (entitlements !== undefined && !Array.isArray(entitlements)) {
|
|
@@ -439,6 +453,7 @@ export function resolveShipHelperExecutables(input) {
|
|
|
439
453
|
}),
|
|
440
454
|
};
|
|
441
455
|
});
|
|
456
|
+
return input.layoutOs === 'darwin' ? resolved : [];
|
|
442
457
|
}
|
|
443
458
|
/**
|
|
444
459
|
* The ONE place a ship target's ENTRY is decided — {@link resolveShipApp}'s twin.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/cli",
|
|
3
|
-
"version": "0.64.
|
|
3
|
+
"version": "0.64.23",
|
|
4
4
|
"description": "CLI for Gjsify",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -142,22 +142,22 @@
|
|
|
142
142
|
"cli"
|
|
143
143
|
],
|
|
144
144
|
"dependencies": {
|
|
145
|
-
"@gjsify/blueprint": "^0.64.
|
|
146
|
-
"@gjsify/buffer": "^0.64.
|
|
147
|
-
"@gjsify/create-app": "^0.64.
|
|
148
|
-
"@gjsify/node-globals": "^0.64.
|
|
149
|
-
"@gjsify/node-polyfills": "^0.64.
|
|
150
|
-
"@gjsify/npm-registry": "^0.64.
|
|
151
|
-
"@gjsify/resolve-npm": "^0.64.
|
|
152
|
-
"@gjsify/rolldown-plugin-gjsify": "^0.64.
|
|
153
|
-
"@gjsify/vite-plugin-blueprint": "^0.64.
|
|
154
|
-
"@gjsify/rolldown-plugin-pnp": "^0.64.
|
|
155
|
-
"@gjsify/semver": "^0.64.
|
|
156
|
-
"@gjsify/tar": "^0.64.
|
|
157
|
-
"@gjsify/tsc": "^0.64.
|
|
158
|
-
"@gjsify/utils": "^0.64.
|
|
159
|
-
"@gjsify/web-polyfills": "^0.64.
|
|
160
|
-
"@gjsify/workspace": "^0.64.
|
|
145
|
+
"@gjsify/blueprint": "^0.64.23",
|
|
146
|
+
"@gjsify/buffer": "^0.64.23",
|
|
147
|
+
"@gjsify/create-app": "^0.64.23",
|
|
148
|
+
"@gjsify/node-globals": "^0.64.23",
|
|
149
|
+
"@gjsify/node-polyfills": "^0.64.23",
|
|
150
|
+
"@gjsify/npm-registry": "^0.64.23",
|
|
151
|
+
"@gjsify/resolve-npm": "^0.64.23",
|
|
152
|
+
"@gjsify/rolldown-plugin-gjsify": "^0.64.23",
|
|
153
|
+
"@gjsify/vite-plugin-blueprint": "^0.64.23",
|
|
154
|
+
"@gjsify/rolldown-plugin-pnp": "^0.64.23",
|
|
155
|
+
"@gjsify/semver": "^0.64.23",
|
|
156
|
+
"@gjsify/tar": "^0.64.23",
|
|
157
|
+
"@gjsify/tsc": "^0.64.23",
|
|
158
|
+
"@gjsify/utils": "^0.64.23",
|
|
159
|
+
"@gjsify/web-polyfills": "^0.64.23",
|
|
160
|
+
"@gjsify/workspace": "^0.64.23",
|
|
161
161
|
"acorn": "^8.17.0",
|
|
162
162
|
"cosmiconfig": "^9.0.2",
|
|
163
163
|
"get-tsconfig": "^4.14.0",
|
|
@@ -166,13 +166,13 @@
|
|
|
166
166
|
"yargs": "^18.0.0"
|
|
167
167
|
},
|
|
168
168
|
"devDependencies": {
|
|
169
|
-
"@gjsify/unit": "^0.64.
|
|
169
|
+
"@gjsify/unit": "^0.64.23",
|
|
170
170
|
"@types/yargs": "^17.0.35",
|
|
171
171
|
"typescript": "^6.0.3"
|
|
172
172
|
},
|
|
173
173
|
"peerDependencies": {
|
|
174
|
-
"@gjsify/oxfmt-native": "^0.64.
|
|
175
|
-
"@gjsify/rolldown-native": "^0.64.
|
|
174
|
+
"@gjsify/oxfmt-native": "^0.64.23",
|
|
175
|
+
"@gjsify/rolldown-native": "^0.64.23"
|
|
176
176
|
},
|
|
177
177
|
"peerDependenciesMeta": {
|
|
178
178
|
"@gjsify/oxfmt-native": {
|