@qooxdoo/framework 7.3.2 → 7.3.3
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/Manifest.json +1 -1
- package/bin/tools/utils.js +561 -0
- package/lib/compiler/compile-info.json +59 -59
- package/lib/compiler/index.js +237 -237
- package/package.json +2 -1
package/Manifest.json
CHANGED
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const async = require("async");
|
|
4
|
+
const child_process = require("child_process");
|
|
5
|
+
//var fsPromises = require("fs").promises;
|
|
6
|
+
// node 8 compatibility
|
|
7
|
+
const {promisify} = require('util');
|
|
8
|
+
const stat = promisify(fs.stat);
|
|
9
|
+
|
|
10
|
+
const fsPromises = {
|
|
11
|
+
readFile: promisify(fs.readFile),
|
|
12
|
+
writeFile: promisify(fs.writeFile),
|
|
13
|
+
unlink: promisify(fs.unlink),
|
|
14
|
+
mkdir: promisify(fs.mkdir),
|
|
15
|
+
readdir: promisify(fs.readdir)
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Return the path to the compiler executable, unless the "QX_JS" OS environment
|
|
20
|
+
* variable is set, in which case the content of this variable is returned.
|
|
21
|
+
*
|
|
22
|
+
* @param {String} buildVersion? The build version, defaults to "build"
|
|
23
|
+
* @return {String}
|
|
24
|
+
*/
|
|
25
|
+
function getCompiler(buildVersion="build") {
|
|
26
|
+
let qxJs = process.env.QX_JS;
|
|
27
|
+
if (!qxJs) {
|
|
28
|
+
qxJs = path.join(__dirname, "..", buildVersion, "qx");
|
|
29
|
+
}
|
|
30
|
+
return qxJs;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function runCompiler(dir, ...cmd) {
|
|
34
|
+
let result = await runCommand(dir, getCompiler(), "compile", "--machine-readable", ...cmd);
|
|
35
|
+
result.messages = [];
|
|
36
|
+
result.output.split("\n").forEach(line => {
|
|
37
|
+
let m = line.match(/^\#\#([^:]+):\[(.*)\]$/);
|
|
38
|
+
if (m) {
|
|
39
|
+
let args = m[2].match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g);
|
|
40
|
+
if (args) {
|
|
41
|
+
args = args.map(arg => {
|
|
42
|
+
if (arg.length && arg[0] == "\"" && arg[arg.length - 1] == "\"")
|
|
43
|
+
return arg.substring(1, arg.length - 1);
|
|
44
|
+
return arg;
|
|
45
|
+
});
|
|
46
|
+
} else {
|
|
47
|
+
args = [];
|
|
48
|
+
}
|
|
49
|
+
result.messages.push({
|
|
50
|
+
id: m[1],
|
|
51
|
+
args: args
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function runCommand(dir, ...args) {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
let cmd = args.shift();
|
|
61
|
+
let proc = child_process.spawn(cmd, args, {
|
|
62
|
+
cwd: dir,
|
|
63
|
+
shell: true
|
|
64
|
+
});
|
|
65
|
+
let result = {
|
|
66
|
+
exitCode: null,
|
|
67
|
+
output: "",
|
|
68
|
+
error: "",
|
|
69
|
+
messages: null
|
|
70
|
+
};
|
|
71
|
+
proc.stdout.on('data', (data) => {
|
|
72
|
+
data = data.toString().trim();
|
|
73
|
+
console.log(data);
|
|
74
|
+
result.output += data;
|
|
75
|
+
});
|
|
76
|
+
proc.stderr.on('data', (data) => {
|
|
77
|
+
data = data.toString().trim();
|
|
78
|
+
console.error(data);
|
|
79
|
+
result.error += data;
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
proc.on('close', code => {
|
|
83
|
+
result.exitCode = code;
|
|
84
|
+
resolve(result);
|
|
85
|
+
});
|
|
86
|
+
proc.on('error', err => {
|
|
87
|
+
reject(err);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function deleteRecursive(name) {
|
|
93
|
+
return new Promise((resolve, reject) => {
|
|
94
|
+
fs.access(name, err => {
|
|
95
|
+
if (err) {
|
|
96
|
+
return resolve();
|
|
97
|
+
}
|
|
98
|
+
deleteRecursiveImpl(name, err => {
|
|
99
|
+
if (err) {
|
|
100
|
+
reject(err);
|
|
101
|
+
} else {
|
|
102
|
+
resolve(err);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
return null;
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
function deleteRecursiveImpl(name, cb) {
|
|
109
|
+
fs.stat(name, function (err, stat) {
|
|
110
|
+
if (err) {
|
|
111
|
+
return cb && cb(err);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (stat.isDirectory()) {
|
|
115
|
+
fs.readdir(name, function (err, files) {
|
|
116
|
+
if (err) {
|
|
117
|
+
return cb && cb(err);
|
|
118
|
+
}
|
|
119
|
+
async.each(files,
|
|
120
|
+
function (file, cb) {
|
|
121
|
+
deleteRecursiveImpl(name + "/" + file, cb);
|
|
122
|
+
},
|
|
123
|
+
function (err) {
|
|
124
|
+
if (err) {
|
|
125
|
+
return cb && cb(err);
|
|
126
|
+
}
|
|
127
|
+
fs.rmdir(name, cb);
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
return null;
|
|
132
|
+
});
|
|
133
|
+
} else {
|
|
134
|
+
fs.unlink(name, cb);
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async function safeDelete(filename) {
|
|
143
|
+
try {
|
|
144
|
+
await fsPromises.unlink(filename);
|
|
145
|
+
} catch(ex) {
|
|
146
|
+
if (ex.code == "ENOENT")
|
|
147
|
+
return;
|
|
148
|
+
throw ex;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function defaultOptions() {
|
|
153
|
+
return {
|
|
154
|
+
clean: true,
|
|
155
|
+
version: null,
|
|
156
|
+
target: "build",
|
|
157
|
+
incVersion: false
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
async function bootstrapCompiler(options) {
|
|
163
|
+
if (!options)
|
|
164
|
+
options = defaultOptions();
|
|
165
|
+
let result;
|
|
166
|
+
|
|
167
|
+
if (options.clean) {
|
|
168
|
+
console.log("Deleting previous bootstrap compiler");
|
|
169
|
+
await deleteRecursive("bootstrap");
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Use the compiler in node_modules to compile a temporary version
|
|
173
|
+
console.log("Creating temporary compiler with known-good one");
|
|
174
|
+
result = await runCommand("known-good", "node", "../bin/known-good/qx", "compile", "--target=" + options.target);
|
|
175
|
+
if (result.exitCode) {
|
|
176
|
+
process.exit(result.exitCode);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Create a handy `qx` binary for that version
|
|
180
|
+
await fsPromises.writeFile("bootstrap/qx",
|
|
181
|
+
`#!/usr/bin/env node
|
|
182
|
+
const path=require("path");
|
|
183
|
+
require("../source/resource/qx/tool/loadsass.js");
|
|
184
|
+
require(path.join(__dirname, "compiled", "node", "${options.target}", "compiler"));
|
|
185
|
+
`, "utf8");
|
|
186
|
+
fs.chmodSync("bootstrap/qx", "777");
|
|
187
|
+
fs.copyFileSync("bin/build/qx.cmd", "bootstrap/qx.cmd");
|
|
188
|
+
|
|
189
|
+
/*
|
|
190
|
+
* Now use the new ./bootstrap/ compiler to compile itself again; the output goes into the
|
|
191
|
+
* normal `compiled` directory, ready for use.
|
|
192
|
+
*
|
|
193
|
+
* Note that we compile both source and build targets; this is because some of
|
|
194
|
+
* the unit tests have to refer to the compiled code and we want to be sure that
|
|
195
|
+
* it does not matter if they use source or build, just make sure it is up to date
|
|
196
|
+
*/
|
|
197
|
+
console.log("Compiling source version");
|
|
198
|
+
result = await runCommand(".", "node", "./bootstrap/qx", "compile", "--clean", "--verbose");
|
|
199
|
+
if (result.exitCode) {
|
|
200
|
+
process.exit(result.exitCode);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
console.log("Compiling build version");
|
|
204
|
+
result = await runCommand(".", "node", "./bootstrap/qx", "compile", "--target=build", "--clean", "--verbose");
|
|
205
|
+
if (result.exitCode) {
|
|
206
|
+
process.exit(result.exitCode);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
console.log("Compiler successfully bootstrapped");
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// this is simply a copy of qx.tool.utils.files.Utils
|
|
213
|
+
// needs to be cleaned up.
|
|
214
|
+
moreUtils = {
|
|
215
|
+
async findAllFiles(dir, fnEach) {
|
|
216
|
+
let filenames;
|
|
217
|
+
try {
|
|
218
|
+
filenames = await fsPromises.readdir(dir);
|
|
219
|
+
} catch (ex) {
|
|
220
|
+
if (ex.code == "ENOENT") {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
throw ex;
|
|
224
|
+
}
|
|
225
|
+
await qx.Promise.all(filenames.map(async shortName => {
|
|
226
|
+
let filename = path.join(dir, shortName);
|
|
227
|
+
let tmp = await stat(filename);
|
|
228
|
+
if (tmp.isDirectory()) {
|
|
229
|
+
await qx.tool.utils.files.Utils.findAllFiles(filename, fnEach);
|
|
230
|
+
} else {
|
|
231
|
+
await fnEach(filename);
|
|
232
|
+
}
|
|
233
|
+
}));
|
|
234
|
+
},
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Synchronises two files or folders; files are copied from/to but only if their
|
|
238
|
+
* modification time or size has changed.
|
|
239
|
+
* @param from {String} path to copy from
|
|
240
|
+
* @param to {String} path to copy to
|
|
241
|
+
* @param filter {Function?} optional filter method to validate filenames before sync
|
|
242
|
+
* @async
|
|
243
|
+
*/
|
|
244
|
+
sync: function(from, to, filter) {
|
|
245
|
+
var t = this;
|
|
246
|
+
|
|
247
|
+
function copy(statFrom, statTo) {
|
|
248
|
+
if (statFrom.isDirectory()) {
|
|
249
|
+
var p;
|
|
250
|
+
if (statTo === null) {
|
|
251
|
+
p = fsPromises.mkdir(to);
|
|
252
|
+
} else {
|
|
253
|
+
p = Promise.resolve();
|
|
254
|
+
}
|
|
255
|
+
return p.then(() => fsPromises.readdir(from)
|
|
256
|
+
.then(files => Promise.all(files.map(file => t.sync(path.join(from, file), path.join(to, file), filter)))));
|
|
257
|
+
} else if (statFrom.isFile()) {
|
|
258
|
+
return Promise.resolve(filter ? filter(from, to) : true)
|
|
259
|
+
.then(result => result && t.copyFile(from, to));
|
|
260
|
+
}
|
|
261
|
+
return undefined;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return new Promise((resolve, reject) => {
|
|
265
|
+
var statFrom = null;
|
|
266
|
+
var statTo = null;
|
|
267
|
+
|
|
268
|
+
stat(from)
|
|
269
|
+
.then(tmp => {
|
|
270
|
+
statFrom = tmp;
|
|
271
|
+
return stat(to)
|
|
272
|
+
.then(tmp => statTo = tmp)
|
|
273
|
+
.catch(err => {
|
|
274
|
+
if (err.code !== "ENOENT") {
|
|
275
|
+
throw err;
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
})
|
|
279
|
+
.then(() => {
|
|
280
|
+
if (!statTo || statFrom.isDirectory() != statTo.isDirectory()) {
|
|
281
|
+
return t.deleteRecursive(to)
|
|
282
|
+
.then(() => copy(statFrom, statTo));
|
|
283
|
+
} else if (statFrom.isDirectory() || (statFrom.mtime.getTime() > statTo.mtime.getTime() || statFrom.size != statTo.size)) {
|
|
284
|
+
return copy(statFrom, statTo);
|
|
285
|
+
}
|
|
286
|
+
return undefined;
|
|
287
|
+
})
|
|
288
|
+
.then(resolve)
|
|
289
|
+
.catch(reject);
|
|
290
|
+
});
|
|
291
|
+
},
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Copies a file
|
|
295
|
+
* @param from {String} path to copy from
|
|
296
|
+
* @param to {String} path to copy to
|
|
297
|
+
* @async
|
|
298
|
+
*/
|
|
299
|
+
copyFile: function(from, to) {
|
|
300
|
+
return new Promise((resolve, reject) => {
|
|
301
|
+
moreUtils.mkParentPath(to, function() {
|
|
302
|
+
var rs = fs.createReadStream(from, { flags: "r", encoding: "binary" });
|
|
303
|
+
var ws = fs.createWriteStream(to, { flags: "w", encoding: "binary" });
|
|
304
|
+
rs.on("end", function() {
|
|
305
|
+
resolve(from, to);
|
|
306
|
+
});
|
|
307
|
+
rs.on("error", reject);
|
|
308
|
+
ws.on("error", reject);
|
|
309
|
+
rs.pipe(ws);
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
},
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Returns the stats for a file, or null if the file does not exist
|
|
316
|
+
*
|
|
317
|
+
* @param filename
|
|
318
|
+
* @returns {fs.Stat}
|
|
319
|
+
* @async
|
|
320
|
+
*/
|
|
321
|
+
safeStat: function(filename) {
|
|
322
|
+
return new Promise((resolve, reject) => {
|
|
323
|
+
fs.stat(filename, function(err, stats) {
|
|
324
|
+
if (err && err.code != "ENOENT") {
|
|
325
|
+
reject(err);
|
|
326
|
+
} else {
|
|
327
|
+
resolve(err ? null : stats);
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
},
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Deletes a file, does nothing if the file does not exist
|
|
335
|
+
*
|
|
336
|
+
* @param filename {String} file to delete
|
|
337
|
+
* @async
|
|
338
|
+
*/
|
|
339
|
+
safeUnlink: function(filename) {
|
|
340
|
+
return new Promise((resolve, reject) => {
|
|
341
|
+
fs.unlink(filename, function(err) {
|
|
342
|
+
if (err && err.code != "ENOENT") {
|
|
343
|
+
reject(err);
|
|
344
|
+
} else {
|
|
345
|
+
resolve();
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
},
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Renames a file, does nothing if the file does not exist
|
|
353
|
+
*
|
|
354
|
+
* @param from {String} file to rename
|
|
355
|
+
* @param to {String} new filename
|
|
356
|
+
* @async
|
|
357
|
+
*/
|
|
358
|
+
safeRename: function(from, to) {
|
|
359
|
+
return new Promise((resolve, reject) => {
|
|
360
|
+
fs.rename(from, to, function(err) {
|
|
361
|
+
if (err && err.code != "ENOENT") {
|
|
362
|
+
reject(err);
|
|
363
|
+
} else {
|
|
364
|
+
resolve();
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
},
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Normalises the path and corrects the case of the path to match what is actually on the filing system
|
|
372
|
+
*
|
|
373
|
+
* @param dir {String} the filename to normalise
|
|
374
|
+
* @returns {String} the new path
|
|
375
|
+
* @async
|
|
376
|
+
*/
|
|
377
|
+
correctCase: function(dir) {
|
|
378
|
+
var drivePrefix = "";
|
|
379
|
+
if (process.platform === "win32" && dir.match(/^[a-zA-Z]:/)) {
|
|
380
|
+
drivePrefix = dir.substring(0, 2);
|
|
381
|
+
dir = dir.substring(2);
|
|
382
|
+
}
|
|
383
|
+
dir = dir.replace(/\\/g, "/");
|
|
384
|
+
var segs = dir.split("/");
|
|
385
|
+
if (!segs.length) {
|
|
386
|
+
return drivePrefix + dir;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
var currentDir;
|
|
390
|
+
var index;
|
|
391
|
+
if (segs[0].length) {
|
|
392
|
+
currentDir = "";
|
|
393
|
+
index = 0;
|
|
394
|
+
} else {
|
|
395
|
+
currentDir = "/";
|
|
396
|
+
index = 1;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function bumpToNext(nextSeg) {
|
|
400
|
+
index++;
|
|
401
|
+
if (currentDir.length && currentDir !== "/") {
|
|
402
|
+
currentDir += "/";
|
|
403
|
+
}
|
|
404
|
+
currentDir += nextSeg;
|
|
405
|
+
return next();
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function next() {
|
|
409
|
+
if (index == segs.length) {
|
|
410
|
+
if (process.platform === "win32") {
|
|
411
|
+
currentDir = currentDir.replace(/\//g, "\\");
|
|
412
|
+
}
|
|
413
|
+
return Promise.resolve(drivePrefix + currentDir);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
let nextSeg = segs[index];
|
|
417
|
+
if (nextSeg == "." || nextSeg == "..") {
|
|
418
|
+
return bumpToNext(nextSeg);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
return new Promise((resolve, reject) => {
|
|
422
|
+
fs.readdir(currentDir.length == 0 ? "." : drivePrefix + currentDir, { encoding: "utf8" }, (err, files) => {
|
|
423
|
+
if (err) {
|
|
424
|
+
reject(err);
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
let nextLowerCase = nextSeg.toLowerCase();
|
|
429
|
+
let exact = false;
|
|
430
|
+
let insensitive = null;
|
|
431
|
+
for (let i = 0; i < files.length; i++) {
|
|
432
|
+
if (files[i] === nextSeg) {
|
|
433
|
+
exact = true;
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
436
|
+
if (files[i].toLowerCase() === nextLowerCase) {
|
|
437
|
+
insensitive = files[i];
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
if (!exact && insensitive) {
|
|
441
|
+
nextSeg = insensitive;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
bumpToNext(nextSeg).then(resolve);
|
|
445
|
+
});
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
return new Promise((resolve, reject) => {
|
|
450
|
+
fs.stat(drivePrefix + dir, err => {
|
|
451
|
+
if (err) {
|
|
452
|
+
if (err.code == "ENOENT") {
|
|
453
|
+
resolve(drivePrefix + dir);
|
|
454
|
+
} else {
|
|
455
|
+
reject(err);
|
|
456
|
+
}
|
|
457
|
+
} else {
|
|
458
|
+
next().then(resolve);
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
});
|
|
462
|
+
},
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Creates a dir
|
|
466
|
+
* @param dir
|
|
467
|
+
* @param cb
|
|
468
|
+
*/
|
|
469
|
+
mkpath: function mkpath(dir, cb) {
|
|
470
|
+
dir = path.normalize(dir);
|
|
471
|
+
var segs = dir.split(path.sep);
|
|
472
|
+
var made = "";
|
|
473
|
+
async.eachSeries(
|
|
474
|
+
segs,
|
|
475
|
+
function (seg, cb) {
|
|
476
|
+
if (made.length || !seg.length) {
|
|
477
|
+
made += "/";
|
|
478
|
+
}
|
|
479
|
+
made += seg;
|
|
480
|
+
fs.exists(made, function (exists) {
|
|
481
|
+
if (!exists) {
|
|
482
|
+
fs.mkdir(made, function (err) {
|
|
483
|
+
if (err && err.code === "EEXIST") {
|
|
484
|
+
err = null;
|
|
485
|
+
}
|
|
486
|
+
cb(err);
|
|
487
|
+
});
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
fs.stat(made, function (err, stat) {
|
|
491
|
+
if (err) {
|
|
492
|
+
cb(err);
|
|
493
|
+
} else if (stat.isDirectory()) {
|
|
494
|
+
cb(null);
|
|
495
|
+
} else {
|
|
496
|
+
cb(new Error("Cannot create " + made + " (in " + dir + ") because it exists and is not a directory", "ENOENT"));
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
});
|
|
500
|
+
},
|
|
501
|
+
function (err) {
|
|
502
|
+
cb(err);
|
|
503
|
+
});
|
|
504
|
+
},
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Creates the parent directory of a filename, if it does not already exist
|
|
508
|
+
*/
|
|
509
|
+
mkParentPath: function mkParentPath(dir, cb) {
|
|
510
|
+
var segs = dir.split(/[\\\/]/);
|
|
511
|
+
segs.pop();
|
|
512
|
+
if (!segs.length) {
|
|
513
|
+
return cb && cb();
|
|
514
|
+
}
|
|
515
|
+
dir = segs.join(path.sep);
|
|
516
|
+
return this.mkpath(dir, cb);
|
|
517
|
+
},
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Creates the parent directory of a filename, if it does not already exist
|
|
521
|
+
*
|
|
522
|
+
* @param {string} filename the filename to create the parent directory of
|
|
523
|
+
*
|
|
524
|
+
* @return {Promise?} the value
|
|
525
|
+
*/
|
|
526
|
+
makeParentDir: function (filename) {
|
|
527
|
+
const mkParentPath = promisify(this.mkParentPath).bind(this);
|
|
528
|
+
return mkParentPath(filename);
|
|
529
|
+
},
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Creates a directory, if it does not exist, including all intermediate paths
|
|
533
|
+
*
|
|
534
|
+
* @param {string} filename the directory to create
|
|
535
|
+
*
|
|
536
|
+
* @return {Promise?} the value
|
|
537
|
+
*/
|
|
538
|
+
makeDirs: function (filename) {
|
|
539
|
+
const mkpath = promisify(this.mkpath);
|
|
540
|
+
return mkpath(filename);
|
|
541
|
+
}
|
|
542
|
+
};
|
|
543
|
+
|
|
544
|
+
module.exports = {
|
|
545
|
+
getCompiler,
|
|
546
|
+
runCompiler,
|
|
547
|
+
runCommand,
|
|
548
|
+
defaultOptions,
|
|
549
|
+
bootstrapCompiler,
|
|
550
|
+
deleteRecursive,
|
|
551
|
+
safeDelete,
|
|
552
|
+
fsPromises,
|
|
553
|
+
promisify,
|
|
554
|
+
findAllFiles: moreUtils.findAllFiles,
|
|
555
|
+
sync: moreUtils.sync,
|
|
556
|
+
copyFile: moreUtils.copyFile,
|
|
557
|
+
safeStat: moreUtils.safeStat,
|
|
558
|
+
safeRename: moreUtils.safeRename,
|
|
559
|
+
correctCase: moreUtils.correctCase
|
|
560
|
+
};
|
|
561
|
+
|