github.com/jfrog/frogbot@v1.1.1-0.20231221090046-821a26f50338/action/node_modules/@actions/io/lib/io.js (about) 1 "use strict"; 2 var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 if (k2 === undefined) k2 = k; 4 Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); 5 }) : (function(o, m, k, k2) { 6 if (k2 === undefined) k2 = k; 7 o[k2] = m[k]; 8 })); 9 var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 10 Object.defineProperty(o, "default", { enumerable: true, value: v }); 11 }) : function(o, v) { 12 o["default"] = v; 13 }); 14 var __importStar = (this && this.__importStar) || function (mod) { 15 if (mod && mod.__esModule) return mod; 16 var result = {}; 17 if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 18 __setModuleDefault(result, mod); 19 return result; 20 }; 21 var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 22 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 23 return new (P || (P = Promise))(function (resolve, reject) { 24 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 25 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 26 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 27 step((generator = generator.apply(thisArg, _arguments || [])).next()); 28 }); 29 }; 30 Object.defineProperty(exports, "__esModule", { value: true }); 31 exports.findInPath = exports.which = exports.mkdirP = exports.rmRF = exports.mv = exports.cp = void 0; 32 const assert_1 = require("assert"); 33 const childProcess = __importStar(require("child_process")); 34 const path = __importStar(require("path")); 35 const util_1 = require("util"); 36 const ioUtil = __importStar(require("./io-util")); 37 const exec = util_1.promisify(childProcess.exec); 38 const execFile = util_1.promisify(childProcess.execFile); 39 /** 40 * Copies a file or folder. 41 * Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js 42 * 43 * @param source source path 44 * @param dest destination path 45 * @param options optional. See CopyOptions. 46 */ 47 function cp(source, dest, options = {}) { 48 return __awaiter(this, void 0, void 0, function* () { 49 const { force, recursive, copySourceDirectory } = readCopyOptions(options); 50 const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null; 51 // Dest is an existing file, but not forcing 52 if (destStat && destStat.isFile() && !force) { 53 return; 54 } 55 // If dest is an existing directory, should copy inside. 56 const newDest = destStat && destStat.isDirectory() && copySourceDirectory 57 ? path.join(dest, path.basename(source)) 58 : dest; 59 if (!(yield ioUtil.exists(source))) { 60 throw new Error(`no such file or directory: ${source}`); 61 } 62 const sourceStat = yield ioUtil.stat(source); 63 if (sourceStat.isDirectory()) { 64 if (!recursive) { 65 throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`); 66 } 67 else { 68 yield cpDirRecursive(source, newDest, 0, force); 69 } 70 } 71 else { 72 if (path.relative(source, newDest) === '') { 73 // a file cannot be copied to itself 74 throw new Error(`'${newDest}' and '${source}' are the same file`); 75 } 76 yield copyFile(source, newDest, force); 77 } 78 }); 79 } 80 exports.cp = cp; 81 /** 82 * Moves a path. 83 * 84 * @param source source path 85 * @param dest destination path 86 * @param options optional. See MoveOptions. 87 */ 88 function mv(source, dest, options = {}) { 89 return __awaiter(this, void 0, void 0, function* () { 90 if (yield ioUtil.exists(dest)) { 91 let destExists = true; 92 if (yield ioUtil.isDirectory(dest)) { 93 // If dest is directory copy src into dest 94 dest = path.join(dest, path.basename(source)); 95 destExists = yield ioUtil.exists(dest); 96 } 97 if (destExists) { 98 if (options.force == null || options.force) { 99 yield rmRF(dest); 100 } 101 else { 102 throw new Error('Destination already exists'); 103 } 104 } 105 } 106 yield mkdirP(path.dirname(dest)); 107 yield ioUtil.rename(source, dest); 108 }); 109 } 110 exports.mv = mv; 111 /** 112 * Remove a path recursively with force 113 * 114 * @param inputPath path to remove 115 */ 116 function rmRF(inputPath) { 117 return __awaiter(this, void 0, void 0, function* () { 118 if (ioUtil.IS_WINDOWS) { 119 // Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another 120 // program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del. 121 // Check for invalid characters 122 // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file 123 if (/[*"<>|]/.test(inputPath)) { 124 throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows'); 125 } 126 try { 127 const cmdPath = ioUtil.getCmdPath(); 128 if (yield ioUtil.isDirectory(inputPath, true)) { 129 yield exec(`${cmdPath} /s /c "rd /s /q "%inputPath%""`, { 130 env: { inputPath } 131 }); 132 } 133 else { 134 yield exec(`${cmdPath} /s /c "del /f /a "%inputPath%""`, { 135 env: { inputPath } 136 }); 137 } 138 } 139 catch (err) { 140 // if you try to delete a file that doesn't exist, desired result is achieved 141 // other errors are valid 142 if (err.code !== 'ENOENT') 143 throw err; 144 } 145 // Shelling out fails to remove a symlink folder with missing source, this unlink catches that 146 try { 147 yield ioUtil.unlink(inputPath); 148 } 149 catch (err) { 150 // if you try to delete a file that doesn't exist, desired result is achieved 151 // other errors are valid 152 if (err.code !== 'ENOENT') 153 throw err; 154 } 155 } 156 else { 157 let isDir = false; 158 try { 159 isDir = yield ioUtil.isDirectory(inputPath); 160 } 161 catch (err) { 162 // if you try to delete a file that doesn't exist, desired result is achieved 163 // other errors are valid 164 if (err.code !== 'ENOENT') 165 throw err; 166 return; 167 } 168 if (isDir) { 169 yield execFile(`rm`, [`-rf`, `${inputPath}`]); 170 } 171 else { 172 yield ioUtil.unlink(inputPath); 173 } 174 } 175 }); 176 } 177 exports.rmRF = rmRF; 178 /** 179 * Make a directory. Creates the full path with folders in between 180 * Will throw if it fails 181 * 182 * @param fsPath path to create 183 * @returns Promise<void> 184 */ 185 function mkdirP(fsPath) { 186 return __awaiter(this, void 0, void 0, function* () { 187 assert_1.ok(fsPath, 'a path argument must be provided'); 188 yield ioUtil.mkdir(fsPath, { recursive: true }); 189 }); 190 } 191 exports.mkdirP = mkdirP; 192 /** 193 * Returns path of a tool had the tool actually been invoked. Resolves via paths. 194 * If you check and the tool does not exist, it will throw. 195 * 196 * @param tool name of the tool 197 * @param check whether to check if tool exists 198 * @returns Promise<string> path to tool 199 */ 200 function which(tool, check) { 201 return __awaiter(this, void 0, void 0, function* () { 202 if (!tool) { 203 throw new Error("parameter 'tool' is required"); 204 } 205 // recursive when check=true 206 if (check) { 207 const result = yield which(tool, false); 208 if (!result) { 209 if (ioUtil.IS_WINDOWS) { 210 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.`); 211 } 212 else { 213 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.`); 214 } 215 } 216 return result; 217 } 218 const matches = yield findInPath(tool); 219 if (matches && matches.length > 0) { 220 return matches[0]; 221 } 222 return ''; 223 }); 224 } 225 exports.which = which; 226 /** 227 * Returns a list of all occurrences of the given tool on the system path. 228 * 229 * @returns Promise<string[]> the paths of the tool 230 */ 231 function findInPath(tool) { 232 return __awaiter(this, void 0, void 0, function* () { 233 if (!tool) { 234 throw new Error("parameter 'tool' is required"); 235 } 236 // build the list of extensions to try 237 const extensions = []; 238 if (ioUtil.IS_WINDOWS && process.env['PATHEXT']) { 239 for (const extension of process.env['PATHEXT'].split(path.delimiter)) { 240 if (extension) { 241 extensions.push(extension); 242 } 243 } 244 } 245 // if it's rooted, return it if exists. otherwise return empty. 246 if (ioUtil.isRooted(tool)) { 247 const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions); 248 if (filePath) { 249 return [filePath]; 250 } 251 return []; 252 } 253 // if any path separators, return empty 254 if (tool.includes(path.sep)) { 255 return []; 256 } 257 // build the list of directories 258 // 259 // Note, technically "where" checks the current directory on Windows. From a toolkit perspective, 260 // it feels like we should not do this. Checking the current directory seems like more of a use 261 // case of a shell, and the which() function exposed by the toolkit should strive for consistency 262 // across platforms. 263 const directories = []; 264 if (process.env.PATH) { 265 for (const p of process.env.PATH.split(path.delimiter)) { 266 if (p) { 267 directories.push(p); 268 } 269 } 270 } 271 // find all matches 272 const matches = []; 273 for (const directory of directories) { 274 const filePath = yield ioUtil.tryGetExecutablePath(path.join(directory, tool), extensions); 275 if (filePath) { 276 matches.push(filePath); 277 } 278 } 279 return matches; 280 }); 281 } 282 exports.findInPath = findInPath; 283 function readCopyOptions(options) { 284 const force = options.force == null ? true : options.force; 285 const recursive = Boolean(options.recursive); 286 const copySourceDirectory = options.copySourceDirectory == null 287 ? true 288 : Boolean(options.copySourceDirectory); 289 return { force, recursive, copySourceDirectory }; 290 } 291 function cpDirRecursive(sourceDir, destDir, currentDepth, force) { 292 return __awaiter(this, void 0, void 0, function* () { 293 // Ensure there is not a run away recursive copy 294 if (currentDepth >= 255) 295 return; 296 currentDepth++; 297 yield mkdirP(destDir); 298 const files = yield ioUtil.readdir(sourceDir); 299 for (const fileName of files) { 300 const srcFile = `${sourceDir}/${fileName}`; 301 const destFile = `${destDir}/${fileName}`; 302 const srcFileStat = yield ioUtil.lstat(srcFile); 303 if (srcFileStat.isDirectory()) { 304 // Recurse 305 yield cpDirRecursive(srcFile, destFile, currentDepth, force); 306 } 307 else { 308 yield copyFile(srcFile, destFile, force); 309 } 310 } 311 // Change the mode for the newly created directory 312 yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode); 313 }); 314 } 315 // Buffered file copy 316 function copyFile(srcFile, destFile, force) { 317 return __awaiter(this, void 0, void 0, function* () { 318 if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) { 319 // unlink/re-link it 320 try { 321 yield ioUtil.lstat(destFile); 322 yield ioUtil.unlink(destFile); 323 } 324 catch (e) { 325 // Try to override file permission 326 if (e.code === 'EPERM') { 327 yield ioUtil.chmod(destFile, '0666'); 328 yield ioUtil.unlink(destFile); 329 } 330 // other errors = it doesn't exist, no work to do 331 } 332 // Copy over symlink 333 const symlinkFull = yield ioUtil.readlink(srcFile); 334 yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null); 335 } 336 else if (!(yield ioUtil.exists(destFile)) || force) { 337 yield ioUtil.copyFile(srcFile, destFile); 338 } 339 }); 340 } 341 //# sourceMappingURL=io.js.map