1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.computeNodeModuleFileSets = exports.computeFileSets = exports.transformFiles = exports.copyAppFiles = exports.getDestinationPath = exports.ELECTRON_COMPILE_SHIM_FILENAME = void 0;
|
4 | const bluebird_lst_1 = require("bluebird-lst");
|
5 | const builder_util_1 = require("builder-util");
|
6 | const fs_1 = require("builder-util/out/fs");
|
7 | const promises_1 = require("fs/promises");
|
8 | const path = require("path");
|
9 | const unpackDetector_1 = require("../asar/unpackDetector");
|
10 | const core_1 = require("../core");
|
11 | const fileMatcher_1 = require("../fileMatcher");
|
12 | const fileTransformer_1 = require("../fileTransformer");
|
13 | const AppFileWalker_1 = require("./AppFileWalker");
|
14 | const NodeModuleCopyHelper_1 = require("./NodeModuleCopyHelper");
|
15 | const BOWER_COMPONENTS_PATTERN = `${path.sep}bower_components${path.sep}`;
|
16 |
|
17 | exports.ELECTRON_COMPILE_SHIM_FILENAME = "__shim.js";
|
18 | function getDestinationPath(file, fileSet) {
|
19 | if (file === fileSet.src) {
|
20 | return fileSet.destination;
|
21 | }
|
22 | else {
|
23 | const src = fileSet.src;
|
24 | const dest = fileSet.destination;
|
25 | if (file.length > src.length && file.startsWith(src) && file[src.length] === path.sep) {
|
26 | return dest + file.substring(src.length);
|
27 | }
|
28 | else {
|
29 |
|
30 |
|
31 |
|
32 | let index = file.indexOf(fileTransformer_1.NODE_MODULES_PATTERN);
|
33 | if (index < 0 && file.endsWith(`${path.sep}node_modules`)) {
|
34 | index = file.length - 13;
|
35 | }
|
36 | if (index < 0) {
|
37 | throw new Error(`File "${file}" not under the source directory "${fileSet.src}"`);
|
38 | }
|
39 | return dest + file.substring(index);
|
40 | }
|
41 | }
|
42 | }
|
43 | exports.getDestinationPath = getDestinationPath;
|
44 | async function copyAppFiles(fileSet, packager, transformer) {
|
45 | const metadata = fileSet.metadata;
|
46 |
|
47 | const taskManager = new builder_util_1.AsyncTaskManager(packager.cancellationToken);
|
48 | const createdParentDirs = new Set();
|
49 | const fileCopier = new fs_1.FileCopier(file => {
|
50 |
|
51 | return !(unpackDetector_1.isLibOrExe(file) || file.endsWith(".node"));
|
52 | }, transformer);
|
53 | const links = [];
|
54 | for (let i = 0, n = fileSet.files.length; i < n; i++) {
|
55 | const sourceFile = fileSet.files[i];
|
56 | const stat = metadata.get(sourceFile);
|
57 | if (stat == null) {
|
58 |
|
59 | continue;
|
60 | }
|
61 | const destinationFile = getDestinationPath(sourceFile, fileSet);
|
62 | if (stat.isSymbolicLink()) {
|
63 | links.push({ file: destinationFile, link: await promises_1.readlink(sourceFile) });
|
64 | continue;
|
65 | }
|
66 | const fileParent = path.dirname(destinationFile);
|
67 | if (!createdParentDirs.has(fileParent)) {
|
68 | createdParentDirs.add(fileParent);
|
69 | await promises_1.mkdir(fileParent, { recursive: true });
|
70 | }
|
71 | taskManager.addTask(fileCopier.copy(sourceFile, destinationFile, stat));
|
72 | if (taskManager.tasks.length > fs_1.MAX_FILE_REQUESTS) {
|
73 | await taskManager.awaitTasks();
|
74 | }
|
75 | }
|
76 | if (taskManager.tasks.length > 0) {
|
77 | await taskManager.awaitTasks();
|
78 | }
|
79 | if (links.length > 0) {
|
80 | await bluebird_lst_1.default.map(links, it => promises_1.symlink(it.link, it.file), fs_1.CONCURRENCY);
|
81 | }
|
82 | }
|
83 | exports.copyAppFiles = copyAppFiles;
|
84 |
|
85 | async function transformFiles(transformer, fileSet) {
|
86 | if (transformer == null) {
|
87 | return;
|
88 | }
|
89 | let transformedFiles = fileSet.transformedFiles;
|
90 | if (fileSet.transformedFiles == null) {
|
91 | transformedFiles = new Map();
|
92 | fileSet.transformedFiles = transformedFiles;
|
93 | }
|
94 | const metadata = fileSet.metadata;
|
95 | await bluebird_lst_1.default.filter(fileSet.files, (it, index) => {
|
96 | const fileStat = metadata.get(it);
|
97 | if (fileStat == null || !fileStat.isFile()) {
|
98 | return false;
|
99 | }
|
100 | const transformedValue = transformer(it);
|
101 | if (transformedValue == null) {
|
102 | return false;
|
103 | }
|
104 | if (typeof transformedValue === "object" && "then" in transformedValue) {
|
105 | return transformedValue.then(it => {
|
106 | if (it != null) {
|
107 | transformedFiles.set(index, it);
|
108 | }
|
109 | return false;
|
110 | });
|
111 | }
|
112 | transformedFiles.set(index, transformedValue);
|
113 | return false;
|
114 | }, fs_1.CONCURRENCY);
|
115 | }
|
116 | exports.transformFiles = transformFiles;
|
117 | async function computeFileSets(matchers, transformer, platformPackager, isElectronCompile) {
|
118 | const fileSets = [];
|
119 | const packager = platformPackager.info;
|
120 | for (const matcher of matchers) {
|
121 | const fileWalker = new AppFileWalker_1.AppFileWalker(matcher, packager);
|
122 | const fromStat = await fs_1.statOrNull(matcher.from);
|
123 | if (fromStat == null) {
|
124 | builder_util_1.log.debug({ directory: matcher.from, reason: "doesn't exist" }, `skipped copying`);
|
125 | continue;
|
126 | }
|
127 | const files = await fs_1.walk(matcher.from, fileWalker.filter, fileWalker);
|
128 | const metadata = fileWalker.metadata;
|
129 | fileSets.push(validateFileSet({ src: matcher.from, files, metadata, destination: matcher.to }));
|
130 | }
|
131 | if (isElectronCompile) {
|
132 |
|
133 | fileSets.unshift(await compileUsingElectronCompile(fileSets[0], packager));
|
134 | }
|
135 | return fileSets;
|
136 | }
|
137 | exports.computeFileSets = computeFileSets;
|
138 | function getNodeModuleExcludedExts(platformPackager) {
|
139 |
|
140 | const result = [".o", ".obj"].concat(fileMatcher_1.excludedExts.split(",").map(it => `.${it}`));
|
141 | if (platformPackager.config.includePdb !== true) {
|
142 | result.push(".pdb");
|
143 | }
|
144 | if (platformPackager.platform !== core_1.Platform.WINDOWS) {
|
145 |
|
146 | result.push(".dll");
|
147 | result.push(".exe");
|
148 | }
|
149 | return result;
|
150 | }
|
151 | function validateFileSet(fileSet) {
|
152 | if (fileSet.src == null || fileSet.src.length === 0) {
|
153 | throw new Error("fileset src is empty");
|
154 | }
|
155 | return fileSet;
|
156 | }
|
157 |
|
158 | async function computeNodeModuleFileSets(platformPackager, mainMatcher) {
|
159 | const deps = await platformPackager.info.getNodeDependencyInfo(platformPackager.platform).value;
|
160 | const nodeModuleExcludedExts = getNodeModuleExcludedExts(platformPackager);
|
161 |
|
162 | const result = new Array();
|
163 | let index = 0;
|
164 | for (const info of deps) {
|
165 | const source = info.dir;
|
166 | const destination = getDestinationPath(source, { src: mainMatcher.from, destination: mainMatcher.to, files: [], metadata: null });
|
167 |
|
168 |
|
169 | const matcher = new fileMatcher_1.FileMatcher(path.dirname(source), destination, mainMatcher.macroExpander, mainMatcher.patterns);
|
170 | const copier = new NodeModuleCopyHelper_1.NodeModuleCopyHelper(matcher, platformPackager.info);
|
171 | const files = await copier.collectNodeModules(source, info.deps.map(it => it.name), nodeModuleExcludedExts);
|
172 | result[index++] = validateFileSet({ src: source, destination, files, metadata: copier.metadata });
|
173 | }
|
174 | return result;
|
175 | }
|
176 | exports.computeNodeModuleFileSets = computeNodeModuleFileSets;
|
177 | async function compileUsingElectronCompile(mainFileSet, packager) {
|
178 | builder_util_1.log.info("compiling using electron-compile");
|
179 | const electronCompileCache = await packager.tempDirManager.getTempDir({ prefix: "electron-compile-cache" });
|
180 | const cacheDir = path.join(electronCompileCache, ".cache");
|
181 |
|
182 | await promises_1.mkdir(cacheDir, { recursive: true });
|
183 | const compilerHost = await fileTransformer_1.createElectronCompilerHost(mainFileSet.src, cacheDir);
|
184 | const nextSlashIndex = mainFileSet.src.length + 1;
|
185 |
|
186 | await bluebird_lst_1.default.map(mainFileSet.files, file => {
|
187 | if (file.includes(fileTransformer_1.NODE_MODULES_PATTERN) ||
|
188 | file.includes(BOWER_COMPONENTS_PATTERN) ||
|
189 | !file.includes(path.sep, nextSlashIndex) ||
|
190 | !mainFileSet.metadata.get(file).isFile()) {
|
191 | return null;
|
192 | }
|
193 | return compilerHost.compile(file).then(() => null);
|
194 | }, fs_1.CONCURRENCY);
|
195 | await compilerHost.saveConfiguration();
|
196 | const metadata = new Map();
|
197 | const cacheFiles = await fs_1.walk(cacheDir, file => !file.startsWith("."), {
|
198 | consume: (file, fileStat) => {
|
199 | if (fileStat.isFile()) {
|
200 | metadata.set(file, fileStat);
|
201 | }
|
202 | return null;
|
203 | },
|
204 | });
|
205 |
|
206 | const shimPath = `${mainFileSet.src}${path.sep}${exports.ELECTRON_COMPILE_SHIM_FILENAME}`;
|
207 | mainFileSet.files.push(shimPath);
|
208 | mainFileSet.metadata.set(shimPath, { isFile: () => true, isDirectory: () => false, isSymbolicLink: () => false });
|
209 | if (mainFileSet.transformedFiles == null) {
|
210 | mainFileSet.transformedFiles = new Map();
|
211 | }
|
212 | mainFileSet.transformedFiles.set(mainFileSet.files.length - 1, `
|
213 | 'use strict';
|
214 | require('electron-compile').init(__dirname, require('path').resolve(__dirname, '${packager.metadata.main || "index"}'), true);
|
215 | `);
|
216 | return { src: electronCompileCache, files: cacheFiles, metadata, destination: mainFileSet.destination };
|
217 | }
|
218 |
|
\ | No newline at end of file |