@gjsify/cli 0.43.0 → 0.45.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 +453 -425
- package/lib/actions/build.js +2 -1
- package/lib/commands/affected-classify.js +7 -5
- package/lib/commands/build.js +6 -0
- package/lib/commands/flatpak/ci.js +10 -2
- package/lib/commands/flatpak/init.js +15 -16
- package/lib/commands/flatpak/utils.d.ts +0 -26
- package/lib/commands/flatpak/utils.js +4 -29
- package/lib/commands/gettext.d.ts +2 -1
- package/lib/commands/gettext.js +105 -47
- package/lib/commands/onboard.d.ts +7 -0
- package/lib/commands/onboard.js +349 -96
- package/lib/commands/ship.d.ts +3 -0
- package/lib/commands/ship.js +911 -70
- package/lib/commands/trust.d.ts +6 -0
- package/lib/commands/trust.js +1 -1
- package/lib/config.js +25 -0
- package/lib/types/cli-build-options.d.ts +11 -0
- package/lib/types/config-data.d.ts +137 -3
- package/lib/utils/flatpak-runtime.d.ts +41 -0
- package/lib/utils/flatpak-runtime.js +54 -0
- package/lib/utils/msgfmt-merge.d.ts +35 -0
- package/lib/utils/msgfmt-merge.js +102 -0
- package/lib/utils/npm-otp.d.ts +27 -2
- package/lib/utils/npm-otp.js +82 -7
- package/lib/utils/onboard-discovery.d.ts +68 -0
- package/lib/utils/onboard-discovery.js +178 -0
- package/lib/utils/onboard-probe.d.ts +118 -1
- package/lib/utils/onboard-probe.js +153 -4
- package/lib/utils/prompt-output.d.ts +12 -0
- package/lib/utils/prompt-output.js +54 -0
- package/lib/utils/prompt.js +22 -2
- package/lib/utils/publishable-packages.d.ts +1 -1
- package/lib/utils/publishable-packages.js +1 -0
- package/lib/utils/resolve-npm-package.d.ts +56 -0
- package/lib/utils/resolve-npm-package.js +69 -0
- package/lib/utils/ship/app-runtime.d.ts +214 -0
- package/lib/utils/ship/app-runtime.js +429 -0
- package/lib/utils/ship/depends.d.ts +54 -7
- package/lib/utils/ship/depends.js +120 -6
- package/lib/utils/ship/discover.js +18 -1
- package/lib/utils/ship/dmg.d.ts +71 -0
- package/lib/utils/ship/dmg.js +181 -0
- package/lib/utils/ship/flatpak-config.d.ts +66 -0
- package/lib/utils/ship/flatpak-config.js +132 -0
- package/lib/utils/ship/flatpak.d.ts +45 -0
- package/lib/utils/ship/flatpak.js +148 -0
- package/lib/utils/ship/formats.d.ts +116 -3
- package/lib/utils/ship/formats.js +869 -11
- package/lib/utils/ship/launcher.d.ts +13 -3
- package/lib/utils/ship/launcher.js +362 -17
- package/lib/utils/ship/layout.d.ts +268 -0
- package/lib/utils/ship/layout.js +351 -0
- package/lib/utils/ship/localize-metadata.d.ts +22 -0
- package/lib/utils/ship/localize-metadata.js +126 -0
- package/lib/utils/ship/mime.js +1 -9
- package/lib/utils/ship/msi.d.ts +126 -0
- package/lib/utils/ship/msi.js +417 -0
- package/lib/utils/ship/node-runtime.d.ts +71 -0
- package/lib/utils/ship/node-runtime.js +122 -0
- package/lib/utils/ship/payload.d.ts +156 -5
- package/lib/utils/ship/payload.js +580 -14
- package/lib/utils/ship/plan.d.ts +21 -0
- package/lib/utils/ship/plan.js +20 -7
- package/lib/utils/ship/plist.d.ts +58 -0
- package/lib/utils/ship/plist.js +198 -0
- package/lib/utils/ship/rpm.js +9 -3
- package/lib/utils/ship/schemas.d.ts +61 -0
- package/lib/utils/ship/schemas.js +118 -0
- package/lib/utils/ship/scripts.js +7 -3
- package/lib/utils/ship/settings.d.ts +19 -1
- package/lib/utils/ship/settings.js +19 -1
- package/lib/utils/ship/share-dirs.d.ts +23 -0
- package/lib/utils/ship/share-dirs.js +46 -0
- package/lib/utils/ship/signing.d.ts +195 -0
- package/lib/utils/ship/signing.js +317 -0
- package/lib/utils/ship/stage-manifest.d.ts +50 -13
- package/lib/utils/ship/stage-manifest.js +137 -14
- package/lib/utils/ship/stage-writer.d.ts +48 -0
- package/lib/utils/ship/stage-writer.js +71 -1
- package/lib/utils/ship/types.d.ts +264 -16
- package/lib/utils/ship/xml.d.ts +7 -0
- package/lib/utils/ship/xml.js +25 -0
- package/lib/utils/ship/zip.d.ts +69 -0
- package/lib/utils/ship/zip.js +245 -0
- package/lib/utils/trust-registry.js +5 -0
- package/package.json +19 -19
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DistroFormatId } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* The GJS the bundles target (root AGENTS.md § Constraints: GJS 1.86 /
|
|
4
4
|
* SpiderMonkey 140, Rolldown `firefox140`). A `--app gjs` bundle can carry
|
|
@@ -14,7 +14,32 @@ import type { FormatId } from './types.js';
|
|
|
14
14
|
* is how a project whose bundle really does run on older GJS lowers it.
|
|
15
15
|
*/
|
|
16
16
|
export declare const DEFAULT_GJS_FLOOR = "1.86";
|
|
17
|
-
|
|
17
|
+
/**
|
|
18
|
+
* The Node the `--app node` bundles target, as a MAJOR.
|
|
19
|
+
*
|
|
20
|
+
* Node 24 is the LTS line `@gjsify/node-runtime-*` bundles for macOS and
|
|
21
|
+
* Windows, and this is the Linux half of the same decision: where an
|
|
22
|
+
* interpreter is bundled, the floor is what was bundled; where it is depended
|
|
23
|
+
* on, the floor is what the bundle needs.
|
|
24
|
+
*
|
|
25
|
+
* It excludes EVERY current DEB stable/LTS — Debian 13 trixie 20, Ubuntu 24.04
|
|
26
|
+
* LTS 18, Ubuntu 26.04 LTS 22; only Debian 14 forky has 24. `warnAboutNodeFloor`
|
|
27
|
+
* is what makes that visible at ship time, and `gjsify.ship.minNodeVersion` is
|
|
28
|
+
* how a project whose bundle really does run on an older Node lowers it. The
|
|
29
|
+
* same honest-floor-plus-warning answer as {@link DEFAULT_GJS_FLOOR}, one axis
|
|
30
|
+
* over — and it will fire far more often.
|
|
31
|
+
*/
|
|
32
|
+
export declare const DEFAULT_NODE_FLOOR = "24";
|
|
33
|
+
export declare function warnAboutGjsFloor(format: DistroFormatId, floor: string): string[];
|
|
34
|
+
/**
|
|
35
|
+
* Warn when the Node floor cannot be satisfied by a released Debian or Ubuntu.
|
|
36
|
+
* Returns the warning lines; empty when the floor is fine.
|
|
37
|
+
*
|
|
38
|
+
* Only reached when the payload actually needs an interpreter — a `--app gjs`
|
|
39
|
+
* package declares no Node dependency, so warning about its floor would be
|
|
40
|
+
* noise attached to a line that is never emitted.
|
|
41
|
+
*/
|
|
42
|
+
export declare function warnAboutNodeFloor(format: DistroFormatId, floor: string): string[];
|
|
18
43
|
export interface DependsInputs {
|
|
19
44
|
/** GI namespaces the bundle imports, in `Ns-Version` spelling. */
|
|
20
45
|
namespaces: readonly string[];
|
|
@@ -29,13 +54,33 @@ export interface DependsInputs {
|
|
|
29
54
|
hasIcons: boolean;
|
|
30
55
|
/** Whether the payload installs GSettings schemas. */
|
|
31
56
|
hasSchemas: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* The interpreter the launcher execs — `settings.app`, the SAME field
|
|
59
|
+
* `renderLauncher` branches on.
|
|
60
|
+
*
|
|
61
|
+
* Not a payload fact, and the attempt to make it one is worth keeping: the
|
|
62
|
+
* first cut derived it from a staged FILENAME (`*.node.mjs`), which is wrong
|
|
63
|
+
* in both directions. `discoverPayload` stages the whole directory beside
|
|
64
|
+
* the bundle and `dist/<name>.gjs.js` next to `dist/<name>.node.mjs` is the
|
|
65
|
+
* documented normal layout, so a pure `--app gjs` project that also builds a
|
|
66
|
+
* Node bundle declared a Node dependency it never execs — and with a `>= 24`
|
|
67
|
+
* floor that `.deb` is REFUSED by apt on trixie, Ubuntu 24.04 and Ubuntu
|
|
68
|
+
* 26.04. A working package made uninstallable is not "one extra package
|
|
69
|
+
* installed".
|
|
70
|
+
*
|
|
71
|
+
* The honest source is the one thing that decides both the launcher and this
|
|
72
|
+
* list. `assertLauncherMatchesInterpreter` re-reads the staged launcher and
|
|
73
|
+
* refuses a package where the two disagree, which is the check a payload
|
|
74
|
+
* heuristic could never be.
|
|
75
|
+
*
|
|
76
|
+
* macOS and Windows never reach here: there the interpreter is CARRIED, from
|
|
77
|
+
* `@gjsify/node-runtime-<target>`.
|
|
78
|
+
*/
|
|
79
|
+
interpreter: 'gjs' | 'node';
|
|
32
80
|
/** User-supplied additions for this format. */
|
|
33
81
|
extra: readonly string[];
|
|
34
82
|
/** Project-supplied table rows, filling gaps in {@link TYPELIB_PACKAGES}. */
|
|
35
|
-
typelibPackages?: Record<string,
|
|
36
|
-
deb: string;
|
|
37
|
-
rpm: string;
|
|
38
|
-
}>;
|
|
83
|
+
typelibPackages?: Record<string, Record<DistroFormatId, string>>;
|
|
39
84
|
/**
|
|
40
85
|
* Paths of typelib files the payload carries itself. The namespaces they cover need no distro
|
|
41
86
|
* dependency — and are derived from these filenames, never declared separately.
|
|
@@ -43,13 +88,15 @@ export interface DependsInputs {
|
|
|
43
88
|
bundledTypelibs?: readonly string[];
|
|
44
89
|
/** Minimum GJS. Default {@link DEFAULT_GJS_FLOOR}. */
|
|
45
90
|
minGjsVersion?: string;
|
|
91
|
+
/** Minimum Node major, when one is depended on. Default {@link DEFAULT_NODE_FLOOR}. */
|
|
92
|
+
minNodeVersion?: string;
|
|
46
93
|
}
|
|
47
94
|
/**
|
|
48
95
|
* The `Depends:` / `Requires:` list for one format.
|
|
49
96
|
*
|
|
50
97
|
* @throws when a namespace has no entry in the table — see the module header.
|
|
51
98
|
*/
|
|
52
|
-
export declare function deriveDepends(format:
|
|
99
|
+
export declare function deriveDepends(format: DistroFormatId, inputs: DependsInputs): string[];
|
|
53
100
|
/** One parsed dependency. `relation`/`version` are absent for an unversioned one. */
|
|
54
101
|
export interface ParsedDepend {
|
|
55
102
|
name: string;
|
|
@@ -35,13 +35,77 @@
|
|
|
35
35
|
* is how a project whose bundle really does run on older GJS lowers it.
|
|
36
36
|
*/
|
|
37
37
|
export const DEFAULT_GJS_FLOOR = '1.86';
|
|
38
|
+
/**
|
|
39
|
+
* The Node the `--app node` bundles target, as a MAJOR.
|
|
40
|
+
*
|
|
41
|
+
* Node 24 is the LTS line `@gjsify/node-runtime-*` bundles for macOS and
|
|
42
|
+
* Windows, and this is the Linux half of the same decision: where an
|
|
43
|
+
* interpreter is bundled, the floor is what was bundled; where it is depended
|
|
44
|
+
* on, the floor is what the bundle needs.
|
|
45
|
+
*
|
|
46
|
+
* It excludes EVERY current DEB stable/LTS — Debian 13 trixie 20, Ubuntu 24.04
|
|
47
|
+
* LTS 18, Ubuntu 26.04 LTS 22; only Debian 14 forky has 24. `warnAboutNodeFloor`
|
|
48
|
+
* is what makes that visible at ship time, and `gjsify.ship.minNodeVersion` is
|
|
49
|
+
* how a project whose bundle really does run on an older Node lowers it. The
|
|
50
|
+
* same honest-floor-plus-warning answer as {@link DEFAULT_GJS_FLOOR}, one axis
|
|
51
|
+
* over — and it will fire far more often.
|
|
52
|
+
*/
|
|
53
|
+
export const DEFAULT_NODE_FLOOR = '24';
|
|
54
|
+
/**
|
|
55
|
+
* The package providing a Node interpreter, per format.
|
|
56
|
+
*
|
|
57
|
+
* ⚠️ THE TWO STRINGS ARE NOT THE SAME NAME, and getting rpm's wrong is silent.
|
|
58
|
+
* `Requires: nodejs >= 24` is a NO-OP on Fedora. Measured with `dnf repoquery`
|
|
59
|
+
* on Fedora 44:
|
|
60
|
+
*
|
|
61
|
+
* --whatprovides 'nodejs >= 24' → nodejs22-1:22.23.1-2.fc44
|
|
62
|
+
* --whatprovides 'nodejs(engine) >= 24' → nodejs24-1:24.18.0-1.fc44
|
|
63
|
+
*
|
|
64
|
+
* F44 has no real `nodejs` package at all — the name is a virtual Provide of the
|
|
65
|
+
* stream packages, which carry **Epoch 1**. A bare `>= 24` desugars to `0:24`,
|
|
66
|
+
* and `1:22.23.1` beats it on epoch alone, so the floor admits the very version
|
|
67
|
+
* it was written to exclude. `nodejs(engine)` carries no epoch and compares as
|
|
68
|
+
* written. (Streams 20/22/24 are parallel-installable, which is why the name has
|
|
69
|
+
* to be a Provide in the first place.) The spelling appears nowhere in the
|
|
70
|
+
* Fedora packaging guideline's own source — it comes from real spec files.
|
|
71
|
+
*
|
|
72
|
+
* No `/usr/bin/node` file dependency beside it — right answer, and the FIRST
|
|
73
|
+
* reason written here for it was wrong, so both are recorded. It is not that
|
|
74
|
+
* `nodejs24` pulls the symlink in: `/usr/bin/node` is provided by `nodejs20-bin`,
|
|
75
|
+
* `nodejs22-bin` AND `nodejs24-bin`, all three of which
|
|
76
|
+
* `Provides`/`Conflicts: alternative-for(nodejs-bin)` and are therefore mutually
|
|
77
|
+
* exclusive. `nodejs24` itself installs `/usr/bin/node-24`. So the file
|
|
78
|
+
* dependency is satisfied by ANY stream's `-bin`, which makes it worthless as a
|
|
79
|
+
* version constraint — that is why it is not emitted.
|
|
80
|
+
*
|
|
81
|
+
* ⚠️ AND THAT LEAVES A REAL HOLE, which no dependency this writer can emit
|
|
82
|
+
* closes. Measured on Fedora 44:
|
|
83
|
+
*
|
|
84
|
+
* dnf install --assumeno nodejs22-bin 'nodejs(engine) >= 24'
|
|
85
|
+
* → installs nodejs22-bin, nodejs22, nodejs24, nodejs24-libs
|
|
86
|
+
* → and NOT nodejs24-bin
|
|
87
|
+
*
|
|
88
|
+
* Every requirement is met and `node` on `PATH` is still 22. rpm's alternatives
|
|
89
|
+
* scheme has no vocabulary for "the stream that owns the symlink must be at
|
|
90
|
+
* least 24", so an app that must have 24 on `PATH` has to check at runtime; a
|
|
91
|
+
* package cannot ask for it. Recorded here because the gap is invisible from the
|
|
92
|
+
* emitted `Requires:` line, which looks correct and is.
|
|
93
|
+
*
|
|
94
|
+
* (`nodejs24` carries no bare `nodejs` Provide at all — only `nodejs22` does on
|
|
95
|
+
* F44, which is the other half of why the epoch trap above bites.)
|
|
96
|
+
*
|
|
97
|
+
* A `Record`, for the reason {@link SCHEMA_COMPILER_PACKAGE} records: a ternary
|
|
98
|
+
* reads as a two-way choice and is really "deb, or ELSE rpm's name", and a third
|
|
99
|
+
* format silently inheriting rpm's spelling has happened here before, at exit 0.
|
|
100
|
+
*/
|
|
101
|
+
const NODE_PACKAGE = { deb: 'nodejs', rpm: 'nodejs(engine)' };
|
|
38
102
|
/**
|
|
39
103
|
* The package providing `glib-compile-schemas`, per format.
|
|
40
104
|
*
|
|
41
105
|
* A record, not `format === 'deb' ? … : …`. The ternary reads as a two-way
|
|
42
106
|
* choice and is really "deb, or ELSE rpm's package name" — measured on a third
|
|
43
107
|
* format, `dmg` got `glib2`, at exit 0, in the `Depends:` of a package that has
|
|
44
|
-
* no such thing. Adding a `
|
|
108
|
+
* no such thing. Adding a `DistroFormatId` now fails to build here instead.
|
|
45
109
|
*/
|
|
46
110
|
const SCHEMA_COMPILER_PACKAGE = { deb: 'libglib2.0-bin', rpm: 'glib2' };
|
|
47
111
|
/** Debian's `gjs` versions per suite, as measured 2026-08-15 — see {@link warnAboutGjsFloor}. */
|
|
@@ -53,10 +117,10 @@ const DEBIAN_GJS = 'trixie ships 1.82.3 and forky 1.88.1; 1.84 and 1.86 were ski
|
|
|
53
117
|
/**
|
|
54
118
|
* Which formats this Debian-suite warning is ABOUT.
|
|
55
119
|
*
|
|
56
|
-
* A `Record<
|
|
120
|
+
* A `Record<DistroFormatId, …>` and not `format !== 'deb'`: the negative form answers
|
|
57
121
|
* for every format that will ever exist, and answers "stay quiet" — so a third
|
|
58
122
|
* format would inherit silence about a floor nobody has checked for its distro,
|
|
59
|
-
* with no compile error. As a record, adding a `
|
|
123
|
+
* with no compile error. As a record, adding a `DistroFormatId` fails to build until
|
|
60
124
|
* someone decides. `rpm` is false because Fedora ships a current GJS, which is a
|
|
61
125
|
* measured fact about Fedora, not a default.
|
|
62
126
|
*/
|
|
@@ -78,6 +142,49 @@ export function warnAboutGjsFloor(format, floor) {
|
|
|
78
142
|
'to make apt happy, because the result is an install that succeeds and an app that does not start.',
|
|
79
143
|
];
|
|
80
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Node majors per DEB suite, as measured 2026-08-28 — see {@link warnAboutNodeFloor}.
|
|
147
|
+
*/
|
|
148
|
+
const DEBIAN_NODE = 'trixie ships 20, forky 24; Ubuntu 24.04 LTS ships 18 and 26.04 LTS 22';
|
|
149
|
+
/**
|
|
150
|
+
* Which formats the Node-floor warning is ABOUT.
|
|
151
|
+
*
|
|
152
|
+
* `rpm` is false, and it is a measured fact about Fedora rather than a default:
|
|
153
|
+
* F43/44/45 default to Node 22 but ship `nodejs24` in the base repository,
|
|
154
|
+
* parallel-installable, so `nodejs(engine) >= 24` resolves without an extra
|
|
155
|
+
* repository. Debian and Ubuntu have no such stream packages — one `nodejs` per
|
|
156
|
+
* suite, and it is older than 24 in every current stable/LTS.
|
|
157
|
+
*
|
|
158
|
+
* A `Record` and not `format !== 'deb'`, for the reason
|
|
159
|
+
* {@link GJS_FLOOR_IS_DEBIAN_NEWS} spells out: the negative form answers "stay
|
|
160
|
+
* quiet" for every format that will ever exist, including ones nobody has
|
|
161
|
+
* checked a distribution for.
|
|
162
|
+
*/
|
|
163
|
+
const NODE_FLOOR_IS_DEBIAN_NEWS = { deb: true, rpm: false };
|
|
164
|
+
/**
|
|
165
|
+
* Warn when the Node floor cannot be satisfied by a released Debian or Ubuntu.
|
|
166
|
+
* Returns the warning lines; empty when the floor is fine.
|
|
167
|
+
*
|
|
168
|
+
* Only reached when the payload actually needs an interpreter — a `--app gjs`
|
|
169
|
+
* package declares no Node dependency, so warning about its floor would be
|
|
170
|
+
* noise attached to a line that is never emitted.
|
|
171
|
+
*/
|
|
172
|
+
export function warnAboutNodeFloor(format, floor) {
|
|
173
|
+
if (!NODE_FLOOR_IS_DEBIAN_NEWS[format])
|
|
174
|
+
return [];
|
|
175
|
+
// Ubuntu 26.04 LTS's 22 is the newest a current DEB stable/LTS carries;
|
|
176
|
+
// trixie's 20 is older still. A floor of 22 or below is satisfiable
|
|
177
|
+
// somewhere released and stays quiet.
|
|
178
|
+
if (compareVersions(floor, '22') <= 0)
|
|
179
|
+
return [];
|
|
180
|
+
return [
|
|
181
|
+
`gjsify ship: \`Depends: nodejs (>= ${floor})\` is not satisfiable on any current DEB stable/LTS — ` +
|
|
182
|
+
`${DEBIAN_NODE}. The package installs on forky/sid and on distributions with a newer Node. Set ` +
|
|
183
|
+
'`gjsify.ship.minNodeVersion` if this bundle genuinely runs on an older Node; do NOT lower it ' +
|
|
184
|
+
'to make apt happy, because the result is an install that succeeds and an app that dies on the ' +
|
|
185
|
+
'first syntax or API the older interpreter does not have.',
|
|
186
|
+
];
|
|
187
|
+
}
|
|
81
188
|
/** Numeric dotted-version compare. Enough for `1.82.3` vs `1.86`. */
|
|
82
189
|
function compareVersions(a, b) {
|
|
83
190
|
const left = a.split('.').map(Number);
|
|
@@ -155,7 +262,14 @@ const BUNDLED_TYPELIB = /^Gjsify[A-Z]/;
|
|
|
155
262
|
* @throws when a namespace has no entry in the table — see the module header.
|
|
156
263
|
*/
|
|
157
264
|
export function deriveDepends(format, inputs) {
|
|
158
|
-
|
|
265
|
+
// The interpreter the launcher execs, and nothing else: a package declares ONE.
|
|
266
|
+
// Linux is the only place this is a dependency at all — macOS and Windows have
|
|
267
|
+
// no system Node, so an artifact for those CARRIES one from
|
|
268
|
+
// `@gjsify/node-runtime-<target>`, and that is the whole reason those three
|
|
269
|
+
// packages exist and this one line is their opposite.
|
|
270
|
+
const out = inputs.interpreter === 'node'
|
|
271
|
+
? [`${NODE_PACKAGE[format]} >= ${inputs.minNodeVersion ?? DEFAULT_NODE_FLOOR}`]
|
|
272
|
+
: [`gjs >= ${inputs.minGjsVersion ?? DEFAULT_GJS_FLOOR}`];
|
|
159
273
|
const unmapped = [];
|
|
160
274
|
// Namespaces the package SHIPS ITSELF, read off the staged filenames rather than from a
|
|
161
275
|
// separate declaration: `Gwebgl-0.1.typelib` → `Gwebgl-0.1` and `Gwebgl`. Deriving it is the
|
|
@@ -206,8 +320,8 @@ export function deriveDepends(format, inputs) {
|
|
|
206
320
|
if (inputs.hasSchemas)
|
|
207
321
|
out.push(SCHEMA_COMPILER_PACKAGE[format]);
|
|
208
322
|
out.push(...inputs.extra);
|
|
209
|
-
// Set-dedupe keeps first-insertion order, so
|
|
210
|
-
// list is stable across runs.
|
|
323
|
+
// Set-dedupe keeps first-insertion order, so the interpreter stays first and
|
|
324
|
+
// the list is stable across runs.
|
|
211
325
|
return [...new Set(out)];
|
|
212
326
|
}
|
|
213
327
|
/**
|
|
@@ -52,7 +52,24 @@ function discoverTypelibs(projectDir, dirs) {
|
|
|
52
52
|
'A missing directory here means the package would install without the typelib it promises.');
|
|
53
53
|
}
|
|
54
54
|
for (const file of listFilesRecursive(root)) {
|
|
55
|
-
|
|
55
|
+
// Every shared-library spelling, not only ELF's. A typelib is
|
|
56
|
+
// useless without its library on macOS and Windows too, and the
|
|
57
|
+
// `.so`-only test dropped `libgwebgl.dylib` and `gwebgl-0.dll` while
|
|
58
|
+
// staging the `.typelib` beside them — a package that installs and
|
|
59
|
+
// dies at the first import, with nothing in the output saying so.
|
|
60
|
+
// The layout axis (ADR 0024 § 2) is what put those two files in
|
|
61
|
+
// reach: they land in `Contents/Frameworks` and in the program
|
|
62
|
+
// directory's `lib\`.
|
|
63
|
+
// Case-insensitive for the extensions that come off case-preserving-
|
|
64
|
+
// but-INSENSITIVE filesystems — `LIBFOO.DLL` and `Foo.Dylib` are
|
|
65
|
+
// ordinary names on macOS and Windows, and a lowercase-only test drops
|
|
66
|
+
// them into exactly the silent failure the paragraph above describes.
|
|
67
|
+
//
|
|
68
|
+
// NOT for `.so`, and the asymmetry is the reason rather than an
|
|
69
|
+
// oversight: ELF sonames come off case-SENSITIVE filesystems where
|
|
70
|
+
// `libfoo.so` is the only spelling, and `/i` there additionally makes
|
|
71
|
+
// `README.SO` a shared library. One rationale, one scope.
|
|
72
|
+
if (/\.(typelib|dylib|dll)$/i.test(file) || /\.so(\.\d+)*$/.test(file))
|
|
56
73
|
out.push(join(root, file));
|
|
57
74
|
}
|
|
58
75
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { PackSettings } from './types.js';
|
|
2
|
+
/** The tool this packer execs. One spelling, read by this module AND by the format row. */
|
|
3
|
+
export declare const DMG_TOOL = "hdiutil";
|
|
4
|
+
/**
|
|
5
|
+
* What the mounted image is called in the Finder's sidebar.
|
|
6
|
+
*
|
|
7
|
+
* The DISPLAY name, like the `.app` inside it — the volume and the bundle are
|
|
8
|
+
* the two things a user reads during the one interaction this format has, and
|
|
9
|
+
* spelling them differently (`Ship Demo.app` inside `ship-demo-1.2.3`) makes the
|
|
10
|
+
* window look like somebody else's download. The FILE keeps the versioned,
|
|
11
|
+
* space-free name, because that one lands in a downloads folder beside others;
|
|
12
|
+
* `FormatDescriptor.fileName` is where that split lives, exactly as it does for
|
|
13
|
+
* the `.app` and its zip.
|
|
14
|
+
*
|
|
15
|
+
* EMPTY IS REFUSED, and it is not defensive: `resolveShipSettings` derives the
|
|
16
|
+
* name as `metadata.name ?? titleCase(binaryName)` and `??` passes `''` straight
|
|
17
|
+
* through — the same hole `windowsProgramDirName` documents. `hdiutil` answers an
|
|
18
|
+
* empty `-volname` by calling the volume `untitled`, at exit 0, so the image
|
|
19
|
+
* would build and mount under a name nothing in the project ever chose.
|
|
20
|
+
*/
|
|
21
|
+
export declare function dmgVolumeName(settings: PackSettings): string;
|
|
22
|
+
export interface DmgCreateInput {
|
|
23
|
+
/** The volume label — see {@link dmgVolumeName}. */
|
|
24
|
+
volumeName: string;
|
|
25
|
+
/** The directory whose CONTENTS become the volume root; it holds `<App>.app` and nothing else. */
|
|
26
|
+
sourceDir: string;
|
|
27
|
+
/** Absolute path the finished `.dmg` is written to. */
|
|
28
|
+
target: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The exact `hdiutil` invocation, as data.
|
|
32
|
+
*
|
|
33
|
+
* Pure, so every flag is unit-testable from Linux — which is the only kind of
|
|
34
|
+
* host this project's contributors and its `e2e` job have. Same split as
|
|
35
|
+
* `renderShipFlatpakManifest`: what the tool is TOLD is checkable everywhere,
|
|
36
|
+
* what the tool DOES is checkable on the one OS that has it, and the two are not
|
|
37
|
+
* the same test.
|
|
38
|
+
*
|
|
39
|
+
* `-srcfolder` and not `-srcdevice`/`-size`: the folder's contents become the
|
|
40
|
+
* volume root, so `hdiutil` sizes the image itself. Passing a `-size` instead is
|
|
41
|
+
* how a `.dmg` build starts failing on the day the payload grows past a number
|
|
42
|
+
* somebody typed once.
|
|
43
|
+
*/
|
|
44
|
+
export declare function hdiutilCreateArgs(input: DmgCreateInput): string[];
|
|
45
|
+
export interface DmgPackInput extends DmgCreateInput {
|
|
46
|
+
verbose: boolean;
|
|
47
|
+
/** Working root, so the log can name the directory that became the volume. */
|
|
48
|
+
workDir: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Build the image at `input.target`.
|
|
52
|
+
*
|
|
53
|
+
* Unlike the Flatpak packer's tool, this one cannot be installed where it is
|
|
54
|
+
* missing: `hdiutil` ships with macOS and exists nowhere else. So the `notFound` branch does not say "install
|
|
55
|
+
* it"; it says which host this belongs on and how the payload gets there, which
|
|
56
|
+
* is the same two-phase sentence `assertHostCanFinish` prints one step earlier.
|
|
57
|
+
* Reaching this branch at all means `process.platform` said darwin and `hdiutil`
|
|
58
|
+
* was still absent, so the honest advice is "this macOS installation is broken",
|
|
59
|
+
* not a package name.
|
|
60
|
+
*/
|
|
61
|
+
export declare function buildDmgImage(input: DmgPackInput): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Where the volume is assembled before `hdiutil` turns it into an image.
|
|
64
|
+
*
|
|
65
|
+
* A directory of its own under the run's output root, never `out/` itself: the
|
|
66
|
+
* volume root holds the `.app` and NOTHING ELSE, because `-srcfolder` copies
|
|
67
|
+
* whatever it finds — a stray sibling would ride into the image, and the reader
|
|
68
|
+
* that would catch it is the same listing comparison that would then have to be
|
|
69
|
+
* relaxed to allow it.
|
|
70
|
+
*/
|
|
71
|
+
export declare function dmgVolumeDir(outRoot: string): string;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
// The `.dmg` packer — ADR 0024 § A1/§ A6, issue #1354 M4.
|
|
2
|
+
//
|
|
3
|
+
// THE FIRST FORMAT THAT IS HOST-BOUND IN THE `HostRequirement` SENSE, and the
|
|
4
|
+
// distinction ADR 0024 § A3 drew between its two refusals is what this row is
|
|
5
|
+
// the first subject of. A Flatpak is `finishOn: ['linux']` because flatpak runs
|
|
6
|
+
// on Linux — the format is bound the way the application is. A `.dmg` is bound
|
|
7
|
+
// by the CONTAINER: it is a UDIF image over a real HFS+/APFS volume, no
|
|
8
|
+
// HFS+/APFS writer exists anywhere in this tree, and `hdiutil` is macOS-only.
|
|
9
|
+
// So `assertHostCanFinish` refuses it off darwin and `assertToolsInstalled`
|
|
10
|
+
// names `hdiutil` on a darwin host that somehow lacks it — two failures with
|
|
11
|
+
// two different fixes, which is exactly why they are two functions.
|
|
12
|
+
//
|
|
13
|
+
// A HAND-WRITTEN UDIF WRITER STAYS REJECTED (§ A6), in that section's own
|
|
14
|
+
// words: 1200-2000 lines against a whole existing packer surface of ~1243, and
|
|
15
|
+
// every mistake silent, because the Finder mounts the image and shows an empty
|
|
16
|
+
// window. What we would buy is an independent reader, and 7-Zip already
|
|
17
|
+
// advertises `Dmg`, `HFS` and `APFS` handlers regardless of who wrote the file.
|
|
18
|
+
//
|
|
19
|
+
// WHICH MAKES THE ORACLE THE INTERESTING PART, because `hdiutil verify` is
|
|
20
|
+
// `hdiutil` reading what `hdiutil` wrote. The reader is a chain that runs on
|
|
21
|
+
// LINUX — `7z l` (7-Zip 23.01 on ubuntu-24.04 carries `Dmg`, `HFS` and `APFS`),
|
|
22
|
+
// `7z t` to inflate what it stores, then `dmg2img` to a raw volume and
|
|
23
|
+
// `fsck.hfsplus -f -n` over that — driven by `.github/ship-oracle/verify-dmg.py`
|
|
24
|
+
// and compared against the stage manifest by name, size and MODE. Three
|
|
25
|
+
// implementations, none of them Apple's and none of them ours.
|
|
26
|
+
//
|
|
27
|
+
// TWO hdiutil FLAGS ARE DECISIONS AND NOT DEFAULTS:
|
|
28
|
+
//
|
|
29
|
+
// * `-fs HFS+J`. APFS is what a modern `hdiutil` reaches for when nothing says
|
|
30
|
+
// otherwise, and the whole Linux reader chain above is an HFS+ chain —
|
|
31
|
+
// `dmg2img` writes a raw volume and `fsck.hfsplus` is an HFS+ fsck. An APFS
|
|
32
|
+
// image would leave 7-Zip's handler as the only reader, i.e. one reader for
|
|
33
|
+
// the negative control to fool. Journaling costs a read-only image nothing
|
|
34
|
+
// and `fsck.hfsplus` reads it: measured on ubuntu-24.04 / hfsprogs
|
|
35
|
+
// 540.1.linux3-5build3 against a `mkfs.hfsplus -J` volume, "** Checking
|
|
36
|
+
// Journaled HFS Plus volume … appears to be OK", exit 0.
|
|
37
|
+
// * `-format UDZO`, i.e. zlib. The alternatives are ULFO (LZFSE) and ULMO
|
|
38
|
+
// (LZMA), and the reader that would have to decode them is the OLD one:
|
|
39
|
+
// ubuntu-24.04 ships 7-Zip 23.01, not this workstation's 26.02. zlib is the
|
|
40
|
+
// method its `Dmg` handler has read since long before either.
|
|
41
|
+
//
|
|
42
|
+
// WHAT THIS PACKER DOES NOT PUT IN THE VOLUME: an `/Applications` symlink, the
|
|
43
|
+
// drag-here convention. `writePayload` writes regular files and nothing else —
|
|
44
|
+
// which is a property `tests/e2e/ship` and the `ship-stage` job both assert, and
|
|
45
|
+
// a symlink is also what `actions/upload-artifact` silently dereferences. The
|
|
46
|
+
// artifact is still draggable out of the mounted volume; what it lacks is the
|
|
47
|
+
// arrow. Unblocker: a staged-symlink concept with a reader that can see one, at
|
|
48
|
+
// which point the link and its oracle land together.
|
|
49
|
+
import { join } from 'node:path';
|
|
50
|
+
import { describeExit, spawnToCompletion } from '../spawn.js';
|
|
51
|
+
/** The tool this packer execs. One spelling, read by this module AND by the format row. */
|
|
52
|
+
export const DMG_TOOL = 'hdiutil';
|
|
53
|
+
/**
|
|
54
|
+
* Characters an HFS+ volume name may not contain.
|
|
55
|
+
*
|
|
56
|
+
* Two of the three `layout.ts` refuses in a bundle DIRECTORY name — its
|
|
57
|
+
* `BUNDLE_NAME_FORBIDDEN` is `/[/:\\]/` — and for the same measured reason: `/`
|
|
58
|
+
* is the POSIX separator and `:` is HFS+'s, and the Finder shows a stored `:` as
|
|
59
|
+
* a `/` and vice versa. A volume called `Ship/Demo` mounts as `Ship:Demo`, so the
|
|
60
|
+
* name a user is told to look for is not the name they see. `\` is the one that
|
|
61
|
+
* is NOT here: it is an ordinary character in a volume name, while a bundle
|
|
62
|
+
* directory refuses it too and `windowsProgramDirName` refuses it for Windows'
|
|
63
|
+
* own reasons.
|
|
64
|
+
*/
|
|
65
|
+
const VOLUME_NAME_FORBIDDEN = /[/:]/;
|
|
66
|
+
/**
|
|
67
|
+
* What the mounted image is called in the Finder's sidebar.
|
|
68
|
+
*
|
|
69
|
+
* The DISPLAY name, like the `.app` inside it — the volume and the bundle are
|
|
70
|
+
* the two things a user reads during the one interaction this format has, and
|
|
71
|
+
* spelling them differently (`Ship Demo.app` inside `ship-demo-1.2.3`) makes the
|
|
72
|
+
* window look like somebody else's download. The FILE keeps the versioned,
|
|
73
|
+
* space-free name, because that one lands in a downloads folder beside others;
|
|
74
|
+
* `FormatDescriptor.fileName` is where that split lives, exactly as it does for
|
|
75
|
+
* the `.app` and its zip.
|
|
76
|
+
*
|
|
77
|
+
* EMPTY IS REFUSED, and it is not defensive: `resolveShipSettings` derives the
|
|
78
|
+
* name as `metadata.name ?? titleCase(binaryName)` and `??` passes `''` straight
|
|
79
|
+
* through — the same hole `windowsProgramDirName` documents. `hdiutil` answers an
|
|
80
|
+
* empty `-volname` by calling the volume `untitled`, at exit 0, so the image
|
|
81
|
+
* would build and mount under a name nothing in the project ever chose.
|
|
82
|
+
*/
|
|
83
|
+
export function dmgVolumeName(settings) {
|
|
84
|
+
const name = settings.name;
|
|
85
|
+
if (name.trim() === '') {
|
|
86
|
+
throw new Error('gjsify ship: the macOS image has no name to call its volume — `gjsify.ship.name` (or the ' +
|
|
87
|
+
'package name it is derived from) is empty. `hdiutil` would accept that and mount the ' +
|
|
88
|
+
'image as `untitled`, which is the name every nameless disk image on the machine has.');
|
|
89
|
+
}
|
|
90
|
+
if (VOLUME_NAME_FORBIDDEN.test(name)) {
|
|
91
|
+
throw new Error(`gjsify ship: the macOS image would mount a volume called "${name}", and HFS+ cannot hold it: ` +
|
|
92
|
+
'the Finder shows a stored ":" as a "/" and a stored "/" as a ":", so the volume would not ' +
|
|
93
|
+
'be the one this project named. Set `gjsify.ship.name` to the display name you want.');
|
|
94
|
+
}
|
|
95
|
+
return name;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The exact `hdiutil` invocation, as data.
|
|
99
|
+
*
|
|
100
|
+
* Pure, so every flag is unit-testable from Linux — which is the only kind of
|
|
101
|
+
* host this project's contributors and its `e2e` job have. Same split as
|
|
102
|
+
* `renderShipFlatpakManifest`: what the tool is TOLD is checkable everywhere,
|
|
103
|
+
* what the tool DOES is checkable on the one OS that has it, and the two are not
|
|
104
|
+
* the same test.
|
|
105
|
+
*
|
|
106
|
+
* `-srcfolder` and not `-srcdevice`/`-size`: the folder's contents become the
|
|
107
|
+
* volume root, so `hdiutil` sizes the image itself. Passing a `-size` instead is
|
|
108
|
+
* how a `.dmg` build starts failing on the day the payload grows past a number
|
|
109
|
+
* somebody typed once.
|
|
110
|
+
*/
|
|
111
|
+
export function hdiutilCreateArgs(input) {
|
|
112
|
+
return [
|
|
113
|
+
'create',
|
|
114
|
+
// Read-only + zlib. See the header: the alternatives are decodable only
|
|
115
|
+
// by a newer 7-Zip than the reader leg has.
|
|
116
|
+
'-format',
|
|
117
|
+
'UDZO',
|
|
118
|
+
// HFS+ EXPLICITLY, because the default is the thing the reader chain
|
|
119
|
+
// cannot read. See the header.
|
|
120
|
+
'-fs',
|
|
121
|
+
'HFS+J',
|
|
122
|
+
'-volname',
|
|
123
|
+
input.volumeName,
|
|
124
|
+
'-srcfolder',
|
|
125
|
+
input.sourceDir,
|
|
126
|
+
// hdiutil REFUSES an existing target rather than replacing it, and
|
|
127
|
+
// `packOne` writes into `out/` which a previous run may have filled. The
|
|
128
|
+
// failure without this is a pack that dies on its second invocation only.
|
|
129
|
+
'-ov',
|
|
130
|
+
// Progress on a TTY is a spinner; in a CI log it is thousands of lines.
|
|
131
|
+
'-quiet',
|
|
132
|
+
input.target,
|
|
133
|
+
];
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Build the image at `input.target`.
|
|
137
|
+
*
|
|
138
|
+
* Unlike the Flatpak packer's tool, this one cannot be installed where it is
|
|
139
|
+
* missing: `hdiutil` ships with macOS and exists nowhere else. So the `notFound` branch does not say "install
|
|
140
|
+
* it"; it says which host this belongs on and how the payload gets there, which
|
|
141
|
+
* is the same two-phase sentence `assertHostCanFinish` prints one step earlier.
|
|
142
|
+
* Reaching this branch at all means `process.platform` said darwin and `hdiutil`
|
|
143
|
+
* was still absent, so the honest advice is "this macOS installation is broken",
|
|
144
|
+
* not a package name.
|
|
145
|
+
*/
|
|
146
|
+
export async function buildDmgImage(input) {
|
|
147
|
+
const args = hdiutilCreateArgs(input);
|
|
148
|
+
if (input.verbose)
|
|
149
|
+
console.log(`[gjsify ship] ${DMG_TOOL} ${args.join(' ')}`);
|
|
150
|
+
// `completion: 'return'`, matching the Flatpak packer: `ship` packs the
|
|
151
|
+
// remaining formats and prints the artifact list afterwards, so it cannot end
|
|
152
|
+
// in `process.exit()`. Under GJS that selects the blocking path, which
|
|
153
|
+
// captures the child's output and re-emits it — the documented cost of a
|
|
154
|
+
// spawn a caller has to return from (`utils/spawn.ts`), and why `--verbose`
|
|
155
|
+
// prints the invocation before the silence starts.
|
|
156
|
+
const result = await spawnToCompletion(DMG_TOOL, args, {
|
|
157
|
+
completion: 'return',
|
|
158
|
+
cwd: input.workDir,
|
|
159
|
+
stdio: 'inherit',
|
|
160
|
+
notFound: () => new Error(`gjsify ship: ${DMG_TOOL} is not on PATH. It ships with macOS and cannot be installed ` +
|
|
161
|
+
'anywhere else, so this is either a broken macOS installation or a host that is not ' +
|
|
162
|
+
'macOS at all. A `.dmg` is packed on darwin (ADR 0024 § A1); from anywhere else the ' +
|
|
163
|
+
'route is `gjsify ship darwin --stage` here and `gjsify ship --from-stage <dir> ' +
|
|
164
|
+
'--target macos-app-dmg` there.'),
|
|
165
|
+
});
|
|
166
|
+
if (result.code !== 0) {
|
|
167
|
+
throw new Error(`gjsify ship: ${DMG_TOOL} failed with ${describeExit(result)}.`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Where the volume is assembled before `hdiutil` turns it into an image.
|
|
172
|
+
*
|
|
173
|
+
* A directory of its own under the run's output root, never `out/` itself: the
|
|
174
|
+
* volume root holds the `.app` and NOTHING ELSE, because `-srcfolder` copies
|
|
175
|
+
* whatever it finds — a stray sibling would ride into the image, and the reader
|
|
176
|
+
* that would catch it is the same listing comparison that would then have to be
|
|
177
|
+
* relaxed to allow it.
|
|
178
|
+
*/
|
|
179
|
+
export function dmgVolumeDir(outRoot) {
|
|
180
|
+
return join(outRoot, 'dmg', 'volume');
|
|
181
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { ConfigDataFlatpak, ConfigDataShip, ShipFlatpakOptions } from '../../types/config-data.js';
|
|
2
|
+
import type { ShipFlatpakSettings } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The release that stops reading `gjsify.flatpak` for the keys below.
|
|
5
|
+
*
|
|
6
|
+
* A major, not the next minor: the block is in published releases and in
|
|
7
|
+
* downstream `package.json`s that this repository does not control, and a
|
|
8
|
+
* window measured in weeks is a window nobody notices before it closes.
|
|
9
|
+
*/
|
|
10
|
+
export declare const LEGACY_FLATPAK_KEYS_REMOVED_IN = "1.0.0";
|
|
11
|
+
/** The keys whose new home is `gjsify.ship.flatpak`, in the order the warning lists them. */
|
|
12
|
+
export declare const MIGRATED_FLATPAK_KEYS: readonly ["runtime", "runtimeVersion", "sdkExtensions", "appendPath", "finishArgs", "cleanup"];
|
|
13
|
+
export type MigratedFlatpakKey = (typeof MIGRATED_FLATPAK_KEYS)[number];
|
|
14
|
+
/** The six keys as a reader sees them, before any default is applied. */
|
|
15
|
+
export type MigratedFlatpakValues = {
|
|
16
|
+
[K in MigratedFlatpakKey]: ConfigDataFlatpak[K];
|
|
17
|
+
};
|
|
18
|
+
export interface PickedFlatpakBuildKeys {
|
|
19
|
+
values: MigratedFlatpakValues;
|
|
20
|
+
/** Keys that came from `gjsify.flatpak`, in {@link MIGRATED_FLATPAK_KEYS} order. */
|
|
21
|
+
fromLegacy: MigratedFlatpakKey[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* `gjsify.ship.flatpak.<key>` when set, else `gjsify.flatpak.<key>` — per KEY,
|
|
25
|
+
* noting which side answered.
|
|
26
|
+
*
|
|
27
|
+
* Per-key and not per-block: a project migrating one key at a time must not
|
|
28
|
+
* lose the five it has not moved yet. That is also what makes the warning
|
|
29
|
+
* actionable — it names the keys still coming from the old block, so the reader
|
|
30
|
+
* knows what to edit rather than being told a block is deprecated.
|
|
31
|
+
*
|
|
32
|
+
* A LOOP over {@link MIGRATED_FLATPAK_KEYS}, not six hand-written picks. Written
|
|
33
|
+
* out, the list was the one unbound copy of this vocabulary: a key added to it
|
|
34
|
+
* with no `pick` call behind it compiled fine, went missing from the window, and
|
|
35
|
+
* the only test that mentioned the constant compared it to a literal copy of
|
|
36
|
+
* itself. Reading the keys off the constant is what makes "this list IS the
|
|
37
|
+
* window" true rather than asserted.
|
|
38
|
+
*
|
|
39
|
+
* NO default is applied here. The defaults differ per reader — `ship` derives
|
|
40
|
+
* `finishArgs` from `kind`, `flatpak init` also merges `--sdk-extension` flags —
|
|
41
|
+
* and a default applied here would be a third answer neither of them chose.
|
|
42
|
+
*/
|
|
43
|
+
export declare function pickFlatpakBuildKeys(preferred: ShipFlatpakOptions | undefined, legacy: ConfigDataFlatpak): PickedFlatpakBuildKeys;
|
|
44
|
+
/** The branch a `ship` Flatpak is exported under when the project names none. */
|
|
45
|
+
export declare const DEFAULT_SHIP_FLATPAK_BRANCH = "stable";
|
|
46
|
+
export interface ShipFlatpakInput {
|
|
47
|
+
ship: ConfigDataShip;
|
|
48
|
+
flatpak: ConfigDataFlatpak;
|
|
49
|
+
/** Decides the finish-args default: a GUI app needs a display, a CLI does not. */
|
|
50
|
+
kind: 'app' | 'cli';
|
|
51
|
+
}
|
|
52
|
+
export interface ResolvedShipFlatpak {
|
|
53
|
+
settings: ShipFlatpakSettings;
|
|
54
|
+
warnings: string[];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Resolve the Flatpak half of `gjsify.ship`, reading the legacy block where the
|
|
58
|
+
* new one is silent, and applying `ship`'s own defaults.
|
|
59
|
+
*
|
|
60
|
+
* The per-key fallback itself is {@link pickFlatpakBuildKeys}, shared with
|
|
61
|
+
* `gjsify flatpak init`/`ci`; what is `ship`-specific and stays here is the
|
|
62
|
+
* defaulting — `branch`, the `kind`-dependent finish-args, the derived
|
|
63
|
+
* `appendPath` — plus the warning, which only `ship` prints because only `ship`
|
|
64
|
+
* has somewhere else to point at.
|
|
65
|
+
*/
|
|
66
|
+
export declare function resolveShipFlatpakSettings(input: ShipFlatpakInput): ResolvedShipFlatpak;
|