UNPKG

8.01 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.archive = exports.computeZipCompressArgs = exports.compute7zCompressArgs = exports.tar = void 0;
4const builder_util_1 = require("builder-util");
5const fs_1 = require("builder-util/out/fs");
6const fs_extra_1 = require("fs-extra");
7const path = require("path");
8const tar_1 = require("tar");
9const tools_1 = require("./tools");
10const builder_util_2 = require("builder-util");
11/** @internal */
12async function tar(compression, format, outFile, dirToArchive, isMacApp, tempDirManager) {
13 const tarFile = await tempDirManager.getTempFile({ suffix: ".tar" });
14 const tarArgs = {
15 file: tarFile,
16 portable: true,
17 cwd: dirToArchive,
18 prefix: path.basename(outFile, `.${format}`),
19 };
20 let tarDirectory = ".";
21 if (isMacApp) {
22 delete tarArgs.prefix;
23 tarArgs.cwd = path.dirname(dirToArchive);
24 tarDirectory = path.basename(dirToArchive);
25 }
26 await Promise.all([
27 (0, tar_1.create)(tarArgs, [tarDirectory]),
28 // remove file before - 7z doesn't overwrite file, but update
29 (0, fs_1.unlinkIfExists)(outFile),
30 ]);
31 if (format === "tar.lz") {
32 // noinspection SpellCheckingInspection
33 let lzipPath = "lzip";
34 if (process.platform === "darwin") {
35 lzipPath = path.join(await (0, tools_1.getLinuxToolsPath)(), "bin", lzipPath);
36 }
37 await (0, builder_util_1.exec)(lzipPath, [compression === "store" ? "-1" : "-9", "--keep" /* keep (don't delete) input files */, tarFile]);
38 // bloody lzip creates file in the same dir where input file with postfix `.lz`, option --output doesn't work
39 await (0, fs_extra_1.move)(`${tarFile}.lz`, outFile);
40 return;
41 }
42 const args = compute7zCompressArgs(format === "tar.xz" ? "xz" : format === "tar.bz2" ? "bzip2" : "gzip", {
43 isRegularFile: true,
44 method: "DEFAULT",
45 compression,
46 });
47 args.push(outFile, tarFile);
48 await (0, builder_util_1.exec)(await (0, builder_util_2.getPath7za)(), args, {
49 cwd: path.dirname(dirToArchive),
50 }, builder_util_1.debug7z.enabled);
51}
52exports.tar = tar;
53function compute7zCompressArgs(format, options = {}) {
54 let storeOnly = options.compression === "store";
55 const args = debug7zArgs("a");
56 let isLevelSet = false;
57 if (process.env.ELECTRON_BUILDER_COMPRESSION_LEVEL != null) {
58 storeOnly = false;
59 args.push(`-mx=${process.env.ELECTRON_BUILDER_COMPRESSION_LEVEL}`);
60 isLevelSet = true;
61 }
62 const isZip = format === "zip";
63 if (!storeOnly) {
64 if (isZip && options.compression === "maximum") {
65 // http://superuser.com/a/742034
66 args.push("-mfb=258", "-mpass=15");
67 }
68 if (!isLevelSet) {
69 // https://github.com/electron-userland/electron-builder/pull/3032
70 args.push("-mx=" + (!isZip || options.compression === "maximum" ? "9" : "7"));
71 }
72 }
73 if (options.dictSize != null) {
74 args.push(`-md=${options.dictSize}m`);
75 }
76 // https://sevenzip.osdn.jp/chm/cmdline/switches/method.htm#7Z
77 // https://stackoverflow.com/questions/27136783/7zip-produces-different-output-from-identical-input
78 // tc and ta are off by default, but to be sure, we explicitly set it to off
79 // disable "Stores NTFS timestamps for files: Modification time, Creation time, Last access time." to produce the same archive for the same data
80 if (!options.isRegularFile) {
81 args.push("-mtc=off");
82 }
83 if (format === "7z" || format.endsWith(".7z")) {
84 if (options.solid === false) {
85 args.push("-ms=off");
86 }
87 if (options.isArchiveHeaderCompressed === false) {
88 args.push("-mhc=off");
89 }
90 // https://www.7-zip.org/7z.html
91 // Filters: BCJ, BCJ2, ARM, ARMT, IA64, PPC, SPARC, ...
92 if (process.env.ELECTRON_BUILDER_7Z_FILTER) {
93 args.push(`-mf=${process.env.ELECTRON_BUILDER_7Z_FILTER}`);
94 }
95 // args valid only for 7z
96 // -mtm=off disable "Stores last Modified timestamps for files."
97 args.push("-mtm=off", "-mta=off");
98 }
99 if (options.method != null) {
100 if (options.method !== "DEFAULT") {
101 args.push(`-mm=${options.method}`);
102 }
103 }
104 else if (isZip || storeOnly) {
105 args.push(`-mm=${storeOnly ? "Copy" : "Deflate"}`);
106 }
107 if (isZip) {
108 // -mcu switch: 7-Zip uses UTF-8, if there are non-ASCII symbols.
109 // because default mode: 7-Zip uses UTF-8, if the local code page doesn't contain required symbols.
110 // but archive should be the same regardless where produced
111 args.push("-mcu");
112 }
113 return args;
114}
115exports.compute7zCompressArgs = compute7zCompressArgs;
116function computeZipCompressArgs(options = {}) {
117 let storeOnly = options.compression === "store";
118 // do not deref symlinks
119 const args = ["-q", "-r", "-y"];
120 if (builder_util_1.debug7z.enabled) {
121 args.push("-v");
122 }
123 if (process.env.ELECTRON_BUILDER_COMPRESSION_LEVEL != null) {
124 storeOnly = false;
125 args.push(`-${process.env.ELECTRON_BUILDER_COMPRESSION_LEVEL}`);
126 }
127 else if (!storeOnly) {
128 // https://github.com/electron-userland/electron-builder/pull/3032
129 args.push("-" + (options.compression === "maximum" ? "9" : "7"));
130 }
131 if (options.dictSize != null) {
132 builder_util_1.log.warn({ distSize: options.dictSize }, `ignoring unsupported option`);
133 }
134 // do not save extra file attributes (Extended Attributes on OS/2, uid/gid and file times on Unix)
135 if (!options.isRegularFile) {
136 args.push("-X");
137 }
138 if (options.method != null) {
139 if (options.method !== "DEFAULT") {
140 builder_util_1.log.warn({ method: options.method }, `ignoring unsupported option`);
141 }
142 }
143 else {
144 args.push("-Z", storeOnly ? "store" : "deflate");
145 }
146 return args;
147}
148exports.computeZipCompressArgs = computeZipCompressArgs;
149// 7z is very fast, so, use ultra compression
150/** @internal */
151async function archive(format, outFile, dirToArchive, options = {}) {
152 const outFileStat = await (0, fs_1.statOrNull)(outFile);
153 const dirStat = await (0, fs_1.statOrNull)(dirToArchive);
154 if (outFileStat && dirStat && outFileStat.mtime > dirStat.mtime) {
155 builder_util_1.log.info({ reason: "Archive file is up to date", outFile }, `skipped archiving`);
156 return outFile;
157 }
158 let use7z = true;
159 if (process.platform === "darwin" && format === "zip" && dirToArchive.normalize("NFC") !== dirToArchive) {
160 builder_util_1.log.warn({ reason: "7z doesn't support NFD-normalized filenames" }, `using zip`);
161 use7z = false;
162 }
163 const args = use7z ? compute7zCompressArgs(format, options) : computeZipCompressArgs(options);
164 // remove file before - 7z and zip doesn't overwrite file, but update
165 await (0, fs_1.unlinkIfExists)(outFile);
166 args.push(outFile, options.withoutDir ? "." : path.basename(dirToArchive));
167 if (options.excluded != null) {
168 for (const mask of options.excluded) {
169 args.push(use7z ? `-xr!${mask}` : `-x${mask}`);
170 }
171 }
172 try {
173 const binary = use7z ? await (0, builder_util_2.getPath7za)() : "zip";
174 await (0, builder_util_1.exec)(binary, args, {
175 cwd: options.withoutDir ? dirToArchive : path.dirname(dirToArchive),
176 }, builder_util_1.debug7z.enabled);
177 }
178 catch (e) {
179 if (e.code === "ENOENT" && !(await (0, fs_1.exists)(dirToArchive))) {
180 throw new Error(`Cannot create archive: "${dirToArchive}" doesn't exist`);
181 }
182 else {
183 throw e;
184 }
185 }
186 return outFile;
187}
188exports.archive = archive;
189function debug7zArgs(command) {
190 const args = [command, "-bd"];
191 if (builder_util_1.debug7z.enabled) {
192 args.push("-bb");
193 }
194 return args;
195}
196//# sourceMappingURL=archive.js.map
\No newline at end of file