1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.unlinkIfExists = unlinkIfExists;
|
7 | exports.statOrNull = statOrNull;
|
8 | exports.exists = exists;
|
9 | exports.walk = walk;
|
10 | exports.copyFile = copyFile;
|
11 | exports.copyOrLinkFile = copyOrLinkFile;
|
12 | exports.copyDir = copyDir;
|
13 | exports.USE_HARD_LINKS = exports.DO_NOT_USE_HARD_LINKS = exports.FileCopier = exports.CopyFileTransformer = exports.CONCURRENCY = exports.MAX_FILE_REQUESTS = void 0;
|
14 |
|
15 | function _bluebirdLst() {
|
16 | const data = _interopRequireDefault(require("bluebird-lst"));
|
17 |
|
18 | _bluebirdLst = function () {
|
19 | return data;
|
20 | };
|
21 |
|
22 | return data;
|
23 | }
|
24 |
|
25 | function _fsExtra() {
|
26 | const data = require("fs-extra");
|
27 |
|
28 | _fsExtra = function () {
|
29 | return data;
|
30 | };
|
31 |
|
32 | return data;
|
33 | }
|
34 |
|
35 | var path = _interopRequireWildcard(require("path"));
|
36 |
|
37 | function _statMode() {
|
38 | const data = require("stat-mode");
|
39 |
|
40 | _statMode = function () {
|
41 | return data;
|
42 | };
|
43 |
|
44 | return data;
|
45 | }
|
46 |
|
47 | function _log() {
|
48 | const data = require("./log");
|
49 |
|
50 | _log = function () {
|
51 | return data;
|
52 | };
|
53 |
|
54 | return data;
|
55 | }
|
56 |
|
57 | function _promise() {
|
58 | const data = require("./promise");
|
59 |
|
60 | _promise = function () {
|
61 | return data;
|
62 | };
|
63 |
|
64 | return data;
|
65 | }
|
66 |
|
67 | function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
68 |
|
69 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
70 |
|
71 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
72 |
|
73 | const MAX_FILE_REQUESTS = 8;
|
74 | exports.MAX_FILE_REQUESTS = MAX_FILE_REQUESTS;
|
75 | const CONCURRENCY = {
|
76 | concurrency: MAX_FILE_REQUESTS
|
77 | };
|
78 | exports.CONCURRENCY = CONCURRENCY;
|
79 |
|
80 | class CopyFileTransformer {
|
81 | constructor(afterCopyTransformer) {
|
82 | this.afterCopyTransformer = afterCopyTransformer;
|
83 | }
|
84 |
|
85 | }
|
86 |
|
87 | exports.CopyFileTransformer = CopyFileTransformer;
|
88 |
|
89 | function unlinkIfExists(file) {
|
90 | return (0, _fsExtra().unlink)(file).catch(() => {});
|
91 | }
|
92 |
|
93 | async function statOrNull(file) {
|
94 | return (0, _promise().orNullIfFileNotExist)((0, _fsExtra().stat)(file));
|
95 | }
|
96 |
|
97 | async function exists(file) {
|
98 | try {
|
99 | await (0, _fsExtra().access)(file);
|
100 | return true;
|
101 | } catch (e) {
|
102 | return false;
|
103 | }
|
104 | }
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 | async function walk(initialDirPath, filter, consumer) {
|
111 | let result = [];
|
112 | const queue = [initialDirPath];
|
113 | let addDirToResult = false;
|
114 | const isIncludeDir = consumer == null ? false : consumer.isIncludeDir === true;
|
115 |
|
116 | while (queue.length > 0) {
|
117 | const dirPath = queue.pop();
|
118 |
|
119 | if (isIncludeDir) {
|
120 | if (addDirToResult) {
|
121 | result.push(dirPath);
|
122 | } else {
|
123 | addDirToResult = true;
|
124 | }
|
125 | }
|
126 |
|
127 | const childNames = await (0, _promise().orIfFileNotExist)((0, _fsExtra().readdir)(dirPath), []);
|
128 | childNames.sort();
|
129 | let nodeModuleContent = null;
|
130 | const dirs = [];
|
131 |
|
132 | const sortedFilePaths = await _bluebirdLst().default.map(childNames, name => {
|
133 | if (name === ".DS_Store" || name === ".gitkeep") {
|
134 | return null;
|
135 | }
|
136 |
|
137 | const filePath = dirPath + path.sep + name;
|
138 | return (0, _fsExtra().lstat)(filePath).then(stat => {
|
139 | if (filter != null && !filter(filePath, stat)) {
|
140 | return null;
|
141 | }
|
142 |
|
143 | const consumerResult = consumer == null ? null : consumer.consume(filePath, stat, dirPath, childNames);
|
144 |
|
145 | if (consumerResult === false) {
|
146 | return null;
|
147 | } else if (consumerResult == null || !("then" in consumerResult)) {
|
148 | if (stat.isDirectory()) {
|
149 | dirs.push(name);
|
150 | return null;
|
151 | } else {
|
152 | return filePath;
|
153 | }
|
154 | } else {
|
155 | return consumerResult.then(it => {
|
156 | if (it != null && Array.isArray(it)) {
|
157 | nodeModuleContent = it;
|
158 | return null;
|
159 | }
|
160 |
|
161 |
|
162 | if ((it != null && "isDirectory" in it ? it : stat).isDirectory()) {
|
163 | dirs.push(name);
|
164 | return null;
|
165 | } else {
|
166 | return filePath;
|
167 | }
|
168 | });
|
169 | }
|
170 | });
|
171 | }, CONCURRENCY);
|
172 |
|
173 | for (const child of sortedFilePaths) {
|
174 | if (child != null) {
|
175 | result.push(child);
|
176 | }
|
177 | }
|
178 |
|
179 | dirs.sort();
|
180 |
|
181 | for (const child of dirs) {
|
182 | queue.push(dirPath + path.sep + child);
|
183 | }
|
184 |
|
185 | if (nodeModuleContent != null) {
|
186 | result = result.concat(nodeModuleContent);
|
187 | }
|
188 | }
|
189 |
|
190 | return result;
|
191 | }
|
192 |
|
193 | const _isUseHardLink = process.platform !== "win32" && process.env.USE_HARD_LINKS !== "false" && (require("is-ci") || process.env.USE_HARD_LINKS === "true");
|
194 |
|
195 | function copyFile(src, dest, isEnsureDir = true) {
|
196 | return (isEnsureDir ? (0, _fsExtra().ensureDir)(path.dirname(dest)) : Promise.resolve()).then(() => copyOrLinkFile(src, dest, null, false));
|
197 | }
|
198 |
|
199 |
|
200 |
|
201 |
|
202 |
|
203 |
|
204 |
|
205 |
|
206 | function copyOrLinkFile(src, dest, stats, isUseHardLink, exDevErrorHandler) {
|
207 | if (isUseHardLink === undefined) {
|
208 | isUseHardLink = _isUseHardLink;
|
209 | }
|
210 |
|
211 | if (stats != null) {
|
212 | const originalModeNumber = stats.mode;
|
213 | const mode = new (_statMode().Mode)(stats);
|
214 |
|
215 | if (mode.owner.execute) {
|
216 | mode.group.execute = true;
|
217 | mode.others.execute = true;
|
218 | }
|
219 |
|
220 | mode.group.read = true;
|
221 | mode.others.read = true;
|
222 | mode.setuid = false;
|
223 | mode.setgid = false;
|
224 |
|
225 | if (originalModeNumber !== stats.mode) {
|
226 | if (_log().log.isDebugEnabled) {
|
227 | const oldMode = new (_statMode().Mode)({
|
228 | mode: originalModeNumber
|
229 | });
|
230 |
|
231 | _log().log.debug({
|
232 | file: dest,
|
233 | oldMode,
|
234 | mode
|
235 | }, "permissions fixed from");
|
236 | }
|
237 |
|
238 |
|
239 |
|
240 |
|
241 | if (isUseHardLink) {
|
242 | isUseHardLink = false;
|
243 |
|
244 | _log().log.debug({
|
245 | dest
|
246 | }, "copied, but not linked, because file permissions need to be fixed");
|
247 | }
|
248 | }
|
249 | }
|
250 |
|
251 | if (isUseHardLink) {
|
252 | return (0, _fsExtra().link)(src, dest).catch(e => {
|
253 | if (e.code === "EXDEV") {
|
254 | const isLog = exDevErrorHandler == null ? true : exDevErrorHandler();
|
255 |
|
256 | if (isLog && _log().log.isDebugEnabled) {
|
257 | _log().log.debug({
|
258 | error: e.message
|
259 | }, "cannot copy using hard link");
|
260 | }
|
261 |
|
262 | return doCopyFile(src, dest, stats);
|
263 | } else {
|
264 | throw e;
|
265 | }
|
266 | });
|
267 | }
|
268 |
|
269 | return doCopyFile(src, dest, stats);
|
270 | }
|
271 |
|
272 | function doCopyFile(src, dest, stats) {
|
273 | const promise = (0, _fsExtra().copyFile)(src, dest);
|
274 |
|
275 | if (stats == null) {
|
276 | return promise;
|
277 | }
|
278 |
|
279 | return promise.then(() => (0, _fsExtra().chmod)(dest, stats.mode));
|
280 | }
|
281 |
|
282 | class FileCopier {
|
283 | constructor(isUseHardLinkFunction, transformer) {
|
284 | this.isUseHardLinkFunction = isUseHardLinkFunction;
|
285 | this.transformer = transformer;
|
286 |
|
287 | if (isUseHardLinkFunction === USE_HARD_LINKS) {
|
288 | this.isUseHardLink = true;
|
289 | } else {
|
290 | this.isUseHardLink = _isUseHardLink && isUseHardLinkFunction !== DO_NOT_USE_HARD_LINKS;
|
291 | }
|
292 | }
|
293 |
|
294 | async copy(src, dest, stat) {
|
295 | let afterCopyTransformer = null;
|
296 |
|
297 | if (this.transformer != null && stat != null && stat.isFile()) {
|
298 | let data = this.transformer(src);
|
299 |
|
300 | if (data != null) {
|
301 | if (typeof data === "object" && "then" in data) {
|
302 | data = await data;
|
303 | }
|
304 |
|
305 | if (data != null) {
|
306 | if (data instanceof CopyFileTransformer) {
|
307 | afterCopyTransformer = data.afterCopyTransformer;
|
308 | } else {
|
309 | await (0, _fsExtra().writeFile)(dest, data);
|
310 | return;
|
311 | }
|
312 | }
|
313 | }
|
314 | }
|
315 |
|
316 | const isUseHardLink = afterCopyTransformer == null && (!this.isUseHardLink || this.isUseHardLinkFunction == null ? this.isUseHardLink : this.isUseHardLinkFunction(dest));
|
317 | await copyOrLinkFile(src, dest, stat, isUseHardLink, isUseHardLink ? () => {
|
318 |
|
319 | if (this.isUseHardLink) {
|
320 | this.isUseHardLink = false;
|
321 | return true;
|
322 | } else {
|
323 | return false;
|
324 | }
|
325 | } : null);
|
326 |
|
327 | if (afterCopyTransformer != null) {
|
328 | await afterCopyTransformer(dest);
|
329 | }
|
330 | }
|
331 |
|
332 | }
|
333 |
|
334 |
|
335 |
|
336 |
|
337 |
|
338 |
|
339 | exports.FileCopier = FileCopier;
|
340 |
|
341 | function copyDir(src, destination, options = {}) {
|
342 | const fileCopier = new FileCopier(options.isUseHardLink, options.transformer);
|
343 |
|
344 | if (_log().log.isDebugEnabled) {
|
345 | _log().log.debug({
|
346 | src,
|
347 | destination
|
348 | }, `copying${fileCopier.isUseHardLink ? " using hard links" : ""}`);
|
349 | }
|
350 |
|
351 | const createdSourceDirs = new Set();
|
352 | const links = [];
|
353 | return walk(src, options.filter, {
|
354 | consume: async (file, stat, parent) => {
|
355 | if (!stat.isFile() && !stat.isSymbolicLink()) {
|
356 | return;
|
357 | }
|
358 |
|
359 | if (!createdSourceDirs.has(parent)) {
|
360 | await (0, _fsExtra().ensureDir)(parent.replace(src, destination));
|
361 | createdSourceDirs.add(parent);
|
362 | }
|
363 |
|
364 | const destFile = file.replace(src, destination);
|
365 |
|
366 | if (stat.isFile()) {
|
367 | await fileCopier.copy(file, destFile, stat);
|
368 | } else {
|
369 | links.push({
|
370 | file: destFile,
|
371 | link: await (0, _fsExtra().readlink)(file)
|
372 | });
|
373 | }
|
374 | }
|
375 | }).then(() => _bluebirdLst().default.map(links, it => (0, _fsExtra().symlink)(it.link, it.file), CONCURRENCY));
|
376 | }
|
377 |
|
378 |
|
379 | const DO_NOT_USE_HARD_LINKS = file => false;
|
380 |
|
381 |
|
382 | exports.DO_NOT_USE_HARD_LINKS = DO_NOT_USE_HARD_LINKS;
|
383 |
|
384 | const USE_HARD_LINKS = file => true; exports.USE_HARD_LINKS = USE_HARD_LINKS;
|
385 |
|
386 |
|
\ | No newline at end of file |