@gtkx/cli 2.0.0-beta.7 → 2.0.0-beta.9
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/commands/deploy.d.ts +4 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +6 -0
- package/dist/commands/deploy.js.map +1 -1
- package/dist/deploy/depends.d.ts.map +1 -1
- package/dist/deploy/depends.js +24 -2
- package/dist/deploy/depends.js.map +1 -1
- package/dist/deploy/download.d.ts +7 -3
- package/dist/deploy/download.d.ts.map +1 -1
- package/dist/deploy/download.js +19 -15
- package/dist/deploy/download.js.map +1 -1
- package/dist/deploy/native-addon.d.ts +5 -0
- package/dist/deploy/native-addon.d.ts.map +1 -0
- package/dist/deploy/native-addon.js +134 -0
- package/dist/deploy/native-addon.js.map +1 -0
- package/dist/deploy/node-runtime/download.js +2 -2
- package/dist/deploy/node-runtime/download.js.map +1 -1
- package/dist/deploy/node-runtime/elf.d.ts +3 -1
- package/dist/deploy/node-runtime/elf.d.ts.map +1 -1
- package/dist/deploy/node-runtime/elf.js +3 -1
- package/dist/deploy/node-runtime/elf.js.map +1 -1
- package/dist/deploy/node-runtime/guard.d.ts.map +1 -1
- package/dist/deploy/node-runtime/guard.js +7 -14
- package/dist/deploy/node-runtime/guard.js.map +1 -1
- package/dist/deploy/node-runtime/index.d.ts +2 -1
- package/dist/deploy/node-runtime/index.d.ts.map +1 -1
- package/dist/deploy/node-runtime/index.js +29 -6
- package/dist/deploy/node-runtime/index.js.map +1 -1
- package/dist/deploy/node-runtime/sonames.d.ts +5 -0
- package/dist/deploy/node-runtime/sonames.d.ts.map +1 -0
- package/dist/deploy/node-runtime/sonames.js +13 -0
- package/dist/deploy/node-runtime/sonames.js.map +1 -0
- package/dist/deploy/payload/stage.d.ts +2 -1
- package/dist/deploy/payload/stage.d.ts.map +1 -1
- package/dist/deploy/payload/stage.js +22 -2
- package/dist/deploy/payload/stage.js.map +1 -1
- package/dist/deploy/run-deploy.d.ts +1 -0
- package/dist/deploy/run-deploy.d.ts.map +1 -1
- package/dist/deploy/run-deploy.js +139 -80
- package/dist/deploy/run-deploy.js.map +1 -1
- package/dist/deploy/settings/arch.d.ts +9 -3
- package/dist/deploy/settings/arch.d.ts.map +1 -1
- package/dist/deploy/settings/arch.js +27 -6
- package/dist/deploy/settings/arch.js.map +1 -1
- package/dist/deploy/settings/index.d.ts +2 -1
- package/dist/deploy/settings/index.d.ts.map +1 -1
- package/dist/deploy/settings/index.js +2 -1
- package/dist/deploy/settings/index.js.map +1 -1
- package/dist/deploy/settings/paths.d.ts +2 -1
- package/dist/deploy/settings/paths.d.ts.map +1 -1
- package/dist/deploy/settings/paths.js +6 -5
- package/dist/deploy/settings/paths.js.map +1 -1
- package/dist/deploy/targets/appimage.d.ts.map +1 -1
- package/dist/deploy/targets/appimage.js +1 -0
- package/dist/deploy/targets/appimage.js.map +1 -1
- package/dist/deploy/targets/flatpak-pnpm.js +4 -4
- package/dist/deploy/targets/flatpak-pnpm.js.map +1 -1
- package/dist/deploy/targets/flatpak.d.ts.map +1 -1
- package/dist/deploy/targets/flatpak.js +1 -0
- package/dist/deploy/targets/flatpak.js.map +1 -1
- package/dist/deploy/targets/nfpm-target.d.ts.map +1 -1
- package/dist/deploy/targets/nfpm-target.js +1 -0
- package/dist/deploy/targets/nfpm-target.js.map +1 -1
- package/dist/deploy/types.d.ts +4 -2
- package/dist/deploy/types.d.ts.map +1 -1
- package/dist/deploy/types.js.map +1 -1
- package/dist/deploy/vendored/appimagetool.js +2 -2
- package/dist/deploy/vendored/appimagetool.js.map +1 -1
- package/dist/deploy/vendored/nfpm.js +1 -1
- package/dist/deploy/vendored/nfpm.js.map +1 -1
- package/dist/dev/font-dir.d.ts +1 -1
- package/dist/dev/font-dir.d.ts.map +1 -1
- package/dist/dev/font-dir.js +0 -3
- package/dist/dev/font-dir.js.map +1 -1
- package/dist/dev/runner.d.ts.map +1 -1
- package/dist/dev/runner.js +19 -6
- package/dist/dev/runner.js.map +1 -1
- package/dist/internal/font-staging.d.ts +5 -2
- package/dist/internal/font-staging.d.ts.map +1 -1
- package/dist/internal/font-staging.js +76 -27
- package/dist/internal/font-staging.js.map +1 -1
- package/dist/internal/icon-staging.d.ts +3 -0
- package/dist/internal/icon-staging.d.ts.map +1 -0
- package/dist/internal/icon-staging.js +40 -0
- package/dist/internal/icon-staging.js.map +1 -0
- package/dist/internal/source-imports.js +1 -1
- package/dist/internal/source-imports.js.map +1 -1
- package/dist/vite-plugins/font-worker-env.d.ts.map +1 -1
- package/dist/vite-plugins/font-worker-env.js +2 -5
- package/dist/vite-plugins/font-worker-env.js.map +1 -1
- package/dist/vite-plugins/font.d.ts.map +1 -1
- package/dist/vite-plugins/font.js +16 -4
- package/dist/vite-plugins/font.js.map +1 -1
- package/dist/vite-plugins/icon-worker-env.d.ts +4 -0
- package/dist/vite-plugins/icon-worker-env.d.ts.map +1 -0
- package/dist/vite-plugins/icon-worker-env.js +23 -0
- package/dist/vite-plugins/icon-worker-env.js.map +1 -0
- package/dist/vite-plugins/icons.js +2 -2
- package/dist/vite-plugins/icons.js.map +1 -1
- package/dist/vite-plugins/react-compiler.js +2 -2
- package/dist/vite-plugins/react-compiler.js.map +1 -1
- package/dist/vite-plugins/resources.js +2 -2
- package/dist/vite-plugins/resources.js.map +1 -1
- package/dist/vite-plugins/settings-worker-env.js +2 -2
- package/dist/vite-plugins/settings-worker-env.js.map +1 -1
- package/dist/vite-plugins/store-links.d.ts.map +1 -1
- package/dist/vite-plugins/store-links.js +2 -1
- package/dist/vite-plugins/store-links.js.map +1 -1
- package/dist/vite-plugins/undeclared-library.js +2 -2
- package/dist/vite-plugins/undeclared-library.js.map +1 -1
- package/dist/vite-plugins/worker.d.ts.map +1 -1
- package/dist/vite-plugins/worker.js +21 -13
- package/dist/vite-plugins/worker.js.map +1 -1
- package/dist/vitest-plugin.d.ts +2 -2
- package/dist/vitest-plugin.d.ts.map +1 -1
- package/dist/vitest-plugin.js +4 -2
- package/dist/vitest-plugin.js.map +1 -1
- package/package.json +13 -13
- package/src/commands/deploy.ts +6 -0
- package/src/deploy/depends.ts +30 -3
- package/src/deploy/download.ts +33 -17
- package/src/deploy/native-addon.ts +183 -0
- package/src/deploy/node-runtime/download.ts +2 -2
- package/src/deploy/node-runtime/elf.ts +4 -1
- package/src/deploy/node-runtime/guard.ts +10 -14
- package/src/deploy/node-runtime/index.ts +42 -7
- package/src/deploy/node-runtime/sonames.ts +17 -0
- package/src/deploy/payload/stage.ts +34 -2
- package/src/deploy/run-deploy.ts +209 -94
- package/src/deploy/settings/arch.ts +40 -8
- package/src/deploy/settings/index.ts +4 -1
- package/src/deploy/settings/paths.ts +8 -6
- package/src/deploy/targets/appimage.ts +1 -0
- package/src/deploy/targets/flatpak-pnpm.ts +4 -4
- package/src/deploy/targets/flatpak.ts +1 -0
- package/src/deploy/targets/nfpm-target.ts +1 -0
- package/src/deploy/types.ts +4 -1
- package/src/deploy/vendored/appimagetool.ts +2 -2
- package/src/deploy/vendored/nfpm.ts +1 -1
- package/src/dev/font-dir.ts +1 -6
- package/src/dev/runner.ts +24 -6
- package/src/internal/font-staging.ts +99 -27
- package/src/internal/icon-staging.ts +58 -0
- package/src/internal/source-imports.ts +1 -1
- package/src/vite-plugins/font-worker-env.ts +2 -6
- package/src/vite-plugins/font.ts +21 -3
- package/src/vite-plugins/icon-worker-env.ts +36 -0
- package/src/vite-plugins/icons.ts +2 -2
- package/src/vite-plugins/react-compiler.ts +2 -2
- package/src/vite-plugins/resources.ts +2 -2
- package/src/vite-plugins/settings-worker-env.ts +2 -2
- package/src/vite-plugins/store-links.ts +2 -1
- package/src/vite-plugins/undeclared-library.ts +2 -2
- package/src/vite-plugins/worker.ts +31 -15
- package/src/vitest-plugin.ts +4 -2
package/src/deploy/run-deploy.ts
CHANGED
|
@@ -3,7 +3,9 @@ import { info, warn } from "@gtkx/utils";
|
|
|
3
3
|
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { dirname, join, relative } from "node:path";
|
|
5
5
|
import type {
|
|
6
|
+
DeployArchName,
|
|
6
7
|
DeployArtifact,
|
|
8
|
+
DeployConfig,
|
|
7
9
|
DeployManifest,
|
|
8
10
|
DeployPayload,
|
|
9
11
|
DeploySettings,
|
|
@@ -29,10 +31,12 @@ import { extractMetadataMessages, localizeMetadata } from "./freedesktop/localiz
|
|
|
29
31
|
import { renderMetainfo } from "./freedesktop/metainfo.js";
|
|
30
32
|
import { renderMimePackage } from "./freedesktop/mime-package.js";
|
|
31
33
|
import { validateDesktopEntry, validateMetainfo } from "./freedesktop/validate.js";
|
|
32
|
-
import {
|
|
34
|
+
import { resolveStagedAddon } from "./native-addon.js";
|
|
35
|
+
import { assertPortableRuntimeSource, resolveNodeRuntime } from "./node-runtime/index.js";
|
|
33
36
|
import { collectNotices } from "./notices/collect.js";
|
|
34
37
|
import { type StagedMetadata, stageOverlays, stagePayload } from "./payload/stage.js";
|
|
35
38
|
import { DEFAULT_TARGETS, parseTargetList, targetsFor } from "./registry.js";
|
|
39
|
+
import { archesFor, hostArchName, isHostArch, parseArchList } from "./settings/arch.js";
|
|
36
40
|
import { readBuildManifest } from "./settings/build-manifest.js";
|
|
37
41
|
import { resolveDeploySettings } from "./settings/index.js";
|
|
38
42
|
import { readPackageManifest } from "./settings/package-manifest.js";
|
|
@@ -62,31 +66,52 @@ type DeployOptions = {
|
|
|
62
66
|
cwd: string;
|
|
63
67
|
configFile?: string | undefined;
|
|
64
68
|
targets?: string | undefined;
|
|
69
|
+
arches?: string | undefined;
|
|
65
70
|
outDir?: string | undefined;
|
|
66
71
|
shouldPrintManifests: boolean;
|
|
67
72
|
shouldSkipBuild: boolean;
|
|
68
73
|
};
|
|
69
74
|
|
|
70
|
-
type
|
|
75
|
+
type LoadedDeployConfig = {
|
|
76
|
+
config: Config;
|
|
77
|
+
configFile: string;
|
|
78
|
+
root: string;
|
|
79
|
+
deploy: DeployConfig;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
type DeployPlan = {
|
|
83
|
+
loaded: LoadedDeployConfig;
|
|
71
84
|
targets: DeployTarget[];
|
|
72
|
-
|
|
85
|
+
arches: [DeployArchName, ...DeployArchName[]];
|
|
73
86
|
project: CatalogProject | null;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
type PreflightRequest = {
|
|
90
|
+
plan: DeployPlan;
|
|
91
|
+
settings: DeploySettings;
|
|
74
92
|
shouldPrintManifests: boolean;
|
|
75
93
|
shouldSkipBuild: boolean;
|
|
76
94
|
};
|
|
77
95
|
|
|
78
|
-
type
|
|
79
|
-
|
|
80
|
-
|
|
96
|
+
type BuildApplicationRequest = {
|
|
97
|
+
options: DeployOptions;
|
|
98
|
+
plan: DeployPlan;
|
|
81
99
|
settings: DeploySettings;
|
|
100
|
+
buildOutDir: string | null;
|
|
82
101
|
};
|
|
83
102
|
|
|
84
103
|
type BuildPayloadRequest = {
|
|
85
104
|
options: DeployOptions;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
105
|
+
plan: DeployPlan;
|
|
106
|
+
settings: DeploySettings;
|
|
107
|
+
metadata: StagedMetadata;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
type ArchRunRequest = {
|
|
111
|
+
options: DeployOptions;
|
|
112
|
+
plan: DeployPlan;
|
|
113
|
+
arch: DeployArchName;
|
|
114
|
+
metadata: StagedMetadata;
|
|
90
115
|
};
|
|
91
116
|
|
|
92
117
|
const BUILD_MODE = "production";
|
|
@@ -229,17 +254,28 @@ const sourceModeTools = (targets: DeployTarget[], settings: DeploySettings): Dep
|
|
|
229
254
|
const isNodeRequired = (targets: DeployTarget[], settings: DeploySettings): boolean =>
|
|
230
255
|
!(settings.deploy.flatpak?.mode === "source" && targets.every((target) => target.name === FLATPAK_TARGET));
|
|
231
256
|
|
|
232
|
-
const
|
|
233
|
-
|
|
257
|
+
const archiveToolsFor = (settings: DeploySettings): DeployTool[] =>
|
|
258
|
+
(settings.deploy.node?.source ?? "download") === "download" ? [TAR] : [];
|
|
259
|
+
|
|
260
|
+
const stripToolsFor = (settings: DeploySettings, arches: DeployArchName[]): DeployTool[] => {
|
|
261
|
+
if (settings.deploy.node?.shouldStrip === false) {
|
|
234
262
|
return [];
|
|
235
263
|
}
|
|
236
264
|
|
|
237
|
-
|
|
238
|
-
|
|
265
|
+
return arches.some((arch) => isHostArch(arch)) ? [STRIP] : [];
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const runtimeToolsFor = (targets: DeployTarget[], settings: DeploySettings, arches: DeployArchName[]): DeployTool[] => {
|
|
269
|
+
if (!isNodeRequired(targets, settings)) {
|
|
270
|
+
return [];
|
|
271
|
+
}
|
|
239
272
|
|
|
240
|
-
return
|
|
273
|
+
return [...archiveToolsFor(settings), ...stripToolsFor(settings, arches)];
|
|
241
274
|
};
|
|
242
275
|
|
|
276
|
+
const crossBuildToolsFor = (arches: DeployArchName[]): DeployTool[] =>
|
|
277
|
+
arches.every((arch) => isHostArch(arch)) ? [] : [TAR];
|
|
278
|
+
|
|
243
279
|
const mutableCatalogTools = (project: CatalogProject): DeployTool[] => {
|
|
244
280
|
if (project.catalogs.length === 0) {
|
|
245
281
|
return [MSGGREP, XGETTEXT];
|
|
@@ -266,40 +302,77 @@ const catalogTools = (project: CatalogProject | null, shouldSkipBuild: boolean):
|
|
|
266
302
|
return project.catalogs.length === 0 ? [] : [MSGFMT];
|
|
267
303
|
};
|
|
268
304
|
|
|
269
|
-
const preflight = ({
|
|
270
|
-
targets,
|
|
271
|
-
|
|
272
|
-
project,
|
|
273
|
-
shouldPrintManifests,
|
|
274
|
-
shouldSkipBuild,
|
|
275
|
-
}: PreflightRequest): void => {
|
|
305
|
+
const preflight = ({ plan, settings, shouldPrintManifests, shouldSkipBuild }: PreflightRequest): void => {
|
|
306
|
+
const { targets, arches, project } = plan;
|
|
307
|
+
|
|
276
308
|
const packagerTools = shouldPrintManifests
|
|
277
309
|
? []
|
|
278
|
-
: [...runtimeToolsFor(targets, settings), ...targets.flatMap((target) => target.tools)];
|
|
310
|
+
: [...runtimeToolsFor(targets, settings, arches), ...targets.flatMap((target) => target.tools)];
|
|
279
311
|
|
|
280
312
|
const required = [
|
|
281
313
|
DESKTOP_FILE_VALIDATE,
|
|
282
314
|
APPSTREAMCLI,
|
|
315
|
+
...crossBuildToolsFor(arches),
|
|
283
316
|
...catalogTools(project, shouldSkipBuild),
|
|
284
317
|
...sourceModeTools(targets, settings),
|
|
285
318
|
];
|
|
286
319
|
|
|
287
320
|
const report = probeTools([...required, ...packagerTools]);
|
|
288
321
|
assertTools(report);
|
|
322
|
+
|
|
323
|
+
if (isNodeRequired(targets, settings)) {
|
|
324
|
+
assertPortableRuntimeSource(settings);
|
|
325
|
+
}
|
|
326
|
+
|
|
289
327
|
warnMissingOptional(report);
|
|
290
328
|
warnFlatpakPermissions(targets, settings);
|
|
291
329
|
warnLibraryMinimums(targets, settings);
|
|
292
330
|
};
|
|
293
331
|
|
|
294
|
-
const
|
|
332
|
+
const hostOnlyNames = (targets: DeployTarget[]): string[] =>
|
|
333
|
+
targets.filter((target) => target.isHostOnly).map((target) => target.name);
|
|
334
|
+
|
|
335
|
+
const assertCrossBuild = (plan: DeployPlan): void => {
|
|
336
|
+
const foreign = plan.arches.filter((arch) => !isHostArch(arch));
|
|
337
|
+
|
|
338
|
+
if (foreign.length === 0) {
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const hostOnly = hostOnlyNames(plan.targets);
|
|
343
|
+
|
|
344
|
+
if (hostOnly.length > 0) {
|
|
345
|
+
throw new Error(
|
|
346
|
+
`Cannot build ${hostOnly.join(" and ")} for ${foreign.join(" and ")}: those targets package with ` +
|
|
347
|
+
`tooling that only runs on ${hostArchName()}. Deploy them in a separate run without --arch.`,
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if ((plan.loaded.deploy.node?.source ?? "download") !== "download") {
|
|
352
|
+
throw new Error(
|
|
353
|
+
'Cannot deploy for another architecture with a `deploy.node.source` other than "download": ' +
|
|
354
|
+
`a host or path runtime is always ${hostArchName()}.`,
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
const resolveTargetNames = (options: DeployOptions, deploy: DeployConfig): string[] => {
|
|
295
360
|
if (options.targets !== undefined) {
|
|
296
361
|
return parseTargetList(options.targets);
|
|
297
362
|
}
|
|
298
363
|
|
|
299
|
-
return
|
|
364
|
+
return deploy.targets ?? DEFAULT_TARGETS;
|
|
300
365
|
};
|
|
301
366
|
|
|
302
|
-
const
|
|
367
|
+
const resolveArchNames = (options: DeployOptions, deploy: DeployConfig): string[] => {
|
|
368
|
+
if (options.arches !== undefined) {
|
|
369
|
+
return parseArchList(options.arches);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return deploy.architectures ?? [hostArchName()];
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
const loadDeployConfig = async (options: DeployOptions): Promise<LoadedDeployConfig> => {
|
|
303
376
|
const { config, configFile, root } = await loadConfig(options.cwd, {
|
|
304
377
|
mode: BUILD_MODE,
|
|
305
378
|
configFile: options.configFile,
|
|
@@ -309,15 +382,26 @@ const loadSettings = async (options: DeployOptions): Promise<LoadedDeploySetting
|
|
|
309
382
|
throw missingDeployError(config.applicationId, readPackageManifest(root));
|
|
310
383
|
}
|
|
311
384
|
|
|
385
|
+
return { config, configFile, root, deploy: config.deploy };
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
const settingsFor = (plan: DeployPlan, options: DeployOptions, arch: DeployArchName): DeploySettings =>
|
|
389
|
+
resolveDeploySettings({
|
|
390
|
+
root: plan.loaded.root,
|
|
391
|
+
config: plan.loaded.config,
|
|
392
|
+
configFile: plan.loaded.configFile,
|
|
393
|
+
outDirOverride: options.outDir,
|
|
394
|
+
arch,
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
const planDeploy = async (options: DeployOptions): Promise<DeployPlan> => {
|
|
398
|
+
const loaded = await loadDeployConfig(options);
|
|
399
|
+
|
|
312
400
|
return {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
config,
|
|
318
|
-
configFile,
|
|
319
|
-
outDirOverride: options.outDir,
|
|
320
|
-
}),
|
|
401
|
+
loaded,
|
|
402
|
+
targets: targetsFor(resolveTargetNames(options, loaded.deploy)),
|
|
403
|
+
arches: archesFor(resolveArchNames(options, loaded.deploy)),
|
|
404
|
+
project: resolveCatalogProject(loaded.root, loaded.config.applicationId),
|
|
321
405
|
};
|
|
322
406
|
};
|
|
323
407
|
|
|
@@ -347,46 +431,57 @@ const synchronizeMetadataCatalogs = async (
|
|
|
347
431
|
}
|
|
348
432
|
};
|
|
349
433
|
|
|
350
|
-
const
|
|
434
|
+
const buildApplication = async ({
|
|
351
435
|
options,
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
project,
|
|
436
|
+
plan,
|
|
437
|
+
settings,
|
|
355
438
|
buildOutDir,
|
|
356
|
-
}:
|
|
357
|
-
const settings = loaded.settings;
|
|
439
|
+
}: BuildApplicationRequest): Promise<StagedMetadata> => {
|
|
358
440
|
const templates = renderMetadata(settings);
|
|
359
441
|
|
|
360
|
-
if (buildOutDir
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
await buildApp({
|
|
365
|
-
entry: options.entry,
|
|
366
|
-
configFile: options.configFile,
|
|
367
|
-
vite: { root: options.cwd, build: { outDir: preparedOutput.path, emptyOutDir: false } },
|
|
368
|
-
});
|
|
442
|
+
if (buildOutDir === null) {
|
|
443
|
+
if (plan.project !== null) {
|
|
444
|
+
compileCatalogs(plan.project, join(settings.paths.dist, LOCALE_DIRNAME));
|
|
445
|
+
}
|
|
369
446
|
|
|
370
|
-
|
|
371
|
-
await synchronizeMetadataCatalogs(settings, templates, project);
|
|
372
|
-
} else if (project !== null) {
|
|
373
|
-
compileCatalogs(project, join(settings.paths.dist, LOCALE_DIRNAME));
|
|
447
|
+
return localizeMetadata(templates, plan.project);
|
|
374
448
|
}
|
|
375
449
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
450
|
+
info(`Building ${options.entry}`);
|
|
451
|
+
using preparedOutput = prepareBuildOutDir(settings.paths.root, buildOutDir);
|
|
452
|
+
|
|
453
|
+
await buildApp({
|
|
454
|
+
entry: options.entry,
|
|
455
|
+
configFile: options.configFile,
|
|
456
|
+
vite: { root: options.cwd, build: { outDir: preparedOutput.path, emptyOutDir: false } },
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
preparedOutput.commit();
|
|
460
|
+
await synchronizeMetadataCatalogs(settings, templates, plan.project);
|
|
461
|
+
|
|
462
|
+
return localizeMetadata(templates, plan.project);
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
const buildArchPayload = async ({
|
|
466
|
+
options,
|
|
467
|
+
plan,
|
|
468
|
+
settings,
|
|
469
|
+
metadata,
|
|
470
|
+
}: BuildPayloadRequest): Promise<DeployPayload> => {
|
|
471
|
+
validateMetadata(settings, metadata, isFlathubSubmission(settings, plan.targets));
|
|
472
|
+
const buildManifest = readBuildManifest(settings, plan.loaded);
|
|
379
473
|
|
|
380
474
|
const builtSettings: DeploySettings = {
|
|
381
475
|
...settings,
|
|
382
476
|
paths: { ...settings.paths, schemaFiles: buildManifest.schemaFiles },
|
|
383
477
|
};
|
|
384
478
|
|
|
385
|
-
const node = options.shouldPrintManifests || !isNodeRequired(targets, builtSettings)
|
|
479
|
+
const node = options.shouldPrintManifests || !isNodeRequired(plan.targets, builtSettings)
|
|
386
480
|
? null
|
|
387
481
|
: await resolveNodeRuntime(builtSettings);
|
|
388
482
|
|
|
389
|
-
const
|
|
483
|
+
const addon = await resolveStagedAddon(builtSettings);
|
|
484
|
+
const stage = stagePayload({ settings: builtSettings, node, addon, metadata });
|
|
390
485
|
info(`Staged ${String(stage.length)} files into ${displayPath(builtSettings, builtSettings.paths.stage)}`);
|
|
391
486
|
const notices = collectNotices({ settings: builtSettings, node, packages: buildManifest.packages });
|
|
392
487
|
|
|
@@ -438,56 +533,76 @@ const packTargets = async (
|
|
|
438
533
|
return artifacts;
|
|
439
534
|
};
|
|
440
535
|
|
|
441
|
-
const announce = (settings: DeploySettings,
|
|
442
|
-
const names = targets.map((target) => target.name).join(", ");
|
|
536
|
+
const announce = (settings: DeploySettings, plan: DeployPlan): void => {
|
|
537
|
+
const names = plan.targets.map((target) => target.name).join(", ");
|
|
443
538
|
const version = `${settings.versions.packageVersion}-${settings.versions.debRevision}`;
|
|
444
|
-
|
|
539
|
+
const arches = plan.arches.join(", ");
|
|
540
|
+
info(`Deploying ${settings.name} ${version} as ${settings.binaryName} (${arches}) to ${names}`);
|
|
445
541
|
};
|
|
446
542
|
|
|
447
|
-
const
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
let buildOutDir = options.shouldSkipBuild ? null : resolveBuildOutDir(settings.paths.root, settings.paths.dist);
|
|
453
|
-
announce(settings, targets);
|
|
543
|
+
const deployArch = async (request: ArchRunRequest): Promise<DeployArtifact[]> => {
|
|
544
|
+
const { options, plan, arch, metadata } = request;
|
|
545
|
+
const settings = settingsFor(plan, options, arch);
|
|
546
|
+
const payload = await buildArchPayload({ options, plan, settings, metadata });
|
|
547
|
+
const rendered = renderTargetManifests(plan.targets, payload);
|
|
454
548
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
project,
|
|
459
|
-
shouldPrintManifests: options.shouldPrintManifests,
|
|
460
|
-
shouldSkipBuild: options.shouldSkipBuild,
|
|
461
|
-
});
|
|
549
|
+
if (options.shouldPrintManifests) {
|
|
550
|
+
const count = rendered.values().toArray().flat().length;
|
|
551
|
+
info(`Wrote ${String(count)} manifests for ${arch}, 0 packages built`);
|
|
462
552
|
|
|
463
|
-
|
|
464
|
-
await ensureGenerated(options.cwd, {
|
|
465
|
-
shouldAnnounce: true,
|
|
466
|
-
mode: BUILD_MODE,
|
|
467
|
-
configFile: options.configFile,
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
loaded = await loadSettings(options);
|
|
471
|
-
settings = loaded.settings;
|
|
472
|
-
project = resolveCatalogProject(settings.paths.root, settings.applicationId);
|
|
473
|
-
targets = targetsFor(resolveTargetNames(options, settings));
|
|
474
|
-
buildOutDir = resolveBuildOutDir(settings.paths.root, settings.paths.dist);
|
|
553
|
+
return [];
|
|
475
554
|
}
|
|
476
555
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
const rendered = renderTargetManifests(targets, payload);
|
|
556
|
+
return await packTargets(rendered, payload);
|
|
557
|
+
};
|
|
480
558
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
559
|
+
const regenerate = async (options: DeployOptions, plan: DeployPlan): Promise<DeployPlan> => {
|
|
560
|
+
if (options.shouldSkipBuild) {
|
|
561
|
+
return plan;
|
|
562
|
+
}
|
|
484
563
|
|
|
564
|
+
await ensureGenerated(options.cwd, {
|
|
565
|
+
shouldAnnounce: true,
|
|
566
|
+
mode: BUILD_MODE,
|
|
567
|
+
configFile: options.configFile,
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
return await planDeploy(options);
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
const finish = (options: DeployOptions, settings: DeploySettings, artifacts: DeployArtifact[]): void => {
|
|
574
|
+
if (options.shouldPrintManifests) {
|
|
485
575
|
return;
|
|
486
576
|
}
|
|
487
577
|
|
|
488
|
-
const artifacts = await packTargets(rendered, payload);
|
|
489
578
|
const output = displayPath(settings, settings.paths.output);
|
|
490
579
|
info(`Deploy complete: ${String(artifacts.length)} artifacts in ${output}`);
|
|
491
580
|
};
|
|
492
581
|
|
|
582
|
+
const runDeploy = async (options: DeployOptions): Promise<void> => {
|
|
583
|
+
const planned = await planDeploy(options);
|
|
584
|
+
assertCrossBuild(planned);
|
|
585
|
+
announce(settingsFor(planned, options, planned.arches[0]), planned);
|
|
586
|
+
|
|
587
|
+
preflight({
|
|
588
|
+
plan: planned,
|
|
589
|
+
settings: settingsFor(planned, options, planned.arches[0]),
|
|
590
|
+
shouldPrintManifests: options.shouldPrintManifests,
|
|
591
|
+
shouldSkipBuild: options.shouldSkipBuild,
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
const plan = await regenerate(options, planned);
|
|
595
|
+
const settings = settingsFor(plan, options, plan.arches[0]);
|
|
596
|
+
const buildOutDir = options.shouldSkipBuild ? null : resolveBuildOutDir(settings.paths.root, settings.paths.dist);
|
|
597
|
+
prepareDeployOutDir(settings.paths.root, settings.paths.outDir);
|
|
598
|
+
const metadata = await buildApplication({ options, plan, settings, buildOutDir });
|
|
599
|
+
const artifacts: DeployArtifact[] = [];
|
|
600
|
+
|
|
601
|
+
for (const arch of plan.arches) {
|
|
602
|
+
artifacts.push(...await deployArch({ options, plan, arch, metadata }));
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
finish(options, settings, artifacts);
|
|
606
|
+
};
|
|
607
|
+
|
|
493
608
|
export { runDeploy };
|
|
@@ -1,18 +1,50 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { sortStrings } from "@gtkx/utils";
|
|
2
|
+
import type { DeployArch, DeployArchName } from "../types.js";
|
|
2
3
|
|
|
3
|
-
const
|
|
4
|
+
const EM_X86_64 = 62;
|
|
5
|
+
const EM_AARCH64 = 183;
|
|
6
|
+
|
|
7
|
+
const ARCH_TABLE: Record<DeployArchName, DeployArch> = {
|
|
4
8
|
arm64: { deb: "arm64", rpm: "aarch64", flatpak: "aarch64", appimage: "aarch64", node: "arm64" },
|
|
5
9
|
x64: { deb: "amd64", rpm: "x86_64", flatpak: "x86_64", appimage: "x86_64", node: "x64" },
|
|
6
10
|
};
|
|
7
11
|
|
|
8
|
-
const
|
|
9
|
-
|
|
12
|
+
const ELF_MACHINE_TABLE: Record<DeployArchName, number> = {
|
|
13
|
+
arm64: EM_AARCH64,
|
|
14
|
+
x64: EM_X86_64,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const KNOWN_ARCH_NAMES = sortStrings(Object.keys(ARCH_TABLE)).join(", ");
|
|
18
|
+
|
|
19
|
+
const isArchName = (name: string): name is DeployArchName => Object.hasOwn(ARCH_TABLE, name);
|
|
20
|
+
|
|
21
|
+
const assertKnownArch = (name: string): DeployArchName => {
|
|
22
|
+
if (!isArchName(name)) {
|
|
23
|
+
throw new Error(`Cannot deploy for ${name}: only ${KNOWN_ARCH_NAMES} are supported`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return name;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const resolveArch = (name: DeployArchName): DeployArch => ARCH_TABLE[name];
|
|
30
|
+
|
|
31
|
+
const hostArchName = (): DeployArchName => assertKnownArch(process.arch);
|
|
32
|
+
|
|
33
|
+
const isHostArch = (name: DeployArchName): boolean => name === hostArchName();
|
|
34
|
+
|
|
35
|
+
const elfMachineFor = (name: DeployArchName): number => ELF_MACHINE_TABLE[name];
|
|
36
|
+
|
|
37
|
+
const parseArchList = (value: string): string[] => value.split(",").map((name) => name.trim()).filter(Boolean);
|
|
38
|
+
|
|
39
|
+
const archesFor = (names: string[]): [DeployArchName, ...DeployArchName[]] => {
|
|
40
|
+
const requested = sortStrings(new Set(names.map((name) => assertKnownArch(name.trim()))));
|
|
41
|
+
const [first, ...rest] = requested.map((name) => assertKnownArch(name));
|
|
10
42
|
|
|
11
|
-
if (
|
|
12
|
-
throw new Error(`Cannot deploy
|
|
43
|
+
if (first === undefined) {
|
|
44
|
+
throw new Error(`Cannot deploy without an architecture; choose from ${KNOWN_ARCH_NAMES}`);
|
|
13
45
|
}
|
|
14
46
|
|
|
15
|
-
return
|
|
47
|
+
return [first, ...rest];
|
|
16
48
|
};
|
|
17
49
|
|
|
18
|
-
export { resolveArch };
|
|
50
|
+
export { archesFor, elfMachineFor, hostArchName, isHostArch, KNOWN_ARCH_NAMES, parseArchList, resolveArch };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Config } from "@gtkx/config";
|
|
2
2
|
import type {
|
|
3
|
+
DeployArchName,
|
|
3
4
|
DeployConfig,
|
|
4
5
|
DeployDesktopAction,
|
|
5
6
|
DeployDeveloper,
|
|
@@ -32,6 +33,7 @@ type SettingsRequest = {
|
|
|
32
33
|
root: string;
|
|
33
34
|
config: Config;
|
|
34
35
|
configFile: string;
|
|
36
|
+
arch: DeployArchName;
|
|
35
37
|
outDirOverride?: string | undefined;
|
|
36
38
|
now?: Date | undefined;
|
|
37
39
|
};
|
|
@@ -181,13 +183,14 @@ const resolveDeploySettings = (request: SettingsRequest): DeploySettings => {
|
|
|
181
183
|
...desktopSlice(deploy),
|
|
182
184
|
extraFiles: resolveExtraFiles(request.root, deploy),
|
|
183
185
|
versions: core.versions,
|
|
184
|
-
arch: resolveArch(),
|
|
186
|
+
arch: resolveArch(request.arch),
|
|
185
187
|
paths: resolvePaths({
|
|
186
188
|
root: request.root,
|
|
187
189
|
deploy,
|
|
188
190
|
applicationIcon: request.config.applicationIcon,
|
|
189
191
|
applicationId: request.config.applicationId,
|
|
190
192
|
outDirOverride: request.outDirOverride,
|
|
193
|
+
arch: request.arch,
|
|
191
194
|
}),
|
|
192
195
|
...resolveLibraries(request.root, request.config),
|
|
193
196
|
deploy,
|
|
@@ -2,7 +2,7 @@ import type { Config } from "@gtkx/config";
|
|
|
2
2
|
import { isPathInside } from "@gtkx/utils";
|
|
3
3
|
import { lstatSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { join, relative, resolve, sep } from "node:path";
|
|
5
|
-
import type { DeployConfig, DeployPaths } from "../types.js";
|
|
5
|
+
import type { DeployArchName, DeployConfig, DeployPaths } from "../types.js";
|
|
6
6
|
import { resolveApplicationIcon } from "../../internal/icon-path.js";
|
|
7
7
|
import { prepareOutputDirectory, readRegularFile } from "../../internal/output-directory.js";
|
|
8
8
|
|
|
@@ -12,6 +12,7 @@ type PathsRequest = {
|
|
|
12
12
|
applicationIcon: Config["applicationIcon"];
|
|
13
13
|
applicationId: Config["applicationId"];
|
|
14
14
|
outDirOverride: string | undefined;
|
|
15
|
+
arch: DeployArchName;
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
const DEFAULT_OUT_DIR = "build";
|
|
@@ -113,16 +114,17 @@ const resolveLicenseFile = (root: string, configured: string | undefined): strin
|
|
|
113
114
|
const resolvePaths = (request: PathsRequest): DeployPaths => {
|
|
114
115
|
const { root, deploy } = request;
|
|
115
116
|
const outDir = resolveOutDir(request);
|
|
117
|
+
const archDir = join(outDir, request.arch);
|
|
116
118
|
|
|
117
119
|
return {
|
|
118
120
|
root,
|
|
119
121
|
dist: join(root, DIST_DIR),
|
|
120
122
|
outDir,
|
|
121
|
-
metadata: join(
|
|
122
|
-
runtime: join(
|
|
123
|
-
stage: join(
|
|
124
|
-
overlay: join(
|
|
125
|
-
targets: join(
|
|
123
|
+
metadata: join(archDir, "metadata"),
|
|
124
|
+
runtime: join(archDir, "runtime"),
|
|
125
|
+
stage: join(archDir, "stage"),
|
|
126
|
+
overlay: join(archDir, "overlay"),
|
|
127
|
+
targets: join(archDir, "targets"),
|
|
126
128
|
output: join(outDir, "out"),
|
|
127
129
|
applicationIcon: resolveApplicationIcon(root, request.applicationId, request.applicationIcon),
|
|
128
130
|
licenseFile: resolveLicenseFile(root, deploy.licenseFile),
|
|
@@ -29,6 +29,7 @@ const EXTRACT_AND_RUN = "APPIMAGE_EXTRACT_AND_RUN";
|
|
|
29
29
|
const appimageTarget: DeployTarget = {
|
|
30
30
|
name: "appimage",
|
|
31
31
|
prefix: PREFIX,
|
|
32
|
+
isHostOnly: true,
|
|
32
33
|
tools: [FILE_TOOL],
|
|
33
34
|
render: (payload) => renderManifests(payload),
|
|
34
35
|
pack: (payload) => packAppImage(payload),
|
|
@@ -9,12 +9,12 @@ type PnpmPin = {
|
|
|
9
9
|
sha512: string;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
const PNPM_VERSION = "11.
|
|
12
|
+
const PNPM_VERSION = "11.26.0";
|
|
13
13
|
const PNPM_MAJOR = 11;
|
|
14
|
-
const PNPM_MINOR =
|
|
14
|
+
const PNPM_MINOR = 26;
|
|
15
15
|
|
|
16
|
-
const PNPM_SHA512 = "
|
|
17
|
-
"
|
|
16
|
+
const PNPM_SHA512 = "fc0e2bf890b9f983611f1ab68c0637bce914390653699f83c1a78b005ed25f2c81e77920c8" +
|
|
17
|
+
"fd8eee2ecf0b58b28cdcb00a84d97f69bcf7c56b2f344710238664";
|
|
18
18
|
|
|
19
19
|
const PNPM_DIR = "flatpak-pnpm";
|
|
20
20
|
const PNPM_COMMAND = "pnpm";
|
|
@@ -21,6 +21,7 @@ const BUILDER_REF = "org.flatpak.Builder";
|
|
|
21
21
|
const flatpakTarget: DeployTarget = {
|
|
22
22
|
name: "flatpak",
|
|
23
23
|
prefix: PREFIX,
|
|
24
|
+
isHostOnly: true,
|
|
24
25
|
tools: [FLATPAK, FLATPAK_BUILDER, DESKTOP_FILE_VALIDATE, APPSTREAMCLI],
|
|
25
26
|
render: (payload) => renderManifests(payload),
|
|
26
27
|
pack: (payload) => Promise.try(() => packFlatpak(payload)),
|
|
@@ -32,6 +32,7 @@ const packPackage = async (payload: DeployPayload, packager: NfpmPackager): Prom
|
|
|
32
32
|
const nfpmTarget = (packager: NfpmPackager): DeployTarget => ({
|
|
33
33
|
name: packager,
|
|
34
34
|
prefix: PREFIX,
|
|
35
|
+
isHostOnly: false,
|
|
35
36
|
tools: [TAR],
|
|
36
37
|
render: (payload) => renderManifests(payload, packager),
|
|
37
38
|
pack: (payload) => packPackage(payload, packager),
|
package/src/deploy/types.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { Config } from "@gtkx/config";
|
|
|
2
2
|
import type { ResolvedApplicationIcon } from "../internal/icon-path.js";
|
|
3
3
|
|
|
4
4
|
type DeployConfig = NonNullable<Config["deploy"]>;
|
|
5
|
+
type DeployArchName = NonNullable<DeployConfig["architectures"]>[number];
|
|
5
6
|
type DeployTargetName = NonNullable<DeployConfig["targets"]>[number];
|
|
6
7
|
type PackageFamily = "arch" | "debian" | "fedora" | "suse" | "unknown";
|
|
7
8
|
|
|
@@ -94,7 +95,7 @@ type DeployArch = {
|
|
|
94
95
|
rpm: string;
|
|
95
96
|
flatpak: string;
|
|
96
97
|
appimage: string;
|
|
97
|
-
node:
|
|
98
|
+
node: DeployArchName;
|
|
98
99
|
};
|
|
99
100
|
|
|
100
101
|
type DeployPaths = {
|
|
@@ -170,6 +171,7 @@ type DeployArtifact = {
|
|
|
170
171
|
type DeployTarget = {
|
|
171
172
|
name: DeployTargetName;
|
|
172
173
|
prefix: string;
|
|
174
|
+
isHostOnly: boolean;
|
|
173
175
|
tools: DeployTool[];
|
|
174
176
|
render: (payload: DeployPayload) => DeployManifest[];
|
|
175
177
|
pack: (payload: DeployPayload, manifests: DeployManifest[]) => Promise<DeployArtifact[]>;
|
|
@@ -177,6 +179,7 @@ type DeployTarget = {
|
|
|
177
179
|
|
|
178
180
|
export type {
|
|
179
181
|
DeployArch,
|
|
182
|
+
DeployArchName,
|
|
180
183
|
DeployArtifact,
|
|
181
184
|
DeployConfig,
|
|
182
185
|
DeployDesktopAction,
|
|
@@ -39,7 +39,7 @@ const resolveAppimageTooling = async (arch: string): Promise<AppimageTooling> =>
|
|
|
39
39
|
url: `${APPIMAGETOOL_URL}/appimagetool-${arch}.AppImage`,
|
|
40
40
|
dest: join(dir, `appimagetool-${arch}`),
|
|
41
41
|
label: `appimagetool ${APPIMAGETOOL_VERSION}`,
|
|
42
|
-
|
|
42
|
+
digest: digestFor(APPIMAGETOOL_DIGESTS, arch, "appimagetool"),
|
|
43
43
|
mode: EXECUTABLE_MODE,
|
|
44
44
|
});
|
|
45
45
|
|
|
@@ -47,7 +47,7 @@ const resolveAppimageTooling = async (arch: string): Promise<AppimageTooling> =>
|
|
|
47
47
|
url: `${RUNTIME_URL}/runtime-${arch}`,
|
|
48
48
|
dest: join(dir, `runtime-${arch}`),
|
|
49
49
|
label: `the AppImage runtime ${RUNTIME_VERSION}`,
|
|
50
|
-
|
|
50
|
+
digest: digestFor(RUNTIME_DIGESTS, arch, "the AppImage runtime"),
|
|
51
51
|
mode: EXECUTABLE_MODE,
|
|
52
52
|
});
|
|
53
53
|
|
|
@@ -56,7 +56,7 @@ const downloadNfpm = async (dir: string, binary: string): Promise<string> => {
|
|
|
56
56
|
url: `${NFPM_BASE_URL}/${assetName}`,
|
|
57
57
|
dest: join(dir, assetName),
|
|
58
58
|
label: `nfpm ${NFPM_VERSION}`,
|
|
59
|
-
|
|
59
|
+
digest: digestFor(process.arch),
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
extractNfpm(archive, binary);
|