1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const flatpak_bundler_1 = require("@malept/flatpak-bundler");
|
4 | const builder_util_1 = require("builder-util");
|
5 | const fs_extra_1 = require("fs-extra");
|
6 | const path = require("path");
|
7 | const core_1 = require("../core");
|
8 | const license_1 = require("../util/license");
|
9 | const targetUtil_1 = require("./targetUtil");
|
10 | class FlatpakTarget extends core_1.Target {
|
11 | constructor(name, packager, helper, outDir) {
|
12 | super(name);
|
13 | this.packager = packager;
|
14 | this.helper = helper;
|
15 | this.outDir = outDir;
|
16 | this.options = {
|
17 | ...this.packager.platformSpecificBuildOptions,
|
18 | ...this.packager.config[this.name],
|
19 | };
|
20 | }
|
21 | get appId() {
|
22 | return filterFlatpakAppIdentifier(this.packager.appInfo.id);
|
23 | }
|
24 | async build(appOutDir, arch) {
|
25 | const { packager, options } = this;
|
26 | const artifactName = packager.expandArtifactNamePattern(options, "flatpak", arch, undefined, false);
|
27 | const artifactPath = path.join(this.outDir, artifactName);
|
28 | await packager.info.callArtifactBuildStarted({
|
29 | targetPresentableName: "flatpak",
|
30 | file: artifactPath,
|
31 | arch,
|
32 | });
|
33 | const stageDir = await this.prepareStageDir(arch);
|
34 | const { manifest, buildOptions } = this.getFlatpakBuilderOptions(appOutDir, stageDir.dir, artifactName, arch);
|
35 | await (0, flatpak_bundler_1.bundle)(manifest, buildOptions);
|
36 | await stageDir.cleanup();
|
37 | await packager.info.callArtifactBuildCompleted({
|
38 | file: artifactPath,
|
39 | safeArtifactName: packager.computeSafeArtifactName(artifactName, "flatpak", arch, false),
|
40 | target: this,
|
41 | arch,
|
42 | packager,
|
43 | isWriteUpdateInfo: false,
|
44 | });
|
45 | }
|
46 | async prepareStageDir(arch) {
|
47 | const stageDir = await (0, targetUtil_1.createStageDir)(this, this.packager, arch);
|
48 | await Promise.all([this.createSandboxBinWrapper(stageDir), this.createDesktopFile(stageDir), this.copyLicenseFile(stageDir), this.copyIcons(stageDir)]);
|
49 | return stageDir;
|
50 | }
|
51 | async createSandboxBinWrapper(stageDir) {
|
52 | const useWaylandFlags = !!this.options.useWaylandFlags;
|
53 | const electronWrapperPath = stageDir.getTempFile(path.join("bin", "electron-wrapper"));
|
54 | await (0, fs_extra_1.outputFile)(electronWrapperPath, getElectronWrapperScript(this.packager.executableName, useWaylandFlags));
|
55 | await (0, fs_extra_1.chmod)(electronWrapperPath, 0o755);
|
56 | }
|
57 | async createDesktopFile(stageDir) {
|
58 | const appIdentifier = this.appId;
|
59 | const desktopFile = stageDir.getTempFile(path.join("share", "applications", `${appIdentifier}.desktop`));
|
60 | await this.helper.writeDesktopEntry(this.options, "electron-wrapper %U", desktopFile, { Icon: appIdentifier });
|
61 | }
|
62 | async copyLicenseFile(stageDir) {
|
63 | const licenseSrc = await (0, license_1.getNotLocalizedLicenseFile)(this.options.license, this.packager, ["txt", "html"]);
|
64 | if (licenseSrc) {
|
65 | const licenseDst = stageDir.getTempFile(path.join("share", "doc", this.appId, "copyright"));
|
66 | await (0, builder_util_1.copyFile)(licenseSrc, licenseDst);
|
67 | }
|
68 | }
|
69 | async copyIcons(stageDir) {
|
70 | const icons = await this.helper.icons;
|
71 | const copyIcons = icons.map(async (icon) => {
|
72 | if (icon.size > 512) {
|
73 |
|
74 | return Promise.resolve();
|
75 | }
|
76 | const extWithDot = path.extname(icon.file);
|
77 | const sizeName = extWithDot === ".svg" ? "scalable" : `${icon.size}x${icon.size}`;
|
78 | const iconDst = stageDir.getTempFile(path.join("share", "icons", "hicolor", sizeName, "apps", `${this.appId}${extWithDot}`));
|
79 | return (0, builder_util_1.copyFile)(icon.file, iconDst);
|
80 | });
|
81 | await Promise.all(copyIcons);
|
82 | }
|
83 | getFlatpakBuilderOptions(appOutDir, stageDir, artifactName, arch) {
|
84 | const appIdentifier = this.appId;
|
85 | const { executableName } = this.packager;
|
86 | const flatpakArch = (0, builder_util_1.toLinuxArchString)(arch, "flatpak");
|
87 | const manifest = {
|
88 | id: appIdentifier,
|
89 | command: "electron-wrapper",
|
90 | runtime: this.options.runtime || flatpakBuilderDefaults.runtime,
|
91 | runtimeVersion: this.options.runtimeVersion || flatpakBuilderDefaults.runtimeVersion,
|
92 | sdk: this.options.sdk || flatpakBuilderDefaults.sdk,
|
93 | base: this.options.base || flatpakBuilderDefaults.base,
|
94 | baseVersion: this.options.baseVersion || flatpakBuilderDefaults.baseVersion,
|
95 | finishArgs: this.options.finishArgs || flatpakBuilderDefaults.finishArgs,
|
96 | branch: this.options.branch,
|
97 | modules: this.options.modules,
|
98 | };
|
99 | const buildOptions = {
|
100 | baseFlatpakref: `app/${manifest.base}/${flatpakArch}/${manifest.baseVersion}`,
|
101 | runtimeFlatpakref: `runtime/${manifest.runtime}/${flatpakArch}/${manifest.runtimeVersion}`,
|
102 | sdkFlatpakref: `runtime/${manifest.sdk}/${flatpakArch}/${manifest.runtimeVersion}`,
|
103 | arch: flatpakArch,
|
104 | bundlePath: path.join(this.outDir, artifactName),
|
105 | files: [[stageDir, "/"], [appOutDir, path.join("/lib", appIdentifier)], ...(this.options.files || [])],
|
106 | symlinks: [[path.join("/lib", appIdentifier, executableName), path.join("/bin", executableName)], ...(this.options.symlinks || [])],
|
107 | };
|
108 | return { manifest, buildOptions };
|
109 | }
|
110 | }
|
111 | exports.default = FlatpakTarget;
|
112 | const flatpakBuilderDefaults = {
|
113 | runtime: "org.freedesktop.Platform",
|
114 | runtimeVersion: "20.08",
|
115 | sdk: "org.freedesktop.Sdk",
|
116 | base: "org.electronjs.Electron2.BaseApp",
|
117 | baseVersion: "20.08",
|
118 | finishArgs: [
|
119 |
|
120 | "--socket=wayland",
|
121 | "--socket=x11",
|
122 | "--share=ipc",
|
123 |
|
124 | "--device=dri",
|
125 |
|
126 | "--socket=pulseaudio",
|
127 |
|
128 | "--filesystem=home",
|
129 |
|
130 | "--share=network",
|
131 |
|
132 | "--talk-name=org.freedesktop.Notifications",
|
133 | ],
|
134 | };
|
135 | function getElectronWrapperScript(executableName, useWaylandFlags) {
|
136 | return useWaylandFlags
|
137 | ? `#!/bin/sh
|
138 |
|
139 | export TMPDIR="$XDG_RUNTIME_DIR/app/$FLATPAK_ID"
|
140 |
|
141 | if [ "\${XDG_SESSION_TYPE}" == "wayland" ]; then
|
142 | zypak-wrapper "${executableName}" --enable-features=UseOzonePlatform --ozone-platform=wayland "$@"
|
143 | else
|
144 | zypak-wrapper "${executableName}" "$@"
|
145 | fi
|
146 | `
|
147 | : `#!/bin/sh
|
148 |
|
149 | export TMPDIR="$XDG_RUNTIME_DIR/app/$FLATPAK_ID"
|
150 |
|
151 | zypak-wrapper "${executableName}" "$@"
|
152 | `;
|
153 | }
|
154 | function filterFlatpakAppIdentifier(identifier) {
|
155 |
|
156 |
|
157 | return identifier.replace(/-/g, "_").replace(/[^a-zA-Z0-9._]/g, "");
|
158 | }
|
159 |
|
\ | No newline at end of file |