app-builder-lib 26.6.0 → 26.8.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/out/codeSign/windowsSignToolManager.d.ts +4 -5
- package/out/codeSign/windowsSignToolManager.js +76 -86
- package/out/codeSign/windowsSignToolManager.js.map +1 -1
- package/out/configuration.d.ts +34 -0
- package/out/configuration.js.map +1 -1
- package/out/index.d.ts +1 -1
- package/out/index.js.map +1 -1
- package/out/linuxPackager.js +1 -1
- package/out/linuxPackager.js.map +1 -1
- package/out/macPackager.js +0 -1
- package/out/macPackager.js.map +1 -1
- package/out/node-module-collector/index.d.ts +1 -2
- package/out/node-module-collector/nodeModulesCollector.d.ts +2 -18
- package/out/node-module-collector/nodeModulesCollector.js +38 -73
- package/out/node-module-collector/nodeModulesCollector.js.map +1 -1
- package/out/node-module-collector/npmNodeModulesCollector.js +11 -7
- package/out/node-module-collector/npmNodeModulesCollector.js.map +1 -1
- package/out/node-module-collector/pnpmNodeModulesCollector.js +1 -1
- package/out/node-module-collector/pnpmNodeModulesCollector.js.map +1 -1
- package/out/node-module-collector/types.d.ts +0 -4
- package/out/node-module-collector/types.js.map +1 -1
- package/out/node-module-collector/yarnNodeModulesCollector.d.ts +4 -10
- package/out/node-module-collector/yarnNodeModulesCollector.js +7 -197
- package/out/node-module-collector/yarnNodeModulesCollector.js.map +1 -1
- package/out/options/AppXOptions.d.ts +8 -0
- package/out/options/AppXOptions.js.map +1 -1
- package/out/options/macOptions.d.ts +12 -0
- package/out/options/macOptions.js.map +1 -1
- package/out/targets/AppxCapabilities.d.ts +8 -0
- package/out/targets/AppxCapabilities.js +258 -0
- package/out/targets/AppxCapabilities.js.map +1 -0
- package/out/targets/AppxTarget.d.ts +1 -0
- package/out/targets/AppxTarget.js +32 -14
- package/out/targets/AppxTarget.js.map +1 -1
- package/out/targets/FpmTarget.js +3 -3
- package/out/targets/FpmTarget.js.map +1 -1
- package/out/targets/MsiWrappedTarget.js +4 -3
- package/out/targets/MsiWrappedTarget.js.map +1 -1
- package/out/targets/appimage/AppImageTarget.d.ts +16 -0
- package/out/targets/{AppImageTarget.js → appimage/AppImageTarget.js} +65 -28
- package/out/targets/appimage/AppImageTarget.js.map +1 -0
- package/out/targets/appimage/appImageUtil.d.ts +23 -0
- package/out/targets/appimage/appImageUtil.js +266 -0
- package/out/targets/appimage/appImageUtil.js.map +1 -0
- package/out/targets/appimage/appLauncher.d.ts +3 -0
- package/out/targets/appimage/appLauncher.js +91 -0
- package/out/targets/appimage/appLauncher.js.map +1 -0
- package/out/targets/archive.js +2 -2
- package/out/targets/archive.js.map +1 -1
- package/out/toolsets/linux.d.ts +9 -0
- package/out/toolsets/linux.js +68 -0
- package/out/toolsets/linux.js.map +1 -0
- package/out/toolsets/windows.d.ts +42 -0
- package/out/toolsets/windows.js +143 -0
- package/out/toolsets/windows.js.map +1 -0
- package/out/util/packageMetadata.js +9 -5
- package/out/util/packageMetadata.js.map +1 -1
- package/out/version.d.ts +1 -1
- package/out/version.js +1 -1
- package/out/version.js.map +1 -1
- package/out/winPackager.js +4 -3
- package/out/winPackager.js.map +1 -1
- package/package.json +9 -9
- package/scheme.json +78 -1
- package/templates/appx/appxmanifest.xml +1 -3
- package/templates/linux/after-install.tpl +1 -1
- package/out/targets/AppImageTarget.d.ts +0 -14
- package/out/targets/AppImageTarget.js.map +0 -1
- package/out/targets/tools.d.ts +0 -2
- package/out/targets/tools.js +0 -46
- package/out/targets/tools.js.map +0 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Arch } from "builder-util";
|
|
2
|
+
import { FileAssociation } from "../../options/FileAssociation";
|
|
3
|
+
import { IconInfo } from "../../platformPackager";
|
|
4
|
+
import { BlockMapDataHolder } from "builder-util-runtime";
|
|
5
|
+
interface Options {
|
|
6
|
+
productName: string;
|
|
7
|
+
productFilename: string;
|
|
8
|
+
executableName: string;
|
|
9
|
+
desktopEntry: string;
|
|
10
|
+
icons: IconInfo[];
|
|
11
|
+
license?: string | null;
|
|
12
|
+
fileAssociations: FileAssociation[];
|
|
13
|
+
compression?: "xz" | "lzo" | "zstd";
|
|
14
|
+
}
|
|
15
|
+
export interface AppImageBuilderOptions {
|
|
16
|
+
appDir: string;
|
|
17
|
+
stageDir: string;
|
|
18
|
+
arch: Arch;
|
|
19
|
+
output: string;
|
|
20
|
+
options: Options;
|
|
21
|
+
}
|
|
22
|
+
export declare function buildAppImage(opts: AppImageBuilderOptions): Promise<BlockMapDataHolder>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildAppImage = buildAppImage;
|
|
4
|
+
const builder_util_1 = require("builder-util");
|
|
5
|
+
const fs = require("fs-extra");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const linux_1 = require("../../toolsets/linux");
|
|
8
|
+
const appLauncher_1 = require("./appLauncher");
|
|
9
|
+
const differentialUpdateInfoBuilder_1 = require("../differentialUpdateInfoBuilder");
|
|
10
|
+
const AppImageTarget_1 = require("./AppImageTarget");
|
|
11
|
+
async function buildAppImage(opts) {
|
|
12
|
+
const { stageDir, output, appDir, options, arch } = opts;
|
|
13
|
+
try {
|
|
14
|
+
await fs.remove(output);
|
|
15
|
+
// Write AppRun launcher and related files
|
|
16
|
+
await writeAppLauncherAndRelatedFiles(opts);
|
|
17
|
+
const { runtimeLibraries: libraries, runtime, mksquashfs } = await (0, linux_1.getAppImageTools)(arch);
|
|
18
|
+
await (0, builder_util_1.copyDir)(libraries, path.join(stageDir, "usr", "lib"));
|
|
19
|
+
// Copy app directory to stage
|
|
20
|
+
// mksquashfs doesn't support merging, so we copy the entire app dir
|
|
21
|
+
await (0, builder_util_1.copyDir)(appDir, stageDir);
|
|
22
|
+
const runtimeData = await fs.readFile(runtime);
|
|
23
|
+
// Create squashfs with offset for runtime
|
|
24
|
+
const args = [stageDir, output, "-offset", runtimeData.length.toString(), "-all-root", "-noappend", "-no-progress", "-quiet", "-no-xattrs", "-no-fragments"];
|
|
25
|
+
if (options.compression) {
|
|
26
|
+
args.push("-comp", options.compression);
|
|
27
|
+
if (options.compression === "xz") {
|
|
28
|
+
args.push("-Xdict-size", "100%", "-b", "1048576");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
await (0, builder_util_1.exec)(mksquashfs, args, {
|
|
32
|
+
cwd: stageDir,
|
|
33
|
+
});
|
|
34
|
+
// Write runtime data at the beginning of the file
|
|
35
|
+
await writeRuntimeData(output, runtimeData);
|
|
36
|
+
// Make executable
|
|
37
|
+
await fs.chmod(output, 0o755);
|
|
38
|
+
// Append blockmap inside try block to ensure cleanup on failure
|
|
39
|
+
const updateInfo = await (0, differentialUpdateInfoBuilder_1.appendBlockmap)(output);
|
|
40
|
+
return updateInfo;
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
// Clean up partial build on failure
|
|
44
|
+
await fs.remove(output).catch(() => { });
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async function writeRuntimeData(filePath, runtimeData) {
|
|
49
|
+
const fd = await fs.open(filePath, "r+");
|
|
50
|
+
try {
|
|
51
|
+
await fs.write(fd, runtimeData, 0, runtimeData.length, 0);
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
try {
|
|
55
|
+
await fs.close(fd);
|
|
56
|
+
}
|
|
57
|
+
catch (closeError) {
|
|
58
|
+
// Log but don't throw - preserve original error if any
|
|
59
|
+
builder_util_1.log.warn({ message: closeError.message, file: filePath }, `failed to close file descriptor`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Escapes a string for safe use in shell scripts by wrapping in single quotes
|
|
65
|
+
* and escaping any single quotes within the string.
|
|
66
|
+
*
|
|
67
|
+
* This allows strings with spaces, special characters, etc. to be safely used.
|
|
68
|
+
*/
|
|
69
|
+
function escapeShellString(str) {
|
|
70
|
+
// Escape single quotes by replacing ' with '\''
|
|
71
|
+
// Then wrap the whole string in single quotes
|
|
72
|
+
return `'${str.replace(/'/g, "'\\''")}'`;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Validates that critical executable/filename fields don't contain dangerous characters
|
|
76
|
+
* that could break paths or cause security issues even when escaped.
|
|
77
|
+
*/
|
|
78
|
+
function validateCriticalPathString(str, fieldName) {
|
|
79
|
+
// Only reject characters that would break filesystem paths or cause severe issues
|
|
80
|
+
// Allow quotes, spaces, etc. since they can be escaped
|
|
81
|
+
if (/[`${}|&;<>\n\r\0]/.test(str) || str.includes("/") || str.includes("\\")) {
|
|
82
|
+
throw new builder_util_1.InvalidConfigurationError(`${fieldName} contains characters that cannot be safely used in file paths: ${str}. ` +
|
|
83
|
+
`Please use only alphanumeric characters, hyphens, underscores, dots, spaces, and quotes.`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async function writeAppLauncherAndRelatedFiles(opts) {
|
|
87
|
+
const { stageDir, options: { license, executableName, productFilename, productName, desktopEntry }, } = opts;
|
|
88
|
+
// Validate only critical path fields for severe path-breaking characters
|
|
89
|
+
// productName and productFilename can contain quotes, spaces, etc. - they'll be escaped
|
|
90
|
+
validateCriticalPathString(executableName, "executableName");
|
|
91
|
+
validateCriticalPathString(productFilename, "productFilename");
|
|
92
|
+
// Write desktop file
|
|
93
|
+
const desktopFileName = `${executableName}.desktop`;
|
|
94
|
+
await fs.writeFile(path.join(stageDir, desktopFileName), desktopEntry, { mode: 0o644 });
|
|
95
|
+
await (0, appLauncher_1.copyIcons)(opts);
|
|
96
|
+
const templateConfig = {
|
|
97
|
+
DesktopFileName: desktopFileName,
|
|
98
|
+
ExecutableName: executableName,
|
|
99
|
+
ProductName: productName,
|
|
100
|
+
ProductFilename: productFilename,
|
|
101
|
+
ResourceName: `appimagekit-${executableName}`,
|
|
102
|
+
};
|
|
103
|
+
const mimeTypeFile = await (0, appLauncher_1.copyMimeTypes)(opts);
|
|
104
|
+
if (mimeTypeFile) {
|
|
105
|
+
templateConfig.MimeTypeFile = mimeTypeFile;
|
|
106
|
+
}
|
|
107
|
+
let finalConfig = templateConfig;
|
|
108
|
+
// Copy license file if provided
|
|
109
|
+
if (license) {
|
|
110
|
+
// Validate license file exists
|
|
111
|
+
if (!(await (0, builder_util_1.exists)(license))) {
|
|
112
|
+
throw new builder_util_1.InvalidConfigurationError(`License file not found: ${license}`);
|
|
113
|
+
}
|
|
114
|
+
const licenseBaseName = path.basename(license);
|
|
115
|
+
const ext = path.extname(license).toLowerCase();
|
|
116
|
+
// Validate license filename for path safety
|
|
117
|
+
validateCriticalPathString(licenseBaseName, "licenseBaseName");
|
|
118
|
+
// Validate extension
|
|
119
|
+
if (![".txt", ".html"].includes(ext)) {
|
|
120
|
+
builder_util_1.log.warn({ license, expected: ".txt or .html" }, `license file has unexpected extension`);
|
|
121
|
+
}
|
|
122
|
+
await (0, builder_util_1.copyFile)(license, path.join(stageDir, licenseBaseName));
|
|
123
|
+
finalConfig = {
|
|
124
|
+
...templateConfig,
|
|
125
|
+
EulaFile: licenseBaseName,
|
|
126
|
+
IsHtmlEula: ext === ".html",
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
const appRunContent = generateAppRunScript(finalConfig);
|
|
130
|
+
await fs.writeFile(path.join(stageDir, AppImageTarget_1.APP_RUN_ENTRYPOINT), appRunContent, { mode: 0o755 });
|
|
131
|
+
}
|
|
132
|
+
function hasEula(config) {
|
|
133
|
+
return "EulaFile" in config && typeof config.EulaFile === "string";
|
|
134
|
+
}
|
|
135
|
+
function generateAppRunScript(config) {
|
|
136
|
+
const eulaEnabled = hasEula(config);
|
|
137
|
+
return `#!/bin/bash
|
|
138
|
+
set -e
|
|
139
|
+
|
|
140
|
+
THIS="$0"
|
|
141
|
+
# http://stackoverflow.com/questions/3190818/
|
|
142
|
+
args=("$@")
|
|
143
|
+
NUMBER_OF_ARGS="$#"
|
|
144
|
+
|
|
145
|
+
if [ -z "$APPDIR" ] ; then
|
|
146
|
+
# Find the AppDir. It is the directory that contains AppRun.
|
|
147
|
+
# This assumes that this script resides inside the AppDir or a subdirectory.
|
|
148
|
+
# If this script is run inside an AppImage, then the AppImage runtime likely has already set $APPDIR
|
|
149
|
+
path="$(dirname "$(readlink -f "\${THIS}")")"
|
|
150
|
+
while [[ "$path" != "" && ! -e "$path/${AppImageTarget_1.APP_RUN_ENTRYPOINT}" ]]; do
|
|
151
|
+
path=\${path%/*}
|
|
152
|
+
done
|
|
153
|
+
APPDIR="$path"
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
export PATH="\${APPDIR}:\${APPDIR}/usr/sbin:\${PATH}"
|
|
157
|
+
export XDG_DATA_DIRS="./share/:/usr/share/gnome:/usr/local/share/:/usr/share/:\${XDG_DATA_DIRS}"
|
|
158
|
+
export LD_LIBRARY_PATH="\${APPDIR}/usr/lib:\${LD_LIBRARY_PATH}"
|
|
159
|
+
export XDG_DATA_DIRS="\${APPDIR}"/usr/share/:"\${XDG_DATA_DIRS}":/usr/share/gnome/:/usr/local/share/:/usr/share/
|
|
160
|
+
export GSETTINGS_SCHEMA_DIR="\${APPDIR}/usr/share/glib-2.0/schemas:\${GSETTINGS_SCHEMA_DIR}"
|
|
161
|
+
|
|
162
|
+
BIN="$APPDIR/${config.ExecutableName}"
|
|
163
|
+
|
|
164
|
+
if [ -z "$APPIMAGE_EXIT_AFTER_INSTALL" ] ; then
|
|
165
|
+
trap atexit EXIT
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
isEulaAccepted=1
|
|
169
|
+
|
|
170
|
+
atexit()
|
|
171
|
+
{
|
|
172
|
+
if [ $isEulaAccepted == 1 ] ; then
|
|
173
|
+
if [ $NUMBER_OF_ARGS -eq 0 ] ; then
|
|
174
|
+
exec "$BIN"
|
|
175
|
+
else
|
|
176
|
+
exec "$BIN" "\${args[@]}"
|
|
177
|
+
fi
|
|
178
|
+
fi
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
error()
|
|
182
|
+
{
|
|
183
|
+
if [ -x /usr/bin/zenity ] ; then
|
|
184
|
+
LD_LIBRARY_PATH="" zenity --error --text "\${1}" 2>/dev/null
|
|
185
|
+
elif [ -x /usr/bin/kdialog ] ; then
|
|
186
|
+
LD_LIBRARY_PATH="" kdialog --msgbox "\${1}" 2>/dev/null
|
|
187
|
+
elif [ -x /usr/bin/Xdialog ] ; then
|
|
188
|
+
LD_LIBRARY_PATH="" Xdialog --msgbox "\${1}" 2>/dev/null
|
|
189
|
+
else
|
|
190
|
+
echo "\${1}"
|
|
191
|
+
fi
|
|
192
|
+
exit 1
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
yesno()
|
|
196
|
+
{
|
|
197
|
+
TITLE=$1
|
|
198
|
+
TEXT=$2
|
|
199
|
+
if [ -x /usr/bin/zenity ] ; then
|
|
200
|
+
LD_LIBRARY_PATH="" zenity --question --title="$TITLE" --text="$TEXT" 2>/dev/null || exit 0
|
|
201
|
+
elif [ -x /usr/bin/kdialog ] ; then
|
|
202
|
+
LD_LIBRARY_PATH="" kdialog --title "$TITLE" --yesno "$TEXT" || exit 0
|
|
203
|
+
elif [ -x /usr/bin/Xdialog ] ; then
|
|
204
|
+
LD_LIBRARY_PATH="" Xdialog --title "$TITLE" --clear --yesno "$TEXT" 10 80 || exit 0
|
|
205
|
+
else
|
|
206
|
+
echo "zenity, kdialog, Xdialog missing. Skipping \${THIS}."
|
|
207
|
+
exit 0
|
|
208
|
+
fi
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
check_dep()
|
|
212
|
+
{
|
|
213
|
+
DEP=$1
|
|
214
|
+
if ! command -v "$DEP" &>/dev/null ; then
|
|
215
|
+
echo "$DEP is missing. Skipping \${THIS}."
|
|
216
|
+
exit 0
|
|
217
|
+
fi
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if [ -z "$APPIMAGE" ] ; then
|
|
221
|
+
APPIMAGE="$APPDIR/${AppImageTarget_1.APP_RUN_ENTRYPOINT}"
|
|
222
|
+
# not running from within an AppImage; hence using the AppRun for Exec=
|
|
223
|
+
fi
|
|
224
|
+
|
|
225
|
+
${eulaEnabled
|
|
226
|
+
? `if [ -z "$APPIMAGE_SILENT_INSTALL" ] ; then
|
|
227
|
+
EULA_MARK_DIR="\${XDG_CONFIG_HOME:-$HOME/.config}/${config.ProductFilename}"
|
|
228
|
+
EULA_MARK_FILE="$EULA_MARK_DIR/eulaAccepted"
|
|
229
|
+
# show EULA only if desktop file doesn't exist
|
|
230
|
+
if [ ! -e "$EULA_MARK_FILE" ] ; then
|
|
231
|
+
if [ -x /usr/bin/zenity ] ; then
|
|
232
|
+
# on cancel simply exits and our trap handler launches app, so, $isEulaAccepted is set here to 0 and then to 1 if EULA accepted
|
|
233
|
+
isEulaAccepted=0
|
|
234
|
+
LD_LIBRARY_PATH="" zenity --text-info --title=${escapeShellString(config.ProductName)} --filename="$APPDIR/${config.EulaFile}" --ok-label=Agree --cancel-label=Disagree ${config.IsHtmlEula ? "--html" : ""}
|
|
235
|
+
elif [ -x /usr/bin/Xdialog ] ; then
|
|
236
|
+
isEulaAccepted=0
|
|
237
|
+
LD_LIBRARY_PATH="" Xdialog --title ${escapeShellString(config.ProductName)} --textbox "$APPDIR/${config.EulaFile}" 30 80 --ok-label Agree --cancel-label Disagree
|
|
238
|
+
elif [ -x /usr/bin/kdialog ] ; then
|
|
239
|
+
# cannot find any option to force Agree/Disagree buttons for kdialog. And official example exactly with OK button https://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs#Example_21._--textbox_dialog_box
|
|
240
|
+
# in any case we pass labels text
|
|
241
|
+
isEulaAccepted=0
|
|
242
|
+
LD_LIBRARY_PATH="" kdialog --textbox "$APPDIR/${config.EulaFile}" --yes-label Agree --cancel-label "Disagree"
|
|
243
|
+
fi
|
|
244
|
+
|
|
245
|
+
case $? in
|
|
246
|
+
0)
|
|
247
|
+
isEulaAccepted=1
|
|
248
|
+
echo "License accepted"
|
|
249
|
+
mkdir -p "$EULA_MARK_DIR"
|
|
250
|
+
touch "$EULA_MARK_FILE"
|
|
251
|
+
;;
|
|
252
|
+
1)
|
|
253
|
+
echo "License not accepted"
|
|
254
|
+
exit 0
|
|
255
|
+
;;
|
|
256
|
+
-1)
|
|
257
|
+
echo "An unexpected error has occurred."
|
|
258
|
+
isEulaAccepted=1
|
|
259
|
+
;;
|
|
260
|
+
esac
|
|
261
|
+
fi
|
|
262
|
+
fi`
|
|
263
|
+
: ""}
|
|
264
|
+
`;
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=appImageUtil.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appImageUtil.js","sourceRoot":"","sources":["../../../src/targets/appimage/appImageUtil.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arch, copyDir, copyFile, exec, exists, InvalidConfigurationError, log } from \"builder-util\"\nimport * as fs from \"fs-extra\"\nimport * as path from \"path\"\nimport { FileAssociation } from \"../../options/FileAssociation\"\nimport { IconInfo } from \"../../platformPackager\"\nimport { getAppImageTools } from \"../../toolsets/linux\"\nimport { copyIcons, copyMimeTypes } from \"./appLauncher\"\nimport { appendBlockmap } from \"../differentialUpdateInfoBuilder\"\nimport { BlockMapDataHolder } from \"builder-util-runtime\"\nimport { APP_RUN_ENTRYPOINT } from \"./AppImageTarget\"\n\ninterface Options {\n productName: string\n productFilename: string\n executableName: string\n desktopEntry: string\n icons: IconInfo[]\n license?: string | null\n fileAssociations: FileAssociation[]\n compression?: \"xz\" | \"lzo\" | \"zstd\"\n}\n\nexport interface AppImageBuilderOptions {\n appDir: string\n stageDir: string\n arch: Arch\n output: string\n options: Options\n}\n\nexport async function buildAppImage(opts: AppImageBuilderOptions): Promise<BlockMapDataHolder> {\n const { stageDir, output, appDir, options, arch } = opts\n\n try {\n await fs.remove(output)\n\n // Write AppRun launcher and related files\n await writeAppLauncherAndRelatedFiles(opts)\n\n const { runtimeLibraries: libraries, runtime, mksquashfs } = await getAppImageTools(arch)\n await copyDir(libraries, path.join(stageDir, \"usr\", \"lib\"))\n\n // Copy app directory to stage\n // mksquashfs doesn't support merging, so we copy the entire app dir\n await copyDir(appDir, stageDir)\n\n const runtimeData = await fs.readFile(runtime)\n\n // Create squashfs with offset for runtime\n const args: string[] = [stageDir, output, \"-offset\", runtimeData.length.toString(), \"-all-root\", \"-noappend\", \"-no-progress\", \"-quiet\", \"-no-xattrs\", \"-no-fragments\"]\n if (options.compression) {\n args.push(\"-comp\", options.compression)\n\n if (options.compression === \"xz\") {\n args.push(\"-Xdict-size\", \"100%\", \"-b\", \"1048576\")\n }\n }\n await exec(mksquashfs, args, {\n cwd: stageDir,\n })\n\n // Write runtime data at the beginning of the file\n await writeRuntimeData(output, runtimeData)\n\n // Make executable\n await fs.chmod(output, 0o755)\n\n // Append blockmap inside try block to ensure cleanup on failure\n const updateInfo = await appendBlockmap(output)\n return updateInfo\n } catch (error) {\n // Clean up partial build on failure\n await fs.remove(output).catch(() => {})\n throw error\n }\n}\n\nasync function writeRuntimeData(filePath: string, runtimeData: Buffer): Promise<void> {\n const fd = await fs.open(filePath, \"r+\")\n try {\n await fs.write(fd, runtimeData, 0, runtimeData.length, 0)\n } finally {\n try {\n await fs.close(fd)\n } catch (closeError: any) {\n // Log but don't throw - preserve original error if any\n log.warn({ message: closeError.message, file: filePath }, `failed to close file descriptor`)\n }\n }\n}\n\n/**\n * Escapes a string for safe use in shell scripts by wrapping in single quotes\n * and escaping any single quotes within the string.\n *\n * This allows strings with spaces, special characters, etc. to be safely used.\n */\nfunction escapeShellString(str: string): string {\n // Escape single quotes by replacing ' with '\\''\n // Then wrap the whole string in single quotes\n return `'${str.replace(/'/g, \"'\\\\''\")}'`\n}\n\n/**\n * Validates that critical executable/filename fields don't contain dangerous characters\n * that could break paths or cause security issues even when escaped.\n */\nfunction validateCriticalPathString(str: string, fieldName: string): void {\n // Only reject characters that would break filesystem paths or cause severe issues\n // Allow quotes, spaces, etc. since they can be escaped\n if (/[`${}|&;<>\\n\\r\\0]/.test(str) || str.includes(\"/\") || str.includes(\"\\\\\")) {\n throw new InvalidConfigurationError(\n `${fieldName} contains characters that cannot be safely used in file paths: ${str}. ` +\n `Please use only alphanumeric characters, hyphens, underscores, dots, spaces, and quotes.`\n )\n }\n}\n\nasync function writeAppLauncherAndRelatedFiles(opts: AppImageBuilderOptions): Promise<void> {\n const {\n stageDir,\n options: { license, executableName, productFilename, productName, desktopEntry },\n } = opts\n\n // Validate only critical path fields for severe path-breaking characters\n // productName and productFilename can contain quotes, spaces, etc. - they'll be escaped\n validateCriticalPathString(executableName, \"executableName\")\n validateCriticalPathString(productFilename, \"productFilename\")\n\n // Write desktop file\n const desktopFileName = `${executableName}.desktop`\n await fs.writeFile(path.join(stageDir, desktopFileName), desktopEntry, { mode: 0o644 })\n await copyIcons(opts)\n\n const templateConfig: AppRunScriptBase = {\n DesktopFileName: desktopFileName,\n ExecutableName: executableName,\n ProductName: productName,\n ProductFilename: productFilename,\n ResourceName: `appimagekit-${executableName}`,\n }\n\n const mimeTypeFile = await copyMimeTypes(opts)\n if (mimeTypeFile) {\n templateConfig.MimeTypeFile = mimeTypeFile\n }\n\n let finalConfig: AppRunScript = templateConfig\n\n // Copy license file if provided\n if (license) {\n // Validate license file exists\n if (!(await exists(license))) {\n throw new InvalidConfigurationError(`License file not found: ${license}`)\n }\n\n const licenseBaseName = path.basename(license)\n const ext = path.extname(license).toLowerCase()\n\n // Validate license filename for path safety\n validateCriticalPathString(licenseBaseName, \"licenseBaseName\")\n\n // Validate extension\n if (![\".txt\", \".html\"].includes(ext)) {\n log.warn({ license, expected: \".txt or .html\" }, `license file has unexpected extension`)\n }\n\n await copyFile(license, path.join(stageDir, licenseBaseName))\n\n finalConfig = {\n ...templateConfig,\n EulaFile: licenseBaseName,\n IsHtmlEula: ext === \".html\",\n }\n }\n\n const appRunContent = generateAppRunScript(finalConfig)\n await fs.writeFile(path.join(stageDir, APP_RUN_ENTRYPOINT), appRunContent, { mode: 0o755 })\n}\n\ntype AppRunScriptBase = {\n ExecutableName: string\n DesktopFileName: string\n ProductFilename: string\n ProductName: string\n ResourceName: string\n MimeTypeFile?: string\n}\n\ntype AppRunScriptWithEula = AppRunScriptBase & {\n EulaFile: string\n IsHtmlEula: boolean\n}\n\ntype AppRunScript = AppRunScriptBase | AppRunScriptWithEula\n\nfunction hasEula(config: AppRunScript): config is AppRunScriptWithEula {\n return \"EulaFile\" in config && typeof config.EulaFile === \"string\"\n}\n\nfunction generateAppRunScript(config: AppRunScript): string {\n const eulaEnabled = hasEula(config)\n\n return `#!/bin/bash\nset -e\n\nTHIS=\"$0\"\n# http://stackoverflow.com/questions/3190818/\nargs=(\"$@\")\nNUMBER_OF_ARGS=\"$#\"\n\nif [ -z \"$APPDIR\" ] ; then\n # Find the AppDir. It is the directory that contains AppRun.\n # This assumes that this script resides inside the AppDir or a subdirectory.\n # If this script is run inside an AppImage, then the AppImage runtime likely has already set $APPDIR\n path=\"$(dirname \"$(readlink -f \"\\${THIS}\")\")\"\n while [[ \"$path\" != \"\" && ! -e \"$path/${APP_RUN_ENTRYPOINT}\" ]]; do\n path=\\${path%/*}\n done\n APPDIR=\"$path\"\nfi\n\nexport PATH=\"\\${APPDIR}:\\${APPDIR}/usr/sbin:\\${PATH}\"\nexport XDG_DATA_DIRS=\"./share/:/usr/share/gnome:/usr/local/share/:/usr/share/:\\${XDG_DATA_DIRS}\"\nexport LD_LIBRARY_PATH=\"\\${APPDIR}/usr/lib:\\${LD_LIBRARY_PATH}\"\nexport XDG_DATA_DIRS=\"\\${APPDIR}\"/usr/share/:\"\\${XDG_DATA_DIRS}\":/usr/share/gnome/:/usr/local/share/:/usr/share/\nexport GSETTINGS_SCHEMA_DIR=\"\\${APPDIR}/usr/share/glib-2.0/schemas:\\${GSETTINGS_SCHEMA_DIR}\"\n\nBIN=\"$APPDIR/${config.ExecutableName}\"\n\nif [ -z \"$APPIMAGE_EXIT_AFTER_INSTALL\" ] ; then\n trap atexit EXIT\nfi\n\nisEulaAccepted=1\n\natexit()\n{\n if [ $isEulaAccepted == 1 ] ; then\n if [ $NUMBER_OF_ARGS -eq 0 ] ; then\n exec \"$BIN\"\n else\n exec \"$BIN\" \"\\${args[@]}\"\n fi\n fi\n}\n\nerror()\n{\n if [ -x /usr/bin/zenity ] ; then\n LD_LIBRARY_PATH=\"\" zenity --error --text \"\\${1}\" 2>/dev/null\n elif [ -x /usr/bin/kdialog ] ; then\n LD_LIBRARY_PATH=\"\" kdialog --msgbox \"\\${1}\" 2>/dev/null\n elif [ -x /usr/bin/Xdialog ] ; then\n LD_LIBRARY_PATH=\"\" Xdialog --msgbox \"\\${1}\" 2>/dev/null\n else\n echo \"\\${1}\"\n fi\n exit 1\n}\n\nyesno()\n{\n TITLE=$1\n TEXT=$2\n if [ -x /usr/bin/zenity ] ; then\n LD_LIBRARY_PATH=\"\" zenity --question --title=\"$TITLE\" --text=\"$TEXT\" 2>/dev/null || exit 0\n elif [ -x /usr/bin/kdialog ] ; then\n LD_LIBRARY_PATH=\"\" kdialog --title \"$TITLE\" --yesno \"$TEXT\" || exit 0\n elif [ -x /usr/bin/Xdialog ] ; then\n LD_LIBRARY_PATH=\"\" Xdialog --title \"$TITLE\" --clear --yesno \"$TEXT\" 10 80 || exit 0\n else\n echo \"zenity, kdialog, Xdialog missing. Skipping \\${THIS}.\"\n exit 0\n fi\n}\n\ncheck_dep()\n{\n DEP=$1\n if ! command -v \"$DEP\" &>/dev/null ; then\n echo \"$DEP is missing. Skipping \\${THIS}.\"\n exit 0\n fi\n}\n\nif [ -z \"$APPIMAGE\" ] ; then\n APPIMAGE=\"$APPDIR/${APP_RUN_ENTRYPOINT}\"\n # not running from within an AppImage; hence using the AppRun for Exec=\nfi\n\n${\n eulaEnabled\n ? `if [ -z \"$APPIMAGE_SILENT_INSTALL\" ] ; then\n EULA_MARK_DIR=\"\\${XDG_CONFIG_HOME:-$HOME/.config}/${config.ProductFilename}\"\n EULA_MARK_FILE=\"$EULA_MARK_DIR/eulaAccepted\"\n # show EULA only if desktop file doesn't exist\n if [ ! -e \"$EULA_MARK_FILE\" ] ; then\n if [ -x /usr/bin/zenity ] ; then\n # on cancel simply exits and our trap handler launches app, so, $isEulaAccepted is set here to 0 and then to 1 if EULA accepted\n isEulaAccepted=0\n LD_LIBRARY_PATH=\"\" zenity --text-info --title=${escapeShellString(config.ProductName)} --filename=\"$APPDIR/${config.EulaFile}\" --ok-label=Agree --cancel-label=Disagree ${config.IsHtmlEula ? \"--html\" : \"\"}\n elif [ -x /usr/bin/Xdialog ] ; then\n isEulaAccepted=0\n LD_LIBRARY_PATH=\"\" Xdialog --title ${escapeShellString(config.ProductName)} --textbox \"$APPDIR/${config.EulaFile}\" 30 80 --ok-label Agree --cancel-label Disagree\n elif [ -x /usr/bin/kdialog ] ; then\n # cannot find any option to force Agree/Disagree buttons for kdialog. And official example exactly with OK button https://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs#Example_21._--textbox_dialog_box\n # in any case we pass labels text\n isEulaAccepted=0\n LD_LIBRARY_PATH=\"\" kdialog --textbox \"$APPDIR/${config.EulaFile}\" --yes-label Agree --cancel-label \"Disagree\"\n fi\n\n case $? in\n 0)\n isEulaAccepted=1\n echo \"License accepted\"\n mkdir -p \"$EULA_MARK_DIR\"\n touch \"$EULA_MARK_FILE\"\n ;;\n 1)\n echo \"License not accepted\"\n exit 0\n ;;\n -1)\n echo \"An unexpected error has occurred.\"\n isEulaAccepted=1\n ;;\n esac\n fi\nfi`\n : \"\"\n}\n`\n}\n"]}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.copyIcons = copyIcons;
|
|
4
|
+
exports.copyMimeTypes = copyMimeTypes;
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const fs = require("fs-extra");
|
|
7
|
+
const builder_util_1 = require("builder-util");
|
|
8
|
+
const ICON_DIR_RELATIVE_PATH = "usr/share/icons/hicolor";
|
|
9
|
+
const MIME_TYPE_DIR_RELATIVE_PATH = "usr/share/mime";
|
|
10
|
+
/**
|
|
11
|
+
* Escapes special XML characters to prevent injection
|
|
12
|
+
*/
|
|
13
|
+
function xmlEscape(str) {
|
|
14
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
15
|
+
}
|
|
16
|
+
async function copyIcons(options) {
|
|
17
|
+
const { stageDir, options: configuration } = options;
|
|
18
|
+
const iconCommonDir = path.join(stageDir, ICON_DIR_RELATIVE_PATH);
|
|
19
|
+
await fs.ensureDir(iconCommonDir);
|
|
20
|
+
const icons = configuration.icons;
|
|
21
|
+
if (!icons || icons.length === 0) {
|
|
22
|
+
throw new Error("At least one icon is required for AppImage");
|
|
23
|
+
}
|
|
24
|
+
const iconExtWithDot = path.extname(icons[0].file);
|
|
25
|
+
const iconFileName = `${configuration.executableName}${iconExtWithDot}`;
|
|
26
|
+
const maxIconIndex = icons.length - 1;
|
|
27
|
+
const iconInfoList = icons.map(icon => {
|
|
28
|
+
if (path.extname(icon.file) !== iconExtWithDot) {
|
|
29
|
+
throw new Error(`All icons must have the same extension: expected ${iconExtWithDot}, but got ${icon.file}`);
|
|
30
|
+
}
|
|
31
|
+
let iconSizeDir;
|
|
32
|
+
if (iconExtWithDot === ".svg") {
|
|
33
|
+
// SVG icons go in scalable/apps directory per freedesktop icon theme spec
|
|
34
|
+
iconSizeDir = "scalable/apps";
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
iconSizeDir = `${icon.size}x${icon.size}/apps`;
|
|
38
|
+
}
|
|
39
|
+
const iconRelativeToStageFile = path.join(ICON_DIR_RELATIVE_PATH, iconSizeDir, iconFileName);
|
|
40
|
+
const iconDir = path.join(iconCommonDir, iconSizeDir);
|
|
41
|
+
const iconFile = path.join(iconDir, iconFileName);
|
|
42
|
+
return { icon, iconDir, iconFile, iconRelativeToStageFile };
|
|
43
|
+
});
|
|
44
|
+
await Promise.all(iconInfoList.map(async ({ icon, iconDir, iconFile }) => {
|
|
45
|
+
await fs.ensureDir(iconDir);
|
|
46
|
+
await (0, builder_util_1.copyOrLinkFile)(icon.file, iconFile);
|
|
47
|
+
}));
|
|
48
|
+
// Create symlinks for the last (largest) icon
|
|
49
|
+
const { iconRelativeToStageFile } = iconInfoList[maxIconIndex];
|
|
50
|
+
await fs.symlink(iconRelativeToStageFile, path.join(stageDir, iconFileName));
|
|
51
|
+
await fs.symlink(iconRelativeToStageFile, path.join(stageDir, ".DirIcon"));
|
|
52
|
+
}
|
|
53
|
+
async function copyMimeTypes(options) {
|
|
54
|
+
const { stageDir, options: { fileAssociations, productName, executableName }, } = options;
|
|
55
|
+
if (!fileAssociations || fileAssociations.length === 0) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
const mimeTypeParts = [];
|
|
59
|
+
for (const fileAssociation of fileAssociations) {
|
|
60
|
+
if (!fileAssociation.mimeType) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
// XML-escape to prevent injection
|
|
64
|
+
mimeTypeParts.push(`<mime-type type="${xmlEscape(fileAssociation.mimeType)}">`);
|
|
65
|
+
mimeTypeParts.push(` <comment>${xmlEscape(productName)} document</comment>`);
|
|
66
|
+
// Handle extension(s)
|
|
67
|
+
const extensions = Array.isArray(fileAssociation.ext) ? fileAssociation.ext : [fileAssociation.ext];
|
|
68
|
+
for (const ext of extensions) {
|
|
69
|
+
// Validate extension doesn't contain dangerous characters
|
|
70
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(ext)) {
|
|
71
|
+
builder_util_1.log.warn({ extension: ext }, `file extension contains unexpected characters and may not be supported`);
|
|
72
|
+
}
|
|
73
|
+
mimeTypeParts.push(` <glob pattern="*.${xmlEscape(ext)}"/>`);
|
|
74
|
+
}
|
|
75
|
+
mimeTypeParts.push(' <generic-icon name="x-office-document"/>');
|
|
76
|
+
mimeTypeParts.push("</mime-type>");
|
|
77
|
+
}
|
|
78
|
+
// If no mime-types were generated, return null
|
|
79
|
+
if (mimeTypeParts.length === 0) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
const mimeTypeDir = path.join(stageDir, MIME_TYPE_DIR_RELATIVE_PATH);
|
|
83
|
+
const fileName = `${executableName}.xml`;
|
|
84
|
+
const mimeTypeFile = path.join(mimeTypeDir, fileName);
|
|
85
|
+
await fs.ensureDir(mimeTypeDir);
|
|
86
|
+
const xmlContent = ['<?xml version="1.0"?>', '<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">', ...mimeTypeParts, "</mime-info>"].join("\n");
|
|
87
|
+
// Use 0o644 (rw-r--r--) instead of 0o666 to avoid world-writable permissions
|
|
88
|
+
await fs.writeFile(mimeTypeFile, xmlContent, { mode: 0o644 });
|
|
89
|
+
return path.join(MIME_TYPE_DIR_RELATIVE_PATH, fileName);
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=appLauncher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appLauncher.js","sourceRoot":"","sources":["../../../src/targets/appimage/appLauncher.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from \"path\"\nimport * as fs from \"fs-extra\"\nimport { copyOrLinkFile, log } from \"builder-util\"\nimport { AppImageBuilderOptions } from \"./appImageUtil\"\n\nconst ICON_DIR_RELATIVE_PATH = \"usr/share/icons/hicolor\"\nconst MIME_TYPE_DIR_RELATIVE_PATH = \"usr/share/mime\"\n\n/**\n * Escapes special XML characters to prevent injection\n */\nfunction xmlEscape(str: string): string {\n return str.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\").replace(/\"/g, \""\").replace(/'/g, \"'\")\n}\n\nexport async function copyIcons(options: AppImageBuilderOptions): Promise<void> {\n const { stageDir, options: configuration } = options\n const iconCommonDir = path.join(stageDir, ICON_DIR_RELATIVE_PATH)\n\n await fs.ensureDir(iconCommonDir)\n\n const icons = configuration.icons\n if (!icons || icons.length === 0) {\n throw new Error(\"At least one icon is required for AppImage\")\n }\n\n const iconExtWithDot = path.extname(icons[0].file)\n const iconFileName = `${configuration.executableName}${iconExtWithDot}`\n const maxIconIndex = icons.length - 1\n\n const iconInfoList = icons.map(icon => {\n if (path.extname(icon.file) !== iconExtWithDot) {\n throw new Error(`All icons must have the same extension: expected ${iconExtWithDot}, but got ${icon.file}`)\n }\n let iconSizeDir: string\n\n if (iconExtWithDot === \".svg\") {\n // SVG icons go in scalable/apps directory per freedesktop icon theme spec\n iconSizeDir = \"scalable/apps\"\n } else {\n iconSizeDir = `${icon.size}x${icon.size}/apps`\n }\n\n const iconRelativeToStageFile = path.join(ICON_DIR_RELATIVE_PATH, iconSizeDir, iconFileName)\n const iconDir = path.join(iconCommonDir, iconSizeDir)\n const iconFile = path.join(iconDir, iconFileName)\n return { icon, iconDir, iconFile, iconRelativeToStageFile }\n })\n await Promise.all(\n iconInfoList.map(async ({ icon, iconDir, iconFile }) => {\n await fs.ensureDir(iconDir)\n await copyOrLinkFile(icon.file, iconFile)\n })\n )\n // Create symlinks for the last (largest) icon\n const { iconRelativeToStageFile } = iconInfoList[maxIconIndex]\n await fs.symlink(iconRelativeToStageFile, path.join(stageDir, iconFileName))\n await fs.symlink(iconRelativeToStageFile, path.join(stageDir, \".DirIcon\"))\n}\n\nexport async function copyMimeTypes(options: AppImageBuilderOptions): Promise<string | null> {\n const {\n stageDir,\n options: { fileAssociations, productName, executableName },\n } = options\n\n if (!fileAssociations || fileAssociations.length === 0) {\n return null\n }\n\n const mimeTypeParts: string[] = []\n\n for (const fileAssociation of fileAssociations) {\n if (!fileAssociation.mimeType) {\n continue\n }\n\n // XML-escape to prevent injection\n mimeTypeParts.push(`<mime-type type=\"${xmlEscape(fileAssociation.mimeType)}\">`)\n mimeTypeParts.push(` <comment>${xmlEscape(productName)} document</comment>`)\n\n // Handle extension(s)\n const extensions = Array.isArray(fileAssociation.ext) ? fileAssociation.ext : [fileAssociation.ext]\n\n for (const ext of extensions) {\n // Validate extension doesn't contain dangerous characters\n if (!/^[a-zA-Z0-9_-]+$/.test(ext)) {\n log.warn({ extension: ext }, `file extension contains unexpected characters and may not be supported`)\n }\n mimeTypeParts.push(` <glob pattern=\"*.${xmlEscape(ext)}\"/>`)\n }\n\n mimeTypeParts.push(' <generic-icon name=\"x-office-document\"/>')\n mimeTypeParts.push(\"</mime-type>\")\n }\n\n // If no mime-types were generated, return null\n if (mimeTypeParts.length === 0) {\n return null\n }\n\n const mimeTypeDir = path.join(stageDir, MIME_TYPE_DIR_RELATIVE_PATH)\n const fileName = `${executableName}.xml`\n const mimeTypeFile = path.join(mimeTypeDir, fileName)\n\n await fs.ensureDir(mimeTypeDir)\n\n const xmlContent = ['<?xml version=\"1.0\"?>', '<mime-info xmlns=\"http://www.freedesktop.org/standards/shared-mime-info\">', ...mimeTypeParts, \"</mime-info>\"].join(\"\\n\")\n\n // Use 0o644 (rw-r--r--) instead of 0o666 to avoid world-writable permissions\n await fs.writeFile(mimeTypeFile, xmlContent, { mode: 0o644 })\n\n return path.join(MIME_TYPE_DIR_RELATIVE_PATH, fileName)\n}\n"]}
|
package/out/targets/archive.js
CHANGED
|
@@ -8,7 +8,7 @@ const builder_util_1 = require("builder-util");
|
|
|
8
8
|
const fs_extra_1 = require("fs-extra");
|
|
9
9
|
const path = require("path");
|
|
10
10
|
const tar_1 = require("tar");
|
|
11
|
-
const
|
|
11
|
+
const linux_1 = require("../toolsets/linux");
|
|
12
12
|
/** @internal */
|
|
13
13
|
async function tar(compression, format, outFile, dirToArchive, isMacApp, tempDirManager) {
|
|
14
14
|
const tarFile = await tempDirManager.getTempFile({ suffix: ".tar" });
|
|
@@ -33,7 +33,7 @@ async function tar(compression, format, outFile, dirToArchive, isMacApp, tempDir
|
|
|
33
33
|
// noinspection SpellCheckingInspection
|
|
34
34
|
let lzipPath = "lzip";
|
|
35
35
|
if (process.platform === "darwin") {
|
|
36
|
-
lzipPath = path.join(await (0,
|
|
36
|
+
lzipPath = path.join(await (0, linux_1.getLinuxToolsPath)(), "bin", lzipPath);
|
|
37
37
|
}
|
|
38
38
|
await (0, builder_util_1.exec)(lzipPath, [compression === "store" ? "-1" : "-9", "--keep" /* keep (don't delete) input files */, tarFile]);
|
|
39
39
|
// bloody lzip creates file in the same dir where input file with postfix `.lz`, option --output doesn't work
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/targets/archive.ts"],"names":[],"mappings":"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","sourcesContent":["import { debug7z, exec, exists, getPath7za, log, statOrNull, unlinkIfExists } from \"builder-util\"\nimport { move } from \"fs-extra\"\nimport * as path from \"path\"\nimport { create } from \"tar\"\nimport { TmpDir } from \"temp-file\"\nimport { CompressionLevel } from \"../core\"\nimport { getLinuxToolsPath } from \"./tools\"\nimport { TarOptionsWithAliasesAsync } from \"tar/dist/commonjs/options\"\n\n/** @internal */\nexport async function tar(compression: CompressionLevel | any, format: string, outFile: string, dirToArchive: string, isMacApp: boolean, tempDirManager: TmpDir): Promise<void> {\n const tarFile = await tempDirManager.getTempFile({ suffix: \".tar\" })\n const tarArgs: TarOptionsWithAliasesAsync = {\n file: tarFile,\n portable: true,\n cwd: dirToArchive,\n prefix: path.basename(outFile, `.${format}`),\n }\n let tarDirectory = \".\"\n if (isMacApp) {\n delete tarArgs.prefix\n tarArgs.cwd = path.dirname(dirToArchive)\n tarDirectory = path.basename(dirToArchive)\n }\n\n await Promise.all([\n create(tarArgs, [tarDirectory]),\n // remove file before - 7z doesn't overwrite file, but update\n unlinkIfExists(outFile),\n ])\n\n if (format === \"tar.lz\") {\n // noinspection SpellCheckingInspection\n let lzipPath = \"lzip\"\n if (process.platform === \"darwin\") {\n lzipPath = path.join(await getLinuxToolsPath(), \"bin\", lzipPath)\n }\n await exec(lzipPath, [compression === \"store\" ? \"-1\" : \"-9\", \"--keep\" /* keep (don't delete) input files */, tarFile])\n // bloody lzip creates file in the same dir where input file with postfix `.lz`, option --output doesn't work\n await move(`${tarFile}.lz`, outFile)\n return\n }\n\n const args = compute7zCompressArgs(format === \"tar.xz\" ? \"xz\" : format === \"tar.bz2\" ? \"bzip2\" : \"gzip\", {\n isRegularFile: true,\n method: \"DEFAULT\",\n compression,\n })\n args.push(outFile, tarFile)\n await exec(\n await getPath7za(),\n args,\n {\n cwd: path.dirname(dirToArchive),\n },\n debug7z.enabled\n )\n}\n\nexport interface ArchiveOptions {\n compression?: CompressionLevel | null\n\n /**\n * @default false\n */\n withoutDir?: boolean\n\n /**\n * @default true\n */\n solid?: boolean\n\n /**\n * @default true\n */\n isArchiveHeaderCompressed?: boolean\n\n dictSize?: number\n excluded?: Array<string> | null\n\n // DEFAULT allows to disable custom logic and do not pass method switch at all\n method?: \"Copy\" | \"LZMA\" | \"Deflate\" | \"DEFAULT\"\n\n isRegularFile?: boolean\n}\n\nexport function compute7zCompressArgs(format: string, options: ArchiveOptions = {}) {\n let storeOnly = options.compression === \"store\"\n const args = debug7zArgs(\"a\")\n\n let isLevelSet = false\n if (process.env.ELECTRON_BUILDER_COMPRESSION_LEVEL != null) {\n storeOnly = false\n args.push(`-mx=${process.env.ELECTRON_BUILDER_COMPRESSION_LEVEL}`)\n isLevelSet = true\n }\n\n const isZip = format === \"zip\"\n if (!storeOnly) {\n if (isZip && options.compression === \"maximum\") {\n // http://superuser.com/a/742034\n args.push(\"-mfb=258\", \"-mpass=15\")\n }\n\n if (!isLevelSet) {\n // https://github.com/electron-userland/electron-builder/pull/3032\n args.push(\"-mx=\" + (!isZip || options.compression === \"maximum\" ? \"9\" : \"7\"))\n }\n }\n\n if (options.dictSize != null) {\n args.push(`-md=${options.dictSize}m`)\n }\n\n // https://sevenzip.osdn.jp/chm/cmdline/switches/method.htm#7Z\n // https://stackoverflow.com/questions/27136783/7zip-produces-different-output-from-identical-input\n // tc and ta are off by default, but to be sure, we explicitly set it to off\n // disable \"Stores NTFS timestamps for files: Modification time, Creation time, Last access time.\" to produce the same archive for the same data\n if (!options.isRegularFile) {\n args.push(\"-mtc=off\")\n }\n\n if (format === \"7z\" || format.endsWith(\".7z\")) {\n if (options.solid === false) {\n args.push(\"-ms=off\")\n }\n\n if (options.isArchiveHeaderCompressed === false) {\n args.push(\"-mhc=off\")\n }\n\n // https://www.7-zip.org/7z.html\n // Filters: BCJ, BCJ2, ARM, ARMT, IA64, PPC, SPARC, ...\n if (process.env.ELECTRON_BUILDER_7Z_FILTER) {\n args.push(`-mf=${process.env.ELECTRON_BUILDER_7Z_FILTER}`)\n }\n\n // args valid only for 7z\n // -mtm=off disable \"Stores last Modified timestamps for files.\"\n args.push(\"-mtm=off\", \"-mta=off\")\n }\n\n if (options.method != null) {\n if (options.method !== \"DEFAULT\") {\n args.push(`-mm=${options.method}`)\n }\n } else if (isZip || storeOnly) {\n args.push(`-mm=${storeOnly ? \"Copy\" : \"Deflate\"}`)\n }\n\n if (isZip) {\n // -mcu switch: 7-Zip uses UTF-8, if there are non-ASCII symbols.\n // because default mode: 7-Zip uses UTF-8, if the local code page doesn't contain required symbols.\n // but archive should be the same regardless where produced\n args.push(\"-mcu\")\n }\n return args\n}\n\nexport function computeZipCompressArgs(options: ArchiveOptions = {}) {\n let storeOnly = options.compression === \"store\"\n // do not deref symlinks\n const args = [\"-q\", \"-r\", \"-y\"]\n if (debug7z.enabled) {\n args.push(\"-v\")\n }\n\n if (process.env.ELECTRON_BUILDER_COMPRESSION_LEVEL != null) {\n storeOnly = false\n args.push(`-${process.env.ELECTRON_BUILDER_COMPRESSION_LEVEL}`)\n } else if (!storeOnly) {\n // https://github.com/electron-userland/electron-builder/pull/3032\n args.push(\"-\" + (options.compression === \"maximum\" ? \"9\" : \"7\"))\n }\n\n if (options.dictSize != null) {\n log.warn({ distSize: options.dictSize }, `ignoring unsupported option`)\n }\n\n // do not save extra file attributes (Extended Attributes on OS/2, uid/gid and file times on Unix)\n if (!options.isRegularFile) {\n args.push(\"-X\")\n }\n\n if (options.method != null) {\n if (options.method !== \"DEFAULT\") {\n log.warn({ method: options.method }, `ignoring unsupported option`)\n }\n } else {\n args.push(\"-Z\", storeOnly ? \"store\" : \"deflate\")\n }\n return args\n}\n\n// 7z is very fast, so, use ultra compression\n/** @internal */\nexport async function archive(format: string, outFile: string, dirToArchive: string, options: ArchiveOptions = {}): Promise<string> {\n const outFileStat = await statOrNull(outFile)\n const dirStat = await statOrNull(dirToArchive)\n if (outFileStat && dirStat && outFileStat.mtime > dirStat.mtime) {\n log.info({ reason: \"Archive file is up to date\", outFile }, `skipped archiving`)\n return outFile\n }\n let use7z = true\n if (process.platform === \"darwin\" && format === \"zip\" && dirToArchive.normalize(\"NFC\") !== dirToArchive) {\n log.warn({ reason: \"7z doesn't support NFD-normalized filenames\" }, `using zip`)\n use7z = false\n }\n const args = use7z ? compute7zCompressArgs(format, options) : computeZipCompressArgs(options)\n // remove file before - 7z and zip doesn't overwrite file, but update\n await unlinkIfExists(outFile)\n\n args.push(outFile, options.withoutDir ? \".\" : path.basename(dirToArchive))\n if (options.excluded != null) {\n for (const mask of options.excluded) {\n args.push(use7z ? `-xr!${mask}` : `-x${mask}`)\n }\n }\n\n try {\n const binary = use7z ? await getPath7za() : \"zip\"\n await exec(\n binary,\n args,\n {\n cwd: options.withoutDir ? dirToArchive : path.dirname(dirToArchive),\n },\n debug7z.enabled\n )\n } catch (e: any) {\n if (e.code === \"ENOENT\" && !(await exists(dirToArchive))) {\n throw new Error(`Cannot create archive: \"${dirToArchive}\" doesn't exist`)\n } else {\n throw e\n }\n }\n\n return outFile\n}\n\nfunction debug7zArgs(command: \"a\" | \"x\"): Array<string> {\n const args = [command, \"-bd\"]\n if (debug7z.enabled) {\n args.push(\"-bb\")\n }\n return args\n}\n"]}
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/targets/archive.ts"],"names":[],"mappings":";;AAUA,kBA+CC;AA6BD,sDAuEC;AAED,wDAiCC;AAID,0BA0CC;AA9OD,+CAAiG;AACjG,uCAA+B;AAC/B,6BAA4B;AAC5B,6BAA4B;AAG5B,6CAAqD;AAGrD,gBAAgB;AACT,KAAK,UAAU,GAAG,CAAC,WAAmC,EAAE,MAAc,EAAE,OAAe,EAAE,YAAoB,EAAE,QAAiB,EAAE,cAAsB;IAC7J,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACpE,MAAM,OAAO,GAA+B;QAC1C,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,IAAI;QACd,GAAG,EAAE,YAAY;QACjB,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,MAAM,EAAE,CAAC;KAC7C,CAAA;IACD,IAAI,YAAY,GAAG,GAAG,CAAA;IACtB,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,OAAO,CAAC,MAAM,CAAA;QACrB,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;QACxC,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;IAC5C,CAAC;IAED,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,IAAA,YAAM,EAAC,OAAO,EAAE,CAAC,YAAY,CAAC,CAAC;QAC/B,6DAA6D;QAC7D,IAAA,6BAAc,EAAC,OAAO,CAAC;KACxB,CAAC,CAAA;IAEF,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,uCAAuC;QACvC,IAAI,QAAQ,GAAG,MAAM,CAAA;QACrB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,IAAA,yBAAiB,GAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAA;QAClE,CAAC;QACD,MAAM,IAAA,mBAAI,EAAC,QAAQ,EAAE,CAAC,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,qCAAqC,EAAE,OAAO,CAAC,CAAC,CAAA;QACtH,6GAA6G;QAC7G,MAAM,IAAA,eAAI,EAAC,GAAG,OAAO,KAAK,EAAE,OAAO,CAAC,CAAA;QACpC,OAAM;IACR,CAAC;IAED,MAAM,IAAI,GAAG,qBAAqB,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE;QACvG,aAAa,EAAE,IAAI;QACnB,MAAM,EAAE,SAAS;QACjB,WAAW;KACZ,CAAC,CAAA;IACF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAC3B,MAAM,IAAA,mBAAI,EACR,MAAM,IAAA,yBAAU,GAAE,EAClB,IAAI,EACJ;QACE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;KAChC,EACD,sBAAO,CAAC,OAAO,CAChB,CAAA;AACH,CAAC;AA6BD,SAAgB,qBAAqB,CAAC,MAAc,EAAE,UAA0B,EAAE;IAChF,IAAI,SAAS,GAAG,OAAO,CAAC,WAAW,KAAK,OAAO,CAAA;IAC/C,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;IAE7B,IAAI,UAAU,GAAG,KAAK,CAAA;IACtB,IAAI,OAAO,CAAC,GAAG,CAAC,kCAAkC,IAAI,IAAI,EAAE,CAAC;QAC3D,SAAS,GAAG,KAAK,CAAA;QACjB,IAAI,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,CAAC,CAAA;QAClE,UAAU,GAAG,IAAI,CAAA;IACnB,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,KAAK,KAAK,CAAA;IAC9B,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,IAAI,KAAK,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YAC/C,gCAAgC;YAChC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;QACpC,CAAC;QAED,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,kEAAkE;YAClE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAC/E,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;IACvC,CAAC;IAED,8DAA8D;IAC9D,mGAAmG;IACnG,4EAA4E;IAC5E,gJAAgJ;IAChJ,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACvB,CAAC;IAED,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9C,IAAI,OAAO,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACtB,CAAC;QAED,IAAI,OAAO,CAAC,yBAAyB,KAAK,KAAK,EAAE,CAAC;YAChD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACvB,CAAC;QAED,gCAAgC;QAChC,uDAAuD;QACvD,IAAI,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,CAAC;YAC3C,IAAI,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,CAAC,CAAA;QAC5D,CAAC;QAED,yBAAyB;QACzB,gEAAgE;QAChE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAA;IACnC,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;QAC3B,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;QACpC,CAAC;IACH,CAAC;SAAM,IAAI,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAA;IACpD,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACV,kEAAkE;QAClE,mGAAmG;QACnG,2DAA2D;QAC3D,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACnB,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAgB,sBAAsB,CAAC,UAA0B,EAAE;IACjE,IAAI,SAAS,GAAG,OAAO,CAAC,WAAW,KAAK,OAAO,CAAA;IAC/C,wBAAwB;IACxB,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;IAC/B,IAAI,sBAAO,CAAC,OAAO,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,kCAAkC,IAAI,IAAI,EAAE,CAAC;QAC3D,SAAS,GAAG,KAAK,CAAA;QACjB,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,CAAC,CAAA;IACjE,CAAC;SAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtB,kEAAkE;QAClE,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IAClE,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC7B,kBAAG,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,6BAA6B,CAAC,CAAA;IACzE,CAAC;IAED,kGAAkG;IAClG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;QAC3B,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACjC,kBAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,6BAA6B,CAAC,CAAA;QACrE,CAAC;IACH,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IAClD,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,6CAA6C;AAC7C,gBAAgB;AACT,KAAK,UAAU,OAAO,CAAC,MAAc,EAAE,OAAe,EAAE,YAAoB,EAAE,UAA0B,EAAE;IAC/G,MAAM,WAAW,GAAG,MAAM,IAAA,yBAAU,EAAC,OAAO,CAAC,CAAA;IAC7C,MAAM,OAAO,GAAG,MAAM,IAAA,yBAAU,EAAC,YAAY,CAAC,CAAA;IAC9C,IAAI,WAAW,IAAI,OAAO,IAAI,WAAW,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;QAChE,kBAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,4BAA4B,EAAE,OAAO,EAAE,EAAE,mBAAmB,CAAC,CAAA;QAChF,OAAO,OAAO,CAAA;IAChB,CAAC;IACD,IAAI,KAAK,GAAG,IAAI,CAAA;IAChB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,KAAK,KAAK,IAAI,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,YAAY,EAAE,CAAC;QACxG,kBAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,6CAA6C,EAAE,EAAE,WAAW,CAAC,CAAA;QAChF,KAAK,GAAG,KAAK,CAAA;IACf,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAA;IAC7F,qEAAqE;IACrE,MAAM,IAAA,6BAAc,EAAC,OAAO,CAAC,CAAA;IAE7B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAA;IAC1E,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;QAChD,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,IAAA,yBAAU,GAAE,CAAC,CAAC,CAAC,KAAK,CAAA;QACjD,MAAM,IAAA,mBAAI,EACR,MAAM,EACN,IAAI,EACJ;YACE,GAAG,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;SACpE,EACD,sBAAO,CAAC,OAAO,CAChB,CAAA;IACH,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAA,qBAAM,EAAC,YAAY,CAAC,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,KAAK,CAAC,2BAA2B,YAAY,iBAAiB,CAAC,CAAA;QAC3E,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,CAAA;QACT,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAS,WAAW,CAAC,OAAkB;IACrC,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAC7B,IAAI,sBAAO,CAAC,OAAO,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAClB,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["import { debug7z, exec, exists, getPath7za, log, statOrNull, unlinkIfExists } from \"builder-util\"\nimport { move } from \"fs-extra\"\nimport * as path from \"path\"\nimport { create } from \"tar\"\nimport { TmpDir } from \"temp-file\"\nimport { CompressionLevel } from \"../core\"\nimport { getLinuxToolsPath } from \"../toolsets/linux\"\nimport { TarOptionsWithAliasesAsync } from \"tar/dist/commonjs/options\"\n\n/** @internal */\nexport async function tar(compression: CompressionLevel | any, format: string, outFile: string, dirToArchive: string, isMacApp: boolean, tempDirManager: TmpDir): Promise<void> {\n const tarFile = await tempDirManager.getTempFile({ suffix: \".tar\" })\n const tarArgs: TarOptionsWithAliasesAsync = {\n file: tarFile,\n portable: true,\n cwd: dirToArchive,\n prefix: path.basename(outFile, `.${format}`),\n }\n let tarDirectory = \".\"\n if (isMacApp) {\n delete tarArgs.prefix\n tarArgs.cwd = path.dirname(dirToArchive)\n tarDirectory = path.basename(dirToArchive)\n }\n\n await Promise.all([\n create(tarArgs, [tarDirectory]),\n // remove file before - 7z doesn't overwrite file, but update\n unlinkIfExists(outFile),\n ])\n\n if (format === \"tar.lz\") {\n // noinspection SpellCheckingInspection\n let lzipPath = \"lzip\"\n if (process.platform === \"darwin\") {\n lzipPath = path.join(await getLinuxToolsPath(), \"bin\", lzipPath)\n }\n await exec(lzipPath, [compression === \"store\" ? \"-1\" : \"-9\", \"--keep\" /* keep (don't delete) input files */, tarFile])\n // bloody lzip creates file in the same dir where input file with postfix `.lz`, option --output doesn't work\n await move(`${tarFile}.lz`, outFile)\n return\n }\n\n const args = compute7zCompressArgs(format === \"tar.xz\" ? \"xz\" : format === \"tar.bz2\" ? \"bzip2\" : \"gzip\", {\n isRegularFile: true,\n method: \"DEFAULT\",\n compression,\n })\n args.push(outFile, tarFile)\n await exec(\n await getPath7za(),\n args,\n {\n cwd: path.dirname(dirToArchive),\n },\n debug7z.enabled\n )\n}\n\nexport interface ArchiveOptions {\n compression?: CompressionLevel | null\n\n /**\n * @default false\n */\n withoutDir?: boolean\n\n /**\n * @default true\n */\n solid?: boolean\n\n /**\n * @default true\n */\n isArchiveHeaderCompressed?: boolean\n\n dictSize?: number\n excluded?: Array<string> | null\n\n // DEFAULT allows to disable custom logic and do not pass method switch at all\n method?: \"Copy\" | \"LZMA\" | \"Deflate\" | \"DEFAULT\"\n\n isRegularFile?: boolean\n}\n\nexport function compute7zCompressArgs(format: string, options: ArchiveOptions = {}) {\n let storeOnly = options.compression === \"store\"\n const args = debug7zArgs(\"a\")\n\n let isLevelSet = false\n if (process.env.ELECTRON_BUILDER_COMPRESSION_LEVEL != null) {\n storeOnly = false\n args.push(`-mx=${process.env.ELECTRON_BUILDER_COMPRESSION_LEVEL}`)\n isLevelSet = true\n }\n\n const isZip = format === \"zip\"\n if (!storeOnly) {\n if (isZip && options.compression === \"maximum\") {\n // http://superuser.com/a/742034\n args.push(\"-mfb=258\", \"-mpass=15\")\n }\n\n if (!isLevelSet) {\n // https://github.com/electron-userland/electron-builder/pull/3032\n args.push(\"-mx=\" + (!isZip || options.compression === \"maximum\" ? \"9\" : \"7\"))\n }\n }\n\n if (options.dictSize != null) {\n args.push(`-md=${options.dictSize}m`)\n }\n\n // https://sevenzip.osdn.jp/chm/cmdline/switches/method.htm#7Z\n // https://stackoverflow.com/questions/27136783/7zip-produces-different-output-from-identical-input\n // tc and ta are off by default, but to be sure, we explicitly set it to off\n // disable \"Stores NTFS timestamps for files: Modification time, Creation time, Last access time.\" to produce the same archive for the same data\n if (!options.isRegularFile) {\n args.push(\"-mtc=off\")\n }\n\n if (format === \"7z\" || format.endsWith(\".7z\")) {\n if (options.solid === false) {\n args.push(\"-ms=off\")\n }\n\n if (options.isArchiveHeaderCompressed === false) {\n args.push(\"-mhc=off\")\n }\n\n // https://www.7-zip.org/7z.html\n // Filters: BCJ, BCJ2, ARM, ARMT, IA64, PPC, SPARC, ...\n if (process.env.ELECTRON_BUILDER_7Z_FILTER) {\n args.push(`-mf=${process.env.ELECTRON_BUILDER_7Z_FILTER}`)\n }\n\n // args valid only for 7z\n // -mtm=off disable \"Stores last Modified timestamps for files.\"\n args.push(\"-mtm=off\", \"-mta=off\")\n }\n\n if (options.method != null) {\n if (options.method !== \"DEFAULT\") {\n args.push(`-mm=${options.method}`)\n }\n } else if (isZip || storeOnly) {\n args.push(`-mm=${storeOnly ? \"Copy\" : \"Deflate\"}`)\n }\n\n if (isZip) {\n // -mcu switch: 7-Zip uses UTF-8, if there are non-ASCII symbols.\n // because default mode: 7-Zip uses UTF-8, if the local code page doesn't contain required symbols.\n // but archive should be the same regardless where produced\n args.push(\"-mcu\")\n }\n return args\n}\n\nexport function computeZipCompressArgs(options: ArchiveOptions = {}) {\n let storeOnly = options.compression === \"store\"\n // do not deref symlinks\n const args = [\"-q\", \"-r\", \"-y\"]\n if (debug7z.enabled) {\n args.push(\"-v\")\n }\n\n if (process.env.ELECTRON_BUILDER_COMPRESSION_LEVEL != null) {\n storeOnly = false\n args.push(`-${process.env.ELECTRON_BUILDER_COMPRESSION_LEVEL}`)\n } else if (!storeOnly) {\n // https://github.com/electron-userland/electron-builder/pull/3032\n args.push(\"-\" + (options.compression === \"maximum\" ? \"9\" : \"7\"))\n }\n\n if (options.dictSize != null) {\n log.warn({ distSize: options.dictSize }, `ignoring unsupported option`)\n }\n\n // do not save extra file attributes (Extended Attributes on OS/2, uid/gid and file times on Unix)\n if (!options.isRegularFile) {\n args.push(\"-X\")\n }\n\n if (options.method != null) {\n if (options.method !== \"DEFAULT\") {\n log.warn({ method: options.method }, `ignoring unsupported option`)\n }\n } else {\n args.push(\"-Z\", storeOnly ? \"store\" : \"deflate\")\n }\n return args\n}\n\n// 7z is very fast, so, use ultra compression\n/** @internal */\nexport async function archive(format: string, outFile: string, dirToArchive: string, options: ArchiveOptions = {}): Promise<string> {\n const outFileStat = await statOrNull(outFile)\n const dirStat = await statOrNull(dirToArchive)\n if (outFileStat && dirStat && outFileStat.mtime > dirStat.mtime) {\n log.info({ reason: \"Archive file is up to date\", outFile }, `skipped archiving`)\n return outFile\n }\n let use7z = true\n if (process.platform === \"darwin\" && format === \"zip\" && dirToArchive.normalize(\"NFC\") !== dirToArchive) {\n log.warn({ reason: \"7z doesn't support NFD-normalized filenames\" }, `using zip`)\n use7z = false\n }\n const args = use7z ? compute7zCompressArgs(format, options) : computeZipCompressArgs(options)\n // remove file before - 7z and zip doesn't overwrite file, but update\n await unlinkIfExists(outFile)\n\n args.push(outFile, options.withoutDir ? \".\" : path.basename(dirToArchive))\n if (options.excluded != null) {\n for (const mask of options.excluded) {\n args.push(use7z ? `-xr!${mask}` : `-x${mask}`)\n }\n }\n\n try {\n const binary = use7z ? await getPath7za() : \"zip\"\n await exec(\n binary,\n args,\n {\n cwd: options.withoutDir ? dirToArchive : path.dirname(dirToArchive),\n },\n debug7z.enabled\n )\n } catch (e: any) {\n if (e.code === \"ENOENT\" && !(await exists(dirToArchive))) {\n throw new Error(`Cannot create archive: \"${dirToArchive}\" doesn't exist`)\n } else {\n throw e\n }\n }\n\n return outFile\n}\n\nfunction debug7zArgs(command: \"a\" | \"x\"): Array<string> {\n const args = [command, \"-bd\"]\n if (debug7z.enabled) {\n args.push(\"-bb\")\n }\n return args\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Arch } from "builder-util";
|
|
2
|
+
export declare function getLinuxToolsPath(): Promise<string>;
|
|
3
|
+
export declare function getFpmPath(): Promise<string>;
|
|
4
|
+
export declare function getAppImageTools(targetArch: Arch): Promise<{
|
|
5
|
+
mksquashfs: string;
|
|
6
|
+
desktopFileValidate: string;
|
|
7
|
+
runtime: string;
|
|
8
|
+
runtimeLibraries: string;
|
|
9
|
+
}>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getLinuxToolsPath = getLinuxToolsPath;
|
|
4
|
+
exports.getFpmPath = getFpmPath;
|
|
5
|
+
exports.getAppImageTools = getAppImageTools;
|
|
6
|
+
const builder_util_1 = require("builder-util");
|
|
7
|
+
const path = require("path");
|
|
8
|
+
const binDownload_1 = require("../binDownload");
|
|
9
|
+
// It's just easier to copy the map of checksums here rather than adding them to within each if-statement. Also, easy copy-paste from the releases page
|
|
10
|
+
const fpmChecksums = {
|
|
11
|
+
"fpm-1.17.0-ruby-3.4.3-darwin-arm64.7z": "0n3BG/Xz1T5YIsoNNTG1bBege9E8A7rym5e3mfzHSHbiSiTS44v6GIHW4amDQk1Y5dtKtWXVq7FwjdmAf3kmMg==",
|
|
12
|
+
"fpm-1.17.0-ruby-3.4.3-darwin-x86_64.7z": "wPX3UheBznIlAXduM22W/d27i+DZVIB/MYnY5eh/qLeEEASZqHJWgN+pIckz3jT0dP37g1SQCikXXfsgxtMSPA==",
|
|
13
|
+
"fpm-1.17.0-ruby-3.4.3-linux-amd64.7z": "7miGWr6dfJSzXDD9ALqkwxvGACp7s7GR50NPcU0YwzbJL825H1SLwGJSGME+v57BxDI2xac47gFEkRZf5u9EtA==",
|
|
14
|
+
"fpm-1.17.0-ruby-3.4.3-linux-arm64v8.7z": "moRNjg6Q2iSXpkrm5sGNL2F6KilGNPagbefxhtr3VEqvAUSg2k2pMLr5xXUo0L4rZ4V+uETbwmbDCpeO3pmLyQ==",
|
|
15
|
+
"fpm-1.17.0-ruby-3.4.3-linux-i386.7z": "UPzsXhkW2T7+oHSKgFsZsFUxxmPC9lNZHsQbT+OeoTbIGsb6+qf3m7c6uP0XvRFnJiu3MM3lE1xAWQOctvajWA==",
|
|
16
|
+
};
|
|
17
|
+
function getLinuxToolsPath() {
|
|
18
|
+
return (0, binDownload_1.getBinFromUrl)("linux-tools-mac-10.12.3", "linux-tools-mac-10.12.3.7z", "SQ8fqIRVXuQVWnVgaMTDWyf2TLAJjJYw3tRSqQJECmgF6qdM7Kogfa6KD49RbGzzMYIFca9Uw3MdsxzOPRWcYw==");
|
|
19
|
+
}
|
|
20
|
+
async function getFpmPath() {
|
|
21
|
+
if (process.env.CUSTOM_FPM_PATH != null) {
|
|
22
|
+
return path.resolve(process.env.CUSTOM_FPM_PATH);
|
|
23
|
+
}
|
|
24
|
+
const exec = "fpm";
|
|
25
|
+
if (process.platform === "win32" || process.env.USE_SYSTEM_FPM === "true") {
|
|
26
|
+
return exec;
|
|
27
|
+
}
|
|
28
|
+
const getKey = () => {
|
|
29
|
+
if (process.platform === "linux") {
|
|
30
|
+
if (process.arch == "x64") {
|
|
31
|
+
return "fpm-1.17.0-ruby-3.4.3-linux-amd64.7z";
|
|
32
|
+
}
|
|
33
|
+
else if (process.arch === "arm64") {
|
|
34
|
+
return "fpm-1.17.0-ruby-3.4.3-linux-arm64v8.7z";
|
|
35
|
+
}
|
|
36
|
+
return "fpm-1.17.0-ruby-3.4.3-linux-i386.7z";
|
|
37
|
+
}
|
|
38
|
+
// darwin arm64
|
|
39
|
+
if (process.arch === "arm64") {
|
|
40
|
+
return "fpm-1.17.0-ruby-3.4.3-darwin-arm64.7z";
|
|
41
|
+
}
|
|
42
|
+
return "fpm-1.17.0-ruby-3.4.3-darwin-x86_64.7z";
|
|
43
|
+
};
|
|
44
|
+
const filename = getKey();
|
|
45
|
+
const fpmPath = await (0, binDownload_1.getBinFromUrl)("fpm@2.1.4", filename, fpmChecksums[filename]);
|
|
46
|
+
return path.join(fpmPath, exec);
|
|
47
|
+
}
|
|
48
|
+
async function getAppImageTools(targetArch) {
|
|
49
|
+
var _a;
|
|
50
|
+
const override = (_a = process.env.APPIMAGE_TOOLS_PATH) === null || _a === void 0 ? void 0 : _a.trim();
|
|
51
|
+
const artifactPath = override ||
|
|
52
|
+
(await (0, binDownload_1.downloadArtifact)({
|
|
53
|
+
releaseName: "appimage@1.0.2",
|
|
54
|
+
filenameWithExt: "appimage-tools-runtime-20251108.tar.gz",
|
|
55
|
+
checksums: {
|
|
56
|
+
"appimage-tools-runtime-20251108.tar.gz": "a784a8c26331ec2e945c23d6bdb14af5c9df27f5939825d84b8709c61dc81eb0",
|
|
57
|
+
},
|
|
58
|
+
githubOrgRepo: "electron-userland/electron-builder-binaries",
|
|
59
|
+
}));
|
|
60
|
+
const runtimeArch = targetArch === builder_util_1.Arch.armv7l ? "arm32" : targetArch === builder_util_1.Arch.arm64 ? "arm64" : targetArch === builder_util_1.Arch.ia32 ? "ia32" : "x64";
|
|
61
|
+
return {
|
|
62
|
+
mksquashfs: path.join(artifactPath, "mksquashfs"),
|
|
63
|
+
desktopFileValidate: path.join(artifactPath, "desktop-file-validate"),
|
|
64
|
+
runtime: path.join(artifactPath, "runtimes", `runtime-${runtimeArch}`),
|
|
65
|
+
runtimeLibraries: path.join(artifactPath, "lib", runtimeArch),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=linux.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linux.js","sourceRoot":"","sources":["../../src/toolsets/linux.ts"],"names":[],"mappings":";;AAaA,8CAEC;AAED,gCA2BC;AAED,4CAoBC;AAlED,+CAAmC;AACnC,6BAA4B;AAC5B,gDAAgE;AAEhE,uJAAuJ;AACvJ,MAAM,YAAY,GAAG;IACnB,uCAAuC,EAAE,0FAA0F;IACnI,wCAAwC,EAAE,0FAA0F;IACpI,sCAAsC,EAAE,0FAA0F;IAClI,wCAAwC,EAAE,0FAA0F;IACpI,qCAAqC,EAAE,0FAA0F;CACzH,CAAA;AAEV,SAAgB,iBAAiB;IAC/B,OAAO,IAAA,2BAAa,EAAC,yBAAyB,EAAE,4BAA4B,EAAE,0FAA0F,CAAC,CAAA;AAC3K,CAAC;AAEM,KAAK,UAAU,UAAU;IAC9B,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;IAClD,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAA;IAClB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM,EAAE,CAAC;QAC1E,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACjC,IAAI,OAAO,CAAC,IAAI,IAAI,KAAK,EAAE,CAAC;gBAC1B,OAAO,sCAAsC,CAAA;YAC/C,CAAC;iBAAM,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACpC,OAAO,wCAAwC,CAAA;YACjD,CAAC;YACD,OAAO,qCAAqC,CAAA;QAC9C,CAAC;QACD,eAAe;QACf,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC7B,OAAO,uCAAuC,CAAA;QAChD,CAAC;QACD,OAAO,wCAAwC,CAAA;IACjD,CAAC,CAAA;IAED,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAA;IACzB,MAAM,OAAO,GAAG,MAAM,IAAA,2BAAa,EAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAA;IAClF,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;AACjC,CAAC;AAEM,KAAK,UAAU,gBAAgB,CAAC,UAAgB;;IACrD,MAAM,QAAQ,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,mBAAmB,0CAAE,IAAI,EAAE,CAAA;IACxD,MAAM,YAAY,GAChB,QAAQ;QACR,CAAC,MAAM,IAAA,8BAAgB,EAAC;YACtB,WAAW,EAAE,gBAAgB;YAC7B,eAAe,EAAE,wCAAwC;YACzD,SAAS,EAAE;gBACT,wCAAwC,EAAE,kEAAkE;aAC7G;YACD,aAAa,EAAE,6CAA6C;SAC7D,CAAC,CAAC,CAAA;IAEL,MAAM,WAAW,GAAG,UAAU,KAAK,mBAAI,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,KAAK,mBAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,KAAK,mBAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAA;IAC1I,OAAO;QACL,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC;QACjD,mBAAmB,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,uBAAuB,CAAC;QACrE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE,WAAW,WAAW,EAAE,CAAC;QACtE,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,WAAW,CAAC;KAC9D,CAAA;AACH,CAAC","sourcesContent":["import { Arch } from \"builder-util\"\nimport * as path from \"path\"\nimport { downloadArtifact, getBinFromUrl } from \"../binDownload\"\n\n// It's just easier to copy the map of checksums here rather than adding them to within each if-statement. Also, easy copy-paste from the releases page\nconst fpmChecksums = {\n \"fpm-1.17.0-ruby-3.4.3-darwin-arm64.7z\": \"0n3BG/Xz1T5YIsoNNTG1bBege9E8A7rym5e3mfzHSHbiSiTS44v6GIHW4amDQk1Y5dtKtWXVq7FwjdmAf3kmMg==\",\n \"fpm-1.17.0-ruby-3.4.3-darwin-x86_64.7z\": \"wPX3UheBznIlAXduM22W/d27i+DZVIB/MYnY5eh/qLeEEASZqHJWgN+pIckz3jT0dP37g1SQCikXXfsgxtMSPA==\",\n \"fpm-1.17.0-ruby-3.4.3-linux-amd64.7z\": \"7miGWr6dfJSzXDD9ALqkwxvGACp7s7GR50NPcU0YwzbJL825H1SLwGJSGME+v57BxDI2xac47gFEkRZf5u9EtA==\",\n \"fpm-1.17.0-ruby-3.4.3-linux-arm64v8.7z\": \"moRNjg6Q2iSXpkrm5sGNL2F6KilGNPagbefxhtr3VEqvAUSg2k2pMLr5xXUo0L4rZ4V+uETbwmbDCpeO3pmLyQ==\",\n \"fpm-1.17.0-ruby-3.4.3-linux-i386.7z\": \"UPzsXhkW2T7+oHSKgFsZsFUxxmPC9lNZHsQbT+OeoTbIGsb6+qf3m7c6uP0XvRFnJiu3MM3lE1xAWQOctvajWA==\",\n} as const\n\nexport function getLinuxToolsPath() {\n return getBinFromUrl(\"linux-tools-mac-10.12.3\", \"linux-tools-mac-10.12.3.7z\", \"SQ8fqIRVXuQVWnVgaMTDWyf2TLAJjJYw3tRSqQJECmgF6qdM7Kogfa6KD49RbGzzMYIFca9Uw3MdsxzOPRWcYw==\")\n}\n\nexport async function getFpmPath() {\n if (process.env.CUSTOM_FPM_PATH != null) {\n return path.resolve(process.env.CUSTOM_FPM_PATH)\n }\n const exec = \"fpm\"\n if (process.platform === \"win32\" || process.env.USE_SYSTEM_FPM === \"true\") {\n return exec\n }\n const getKey = () => {\n if (process.platform === \"linux\") {\n if (process.arch == \"x64\") {\n return \"fpm-1.17.0-ruby-3.4.3-linux-amd64.7z\"\n } else if (process.arch === \"arm64\") {\n return \"fpm-1.17.0-ruby-3.4.3-linux-arm64v8.7z\"\n }\n return \"fpm-1.17.0-ruby-3.4.3-linux-i386.7z\"\n }\n // darwin arm64\n if (process.arch === \"arm64\") {\n return \"fpm-1.17.0-ruby-3.4.3-darwin-arm64.7z\"\n }\n return \"fpm-1.17.0-ruby-3.4.3-darwin-x86_64.7z\"\n }\n\n const filename = getKey()\n const fpmPath = await getBinFromUrl(\"fpm@2.1.4\", filename, fpmChecksums[filename])\n return path.join(fpmPath, exec)\n}\n\nexport async function getAppImageTools(targetArch: Arch) {\n const override = process.env.APPIMAGE_TOOLS_PATH?.trim()\n const artifactPath =\n override ||\n (await downloadArtifact({\n releaseName: \"appimage@1.0.2\",\n filenameWithExt: \"appimage-tools-runtime-20251108.tar.gz\",\n checksums: {\n \"appimage-tools-runtime-20251108.tar.gz\": \"a784a8c26331ec2e945c23d6bdb14af5c9df27f5939825d84b8709c61dc81eb0\",\n },\n githubOrgRepo: \"electron-userland/electron-builder-binaries\",\n }))\n\n const runtimeArch = targetArch === Arch.armv7l ? \"arm32\" : targetArch === Arch.arm64 ? \"arm64\" : targetArch === Arch.ia32 ? \"ia32\" : \"x64\"\n return {\n mksquashfs: path.join(artifactPath, \"mksquashfs\"),\n desktopFileValidate: path.join(artifactPath, \"desktop-file-validate\"),\n runtime: path.join(artifactPath, \"runtimes\", `runtime-${runtimeArch}`),\n runtimeLibraries: path.join(artifactPath, \"lib\", runtimeArch),\n }\n}\n"]}
|