194 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			194 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | "use strict"; | ||
|  | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
|  |     return new (P || (P = Promise))(function (resolve, reject) { | ||
|  |         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
|  |         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
|  |         function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
|  |         step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
|  |     }); | ||
|  | }; | ||
|  | var _a; | ||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||
|  | const assert_1 = require("assert"); | ||
|  | const fs = require("fs"); | ||
|  | const path = require("path"); | ||
|  | _a = fs.promises, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.unlink = _a.unlink; | ||
|  | exports.IS_WINDOWS = process.platform === 'win32'; | ||
|  | function exists(fsPath) { | ||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||
|  |         try { | ||
|  |             yield exports.stat(fsPath); | ||
|  |         } | ||
|  |         catch (err) { | ||
|  |             if (err.code === 'ENOENT') { | ||
|  |                 return false; | ||
|  |             } | ||
|  |             throw err; | ||
|  |         } | ||
|  |         return true; | ||
|  |     }); | ||
|  | } | ||
|  | exports.exists = exists; | ||
|  | function isDirectory(fsPath, useStat = false) { | ||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||
|  |         const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath); | ||
|  |         return stats.isDirectory(); | ||
|  |     }); | ||
|  | } | ||
|  | exports.isDirectory = isDirectory; | ||
|  | /** | ||
|  |  * On OSX/Linux, true if path starts with '/'. On Windows, true for paths like: | ||
|  |  * \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases). | ||
|  |  */ | ||
|  | function isRooted(p) { | ||
|  |     p = normalizeSeparators(p); | ||
|  |     if (!p) { | ||
|  |         throw new Error('isRooted() parameter "p" cannot be empty'); | ||
|  |     } | ||
|  |     if (exports.IS_WINDOWS) { | ||
|  |         return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello
 | ||
|  |         ); // e.g. C: or C:\hello
 | ||
|  |     } | ||
|  |     return p.startsWith('/'); | ||
|  | } | ||
|  | exports.isRooted = isRooted; | ||
|  | /** | ||
|  |  * Recursively create a directory at `fsPath`. | ||
|  |  * | ||
|  |  * This implementation is optimistic, meaning it attempts to create the full | ||
|  |  * path first, and backs up the path stack from there. | ||
|  |  * | ||
|  |  * @param fsPath The path to create | ||
|  |  * @param maxDepth The maximum recursion depth | ||
|  |  * @param depth The current recursion depth | ||
|  |  */ | ||
|  | function mkdirP(fsPath, maxDepth = 1000, depth = 1) { | ||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||
|  |         assert_1.ok(fsPath, 'a path argument must be provided'); | ||
|  |         fsPath = path.resolve(fsPath); | ||
|  |         if (depth >= maxDepth) | ||
|  |             return exports.mkdir(fsPath); | ||
|  |         try { | ||
|  |             yield exports.mkdir(fsPath); | ||
|  |             return; | ||
|  |         } | ||
|  |         catch (err) { | ||
|  |             switch (err.code) { | ||
|  |                 case 'ENOENT': { | ||
|  |                     yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1); | ||
|  |                     yield exports.mkdir(fsPath); | ||
|  |                     return; | ||
|  |                 } | ||
|  |                 default: { | ||
|  |                     let stats; | ||
|  |                     try { | ||
|  |                         stats = yield exports.stat(fsPath); | ||
|  |                     } | ||
|  |                     catch (err2) { | ||
|  |                         throw err; | ||
|  |                     } | ||
|  |                     if (!stats.isDirectory()) | ||
|  |                         throw err; | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |     }); | ||
|  | } | ||
|  | exports.mkdirP = mkdirP; | ||
|  | /** | ||
|  |  * Best effort attempt to determine whether a file exists and is executable. | ||
|  |  * @param filePath    file path to check | ||
|  |  * @param extensions  additional file extensions to try | ||
|  |  * @return if file exists and is executable, returns the file path. otherwise empty string. | ||
|  |  */ | ||
|  | function tryGetExecutablePath(filePath, extensions) { | ||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||
|  |         let stats = undefined; | ||
|  |         try { | ||
|  |             // test file exists
 | ||
|  |             stats = yield exports.stat(filePath); | ||
|  |         } | ||
|  |         catch (err) { | ||
|  |             if (err.code !== 'ENOENT') { | ||
|  |                 // eslint-disable-next-line no-console
 | ||
|  |                 console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); | ||
|  |             } | ||
|  |         } | ||
|  |         if (stats && stats.isFile()) { | ||
|  |             if (exports.IS_WINDOWS) { | ||
|  |                 // on Windows, test for valid extension
 | ||
|  |                 const upperExt = path.extname(filePath).toUpperCase(); | ||
|  |                 if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) { | ||
|  |                     return filePath; | ||
|  |                 } | ||
|  |             } | ||
|  |             else { | ||
|  |                 if (isUnixExecutable(stats)) { | ||
|  |                     return filePath; | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |         // try each extension
 | ||
|  |         const originalFilePath = filePath; | ||
|  |         for (const extension of extensions) { | ||
|  |             filePath = originalFilePath + extension; | ||
|  |             stats = undefined; | ||
|  |             try { | ||
|  |                 stats = yield exports.stat(filePath); | ||
|  |             } | ||
|  |             catch (err) { | ||
|  |                 if (err.code !== 'ENOENT') { | ||
|  |                     // eslint-disable-next-line no-console
 | ||
|  |                     console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); | ||
|  |                 } | ||
|  |             } | ||
|  |             if (stats && stats.isFile()) { | ||
|  |                 if (exports.IS_WINDOWS) { | ||
|  |                     // preserve the case of the actual file (since an extension was appended)
 | ||
|  |                     try { | ||
|  |                         const directory = path.dirname(filePath); | ||
|  |                         const upperName = path.basename(filePath).toUpperCase(); | ||
|  |                         for (const actualName of yield exports.readdir(directory)) { | ||
|  |                             if (upperName === actualName.toUpperCase()) { | ||
|  |                                 filePath = path.join(directory, actualName); | ||
|  |                                 break; | ||
|  |                             } | ||
|  |                         } | ||
|  |                     } | ||
|  |                     catch (err) { | ||
|  |                         // eslint-disable-next-line no-console
 | ||
|  |                         console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`); | ||
|  |                     } | ||
|  |                     return filePath; | ||
|  |                 } | ||
|  |                 else { | ||
|  |                     if (isUnixExecutable(stats)) { | ||
|  |                         return filePath; | ||
|  |                     } | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |         return ''; | ||
|  |     }); | ||
|  | } | ||
|  | exports.tryGetExecutablePath = tryGetExecutablePath; | ||
|  | function normalizeSeparators(p) { | ||
|  |     p = p || ''; | ||
|  |     if (exports.IS_WINDOWS) { | ||
|  |         // convert slashes on Windows
 | ||
|  |         p = p.replace(/\//g, '\\'); | ||
|  |         // remove redundant slashes
 | ||
|  |         return p.replace(/\\\\+/g, '\\'); | ||
|  |     } | ||
|  |     // remove redundant slashes
 | ||
|  |     return p.replace(/\/\/+/g, '/'); | ||
|  | } | ||
|  | // on Mac/Linux, test the execute bit
 | ||
|  | //     R   W  X  R  W X R W X
 | ||
|  | //   256 128 64 32 16 8 4 2 1
 | ||
|  | function isUnixExecutable(stats) { | ||
|  |     return ((stats.mode & 1) > 0 || | ||
|  |         ((stats.mode & 8) > 0 && stats.gid === process.getgid()) || | ||
|  |         ((stats.mode & 64) > 0 && stats.uid === process.getuid())); | ||
|  | } | ||
|  | //# sourceMappingURL=io-util.js.map
 |