| "use strict"; | |
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | |
| if (k2 === undefined) k2 = k; | |
| Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | |
| }) : (function(o, m, k, k2) { | |
| if (k2 === undefined) k2 = k; | |
| o[k2] = m[k]; | |
| })); | |
| var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | |
| Object.defineProperty(o, "default", { enumerable: true, value: v }); | |
| }) : function(o, v) { | |
| o["default"] = v; | |
| }); | |
| var __importStar = (this && this.__importStar) || function (mod) { | |
| if (mod && mod.__esModule) return mod; | |
| var result = {}; | |
| if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | |
| __setModuleDefault(result, mod); | |
| return result; | |
| }; | |
| var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | |
| function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | |
| 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) : adopt(result.value).then(fulfilled, rejected); } | |
| step((generator = generator.apply(thisArg, _arguments || [])).next()); | |
| }); | |
| }; | |
| Object.defineProperty(exports, "__esModule", { value: true }); | |
| exports.findInPath = exports.which = exports.mkdirP = exports.rmRF = exports.mv = exports.cp = void 0; | |
| const assert_1 = require("assert"); | |
| const path = __importStar(require("path")); | |
| const ioUtil = __importStar(require("./io-util")); | |
| /** | |
| * Copies a file or folder. | |
| * Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js | |
| * | |
| * @param source source path | |
| * @param dest destination path | |
| * @param options optional. See CopyOptions. | |
| */ | |
| function cp(source, dest, options = {}) { | |
| return __awaiter(this, void 0, void 0, function* () { | |
| const { force, recursive, copySourceDirectory } = readCopyOptions(options); | |
| const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null; | |
| // Dest is an existing file, but not forcing | |
| if (destStat && destStat.isFile() && !force) { | |
| return; | |
| } | |
| // If dest is an existing directory, should copy inside. | |
| const newDest = destStat && destStat.isDirectory() && copySourceDirectory | |
| ? path.join(dest, path.basename(source)) | |
| : dest; | |
| if (!(yield ioUtil.exists(source))) { | |
| throw new Error(`no such file or directory: ${source}`); | |
| } | |
| const sourceStat = yield ioUtil.stat(source); | |
| if (sourceStat.isDirectory()) { | |
| if (!recursive) { | |
| throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`); | |
| } | |
| else { | |
| yield cpDirRecursive(source, newDest, 0, force); | |
| } | |
| } | |
| else { | |
| if (path.relative(source, newDest) === '') { | |
| // a file cannot be copied to itself | |
| throw new Error(`'${newDest}' and '${source}' are the same file`); | |
| } | |
| yield copyFile(source, newDest, force); | |
| } | |
| }); | |
| } | |
| exports.cp = cp; | |
| /** | |
| * Moves a path. | |
| * | |
| * @param source source path | |
| * @param dest destination path | |
| * @param options optional. See MoveOptions. | |
| */ | |
| function mv(source, dest, options = {}) { | |
| return __awaiter(this, void 0, void 0, function* () { | |
| if (yield ioUtil.exists(dest)) { | |
| let destExists = true; | |
| if (yield ioUtil.isDirectory(dest)) { | |
| // If dest is directory copy src into dest | |
| dest = path.join(dest, path.basename(source)); | |
| destExists = yield ioUtil.exists(dest); | |
| } | |
| if (destExists) { | |
| if (options.force == null || options.force) { | |
| yield rmRF(dest); | |
| } | |
| else { | |
| throw new Error('Destination already exists'); | |
| } | |
| } | |
| } | |
| yield mkdirP(path.dirname(dest)); | |
| yield ioUtil.rename(source, dest); | |
| }); | |
| } | |
| exports.mv = mv; | |
| /** | |
| * Remove a path recursively with force | |
| * | |
| * @param inputPath path to remove | |
| */ | |
| function rmRF(inputPath) { | |
| return __awaiter(this, void 0, void 0, function* () { | |
| if (ioUtil.IS_WINDOWS) { | |
| // Check for invalid characters | |
| // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file | |
| if (/[*"<>|]/.test(inputPath)) { | |
| throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows'); | |
| } | |
| } | |
| try { | |
| // note if path does not exist, error is silent | |
| yield ioUtil.rm(inputPath, { | |
| force: true, | |
| maxRetries: 3, | |
| recursive: true, | |
| retryDelay: 300 | |
| }); | |
| } | |
| catch (err) { | |
| throw new Error(`File was unable to be removed ${err}`); | |
| } | |
| }); | |
| } | |
| exports.rmRF = rmRF; | |
| /** | |
| * Make a directory. Creates the full path with folders in between | |
| * Will throw if it fails | |
| * | |
| * @param fsPath path to create | |
| * @returns Promise<void> | |
| */ | |
| function mkdirP(fsPath) { | |
| return __awaiter(this, void 0, void 0, function* () { | |
| assert_1.ok(fsPath, 'a path argument must be provided'); | |
| yield ioUtil.mkdir(fsPath, { recursive: true }); | |
| }); | |
| } | |
| exports.mkdirP = mkdirP; | |
| /** | |
| * Returns path of a tool had the tool actually been invoked. Resolves via paths. | |
| * If you check and the tool does not exist, it will throw. | |
| * | |
| * @param tool name of the tool | |
| * @param check whether to check if tool exists | |
| * @returns Promise<string> path to tool | |
| */ | |
| function which(tool, check) { | |
| return __awaiter(this, void 0, void 0, function* () { | |
| if (!tool) { | |
| throw new Error("parameter 'tool' is required"); | |
| } | |
| // recursive when check=true | |
| if (check) { | |
| const result = yield which(tool, false); | |
| if (!result) { | |
| if (ioUtil.IS_WINDOWS) { | |
| throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`); | |
| } | |
| else { | |
| throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`); | |
| } | |
| } | |
| return result; | |
| } | |
| const matches = yield findInPath(tool); | |
| if (matches && matches.length > 0) { | |
| return matches[0]; | |
| } | |
| return ''; | |
| }); | |
| } | |
| exports.which = which; | |
| /** | |
| * Returns a list of all occurrences of the given tool on the system path. | |
| * | |
| * @returns Promise<string[]> the paths of the tool | |
| */ | |
| function findInPath(tool) { | |
| return __awaiter(this, void 0, void 0, function* () { | |
| if (!tool) { | |
| throw new Error("parameter 'tool' is required"); | |
| } | |
| // build the list of extensions to try | |
| const extensions = []; | |
| if (ioUtil.IS_WINDOWS && process.env['PATHEXT']) { | |
| for (const extension of process.env['PATHEXT'].split(path.delimiter)) { | |
| if (extension) { | |
| extensions.push(extension); | |
| } | |
| } | |
| } | |
| // if it's rooted, return it if exists. otherwise return empty. | |
| if (ioUtil.isRooted(tool)) { | |
| const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions); | |
| if (filePath) { | |
| return [filePath]; | |
| } | |
| return []; | |
| } | |
| // if any path separators, return empty | |
| if (tool.includes(path.sep)) { | |
| return []; | |
| } | |
| // build the list of directories | |
| // | |
| // Note, technically "where" checks the current directory on Windows. From a toolkit perspective, | |
| // it feels like we should not do this. Checking the current directory seems like more of a use | |
| // case of a shell, and the which() function exposed by the toolkit should strive for consistency | |
| // across platforms. | |
| const directories = []; | |
| if (process.env.PATH) { | |
| for (const p of process.env.PATH.split(path.delimiter)) { | |
| if (p) { | |
| directories.push(p); | |
| } | |
| } | |
| } | |
| // find all matches | |
| const matches = []; | |
| for (const directory of directories) { | |
| const filePath = yield ioUtil.tryGetExecutablePath(path.join(directory, tool), extensions); | |
| if (filePath) { | |
| matches.push(filePath); | |
| } | |
| } | |
| return matches; | |
| }); | |
| } | |
| exports.findInPath = findInPath; | |
| function readCopyOptions(options) { | |
| const force = options.force == null ? true : options.force; | |
| const recursive = Boolean(options.recursive); | |
| const copySourceDirectory = options.copySourceDirectory == null | |
| ? true | |
| : Boolean(options.copySourceDirectory); | |
| return { force, recursive, copySourceDirectory }; | |
| } | |
| function cpDirRecursive(sourceDir, destDir, currentDepth, force) { | |
| return __awaiter(this, void 0, void 0, function* () { | |
| // Ensure there is not a run away recursive copy | |
| if (currentDepth >= 255) | |
| return; | |
| currentDepth++; | |
| yield mkdirP(destDir); | |
| const files = yield ioUtil.readdir(sourceDir); | |
| for (const fileName of files) { | |
| const srcFile = `${sourceDir}/${fileName}`; | |
| const destFile = `${destDir}/${fileName}`; | |
| const srcFileStat = yield ioUtil.lstat(srcFile); | |
| if (srcFileStat.isDirectory()) { | |
| // Recurse | |
| yield cpDirRecursive(srcFile, destFile, currentDepth, force); | |
| } | |
| else { | |
| yield copyFile(srcFile, destFile, force); | |
| } | |
| } | |
| // Change the mode for the newly created directory | |
| yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode); | |
| }); | |
| } | |
| // Buffered file copy | |
| function copyFile(srcFile, destFile, force) { | |
| return __awaiter(this, void 0, void 0, function* () { | |
| if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) { | |
| // unlink/re-link it | |
| try { | |
| yield ioUtil.lstat(destFile); | |
| yield ioUtil.unlink(destFile); | |
| } | |
| catch (e) { | |
| // Try to override file permission | |
| if (e.code === 'EPERM') { | |
| yield ioUtil.chmod(destFile, '0666'); | |
| yield ioUtil.unlink(destFile); | |
| } | |
| // other errors = it doesn't exist, no work to do | |
| } | |
| // Copy over symlink | |
| const symlinkFull = yield ioUtil.readlink(srcFile); | |
| yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null); | |
| } | |
| else if (!(yield ioUtil.exists(destFile)) || force) { | |
| yield ioUtil.copyFile(srcFile, destFile); | |
| } | |
| }); | |
| } | |
| //# sourceMappingURL=io.js.map |