github.com/jfrog/frogbot@v1.1.1-0.20231221090046-821a26f50338/action/node_modules/@actions/tool-cache/lib/tool-cache.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 var __importDefault = (this && this.__importDefault) || function (mod) { 31 return (mod && mod.__esModule) ? mod : { "default": mod }; 32 }; 33 Object.defineProperty(exports, "__esModule", { value: true }); 34 exports.evaluateVersions = exports.isExplicitVersion = exports.findFromManifest = exports.getManifestFromRepo = exports.findAllVersions = exports.find = exports.cacheFile = exports.cacheDir = exports.extractZip = exports.extractXar = exports.extractTar = exports.extract7z = exports.downloadTool = exports.HTTPError = void 0; 35 const core = __importStar(require("@actions/core")); 36 const io = __importStar(require("@actions/io")); 37 const fs = __importStar(require("fs")); 38 const mm = __importStar(require("./manifest")); 39 const os = __importStar(require("os")); 40 const path = __importStar(require("path")); 41 const httpm = __importStar(require("@actions/http-client")); 42 const semver = __importStar(require("semver")); 43 const stream = __importStar(require("stream")); 44 const util = __importStar(require("util")); 45 const assert_1 = require("assert"); 46 const v4_1 = __importDefault(require("uuid/v4")); 47 const exec_1 = require("@actions/exec/lib/exec"); 48 const retry_helper_1 = require("./retry-helper"); 49 class HTTPError extends Error { 50 constructor(httpStatusCode) { 51 super(`Unexpected HTTP response: ${httpStatusCode}`); 52 this.httpStatusCode = httpStatusCode; 53 Object.setPrototypeOf(this, new.target.prototype); 54 } 55 } 56 exports.HTTPError = HTTPError; 57 const IS_WINDOWS = process.platform === 'win32'; 58 const IS_MAC = process.platform === 'darwin'; 59 const userAgent = 'actions/tool-cache'; 60 /** 61 * Download a tool from an url and stream it into a file 62 * 63 * @param url url of tool to download 64 * @param dest path to download tool 65 * @param auth authorization header 66 * @param headers other headers 67 * @returns path to downloaded tool 68 */ 69 function downloadTool(url, dest, auth, headers) { 70 return __awaiter(this, void 0, void 0, function* () { 71 dest = dest || path.join(_getTempDirectory(), v4_1.default()); 72 yield io.mkdirP(path.dirname(dest)); 73 core.debug(`Downloading ${url}`); 74 core.debug(`Destination ${dest}`); 75 const maxAttempts = 3; 76 const minSeconds = _getGlobal('TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS', 10); 77 const maxSeconds = _getGlobal('TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS', 20); 78 const retryHelper = new retry_helper_1.RetryHelper(maxAttempts, minSeconds, maxSeconds); 79 return yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () { 80 return yield downloadToolAttempt(url, dest || '', auth, headers); 81 }), (err) => { 82 if (err instanceof HTTPError && err.httpStatusCode) { 83 // Don't retry anything less than 500, except 408 Request Timeout and 429 Too Many Requests 84 if (err.httpStatusCode < 500 && 85 err.httpStatusCode !== 408 && 86 err.httpStatusCode !== 429) { 87 return false; 88 } 89 } 90 // Otherwise retry 91 return true; 92 }); 93 }); 94 } 95 exports.downloadTool = downloadTool; 96 function downloadToolAttempt(url, dest, auth, headers) { 97 return __awaiter(this, void 0, void 0, function* () { 98 if (fs.existsSync(dest)) { 99 throw new Error(`Destination file path ${dest} already exists`); 100 } 101 // Get the response headers 102 const http = new httpm.HttpClient(userAgent, [], { 103 allowRetries: false 104 }); 105 if (auth) { 106 core.debug('set auth'); 107 if (headers === undefined) { 108 headers = {}; 109 } 110 headers.authorization = auth; 111 } 112 const response = yield http.get(url, headers); 113 if (response.message.statusCode !== 200) { 114 const err = new HTTPError(response.message.statusCode); 115 core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); 116 throw err; 117 } 118 // Download the response body 119 const pipeline = util.promisify(stream.pipeline); 120 const responseMessageFactory = _getGlobal('TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY', () => response.message); 121 const readStream = responseMessageFactory(); 122 let succeeded = false; 123 try { 124 yield pipeline(readStream, fs.createWriteStream(dest)); 125 core.debug('download complete'); 126 succeeded = true; 127 return dest; 128 } 129 finally { 130 // Error, delete dest before retry 131 if (!succeeded) { 132 core.debug('download failed'); 133 try { 134 yield io.rmRF(dest); 135 } 136 catch (err) { 137 core.debug(`Failed to delete '${dest}'. ${err.message}`); 138 } 139 } 140 } 141 }); 142 } 143 /** 144 * Extract a .7z file 145 * 146 * @param file path to the .7z file 147 * @param dest destination directory. Optional. 148 * @param _7zPath path to 7zr.exe. Optional, for long path support. Most .7z archives do not have this 149 * problem. If your .7z archive contains very long paths, you can pass the path to 7zr.exe which will 150 * gracefully handle long paths. By default 7zdec.exe is used because it is a very small program and is 151 * bundled with the tool lib. However it does not support long paths. 7zr.exe is the reduced command line 152 * interface, it is smaller than the full command line interface, and it does support long paths. At the 153 * time of this writing, it is freely available from the LZMA SDK that is available on the 7zip website. 154 * Be sure to check the current license agreement. If 7zr.exe is bundled with your action, then the path 155 * to 7zr.exe can be pass to this function. 156 * @returns path to the destination directory 157 */ 158 function extract7z(file, dest, _7zPath) { 159 return __awaiter(this, void 0, void 0, function* () { 160 assert_1.ok(IS_WINDOWS, 'extract7z() not supported on current OS'); 161 assert_1.ok(file, 'parameter "file" is required'); 162 dest = yield _createExtractFolder(dest); 163 const originalCwd = process.cwd(); 164 process.chdir(dest); 165 if (_7zPath) { 166 try { 167 const logLevel = core.isDebug() ? '-bb1' : '-bb0'; 168 const args = [ 169 'x', 170 logLevel, 171 '-bd', 172 '-sccUTF-8', 173 file 174 ]; 175 const options = { 176 silent: true 177 }; 178 yield exec_1.exec(`"${_7zPath}"`, args, options); 179 } 180 finally { 181 process.chdir(originalCwd); 182 } 183 } 184 else { 185 const escapedScript = path 186 .join(__dirname, '..', 'scripts', 'Invoke-7zdec.ps1') 187 .replace(/'/g, "''") 188 .replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines 189 const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); 190 const escapedTarget = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); 191 const command = `& '${escapedScript}' -Source '${escapedFile}' -Target '${escapedTarget}'`; 192 const args = [ 193 '-NoLogo', 194 '-Sta', 195 '-NoProfile', 196 '-NonInteractive', 197 '-ExecutionPolicy', 198 'Unrestricted', 199 '-Command', 200 command 201 ]; 202 const options = { 203 silent: true 204 }; 205 try { 206 const powershellPath = yield io.which('powershell', true); 207 yield exec_1.exec(`"${powershellPath}"`, args, options); 208 } 209 finally { 210 process.chdir(originalCwd); 211 } 212 } 213 return dest; 214 }); 215 } 216 exports.extract7z = extract7z; 217 /** 218 * Extract a compressed tar archive 219 * 220 * @param file path to the tar 221 * @param dest destination directory. Optional. 222 * @param flags flags for the tar command to use for extraction. Defaults to 'xz' (extracting gzipped tars). Optional. 223 * @returns path to the destination directory 224 */ 225 function extractTar(file, dest, flags = 'xz') { 226 return __awaiter(this, void 0, void 0, function* () { 227 if (!file) { 228 throw new Error("parameter 'file' is required"); 229 } 230 // Create dest 231 dest = yield _createExtractFolder(dest); 232 // Determine whether GNU tar 233 core.debug('Checking tar --version'); 234 let versionOutput = ''; 235 yield exec_1.exec('tar --version', [], { 236 ignoreReturnCode: true, 237 silent: true, 238 listeners: { 239 stdout: (data) => (versionOutput += data.toString()), 240 stderr: (data) => (versionOutput += data.toString()) 241 } 242 }); 243 core.debug(versionOutput.trim()); 244 const isGnuTar = versionOutput.toUpperCase().includes('GNU TAR'); 245 // Initialize args 246 let args; 247 if (flags instanceof Array) { 248 args = flags; 249 } 250 else { 251 args = [flags]; 252 } 253 if (core.isDebug() && !flags.includes('v')) { 254 args.push('-v'); 255 } 256 let destArg = dest; 257 let fileArg = file; 258 if (IS_WINDOWS && isGnuTar) { 259 args.push('--force-local'); 260 destArg = dest.replace(/\\/g, '/'); 261 // Technically only the dest needs to have `/` but for aesthetic consistency 262 // convert slashes in the file arg too. 263 fileArg = file.replace(/\\/g, '/'); 264 } 265 if (isGnuTar) { 266 // Suppress warnings when using GNU tar to extract archives created by BSD tar 267 args.push('--warning=no-unknown-keyword'); 268 args.push('--overwrite'); 269 } 270 args.push('-C', destArg, '-f', fileArg); 271 yield exec_1.exec(`tar`, args); 272 return dest; 273 }); 274 } 275 exports.extractTar = extractTar; 276 /** 277 * Extract a xar compatible archive 278 * 279 * @param file path to the archive 280 * @param dest destination directory. Optional. 281 * @param flags flags for the xar. Optional. 282 * @returns path to the destination directory 283 */ 284 function extractXar(file, dest, flags = []) { 285 return __awaiter(this, void 0, void 0, function* () { 286 assert_1.ok(IS_MAC, 'extractXar() not supported on current OS'); 287 assert_1.ok(file, 'parameter "file" is required'); 288 dest = yield _createExtractFolder(dest); 289 let args; 290 if (flags instanceof Array) { 291 args = flags; 292 } 293 else { 294 args = [flags]; 295 } 296 args.push('-x', '-C', dest, '-f', file); 297 if (core.isDebug()) { 298 args.push('-v'); 299 } 300 const xarPath = yield io.which('xar', true); 301 yield exec_1.exec(`"${xarPath}"`, _unique(args)); 302 return dest; 303 }); 304 } 305 exports.extractXar = extractXar; 306 /** 307 * Extract a zip 308 * 309 * @param file path to the zip 310 * @param dest destination directory. Optional. 311 * @returns path to the destination directory 312 */ 313 function extractZip(file, dest) { 314 return __awaiter(this, void 0, void 0, function* () { 315 if (!file) { 316 throw new Error("parameter 'file' is required"); 317 } 318 dest = yield _createExtractFolder(dest); 319 if (IS_WINDOWS) { 320 yield extractZipWin(file, dest); 321 } 322 else { 323 yield extractZipNix(file, dest); 324 } 325 return dest; 326 }); 327 } 328 exports.extractZip = extractZip; 329 function extractZipWin(file, dest) { 330 return __awaiter(this, void 0, void 0, function* () { 331 // build the powershell command 332 const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines 333 const escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); 334 const pwshPath = yield io.which('pwsh', false); 335 //To match the file overwrite behavior on nix systems, we use the overwrite = true flag for ExtractToDirectory 336 //and the -Force flag for Expand-Archive as a fallback 337 if (pwshPath) { 338 //attempt to use pwsh with ExtractToDirectory, if this fails attempt Expand-Archive 339 const pwshCommand = [ 340 `$ErrorActionPreference = 'Stop' ;`, 341 `try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`, 342 `try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) }`, 343 `catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force } else { throw $_ } } ;` 344 ].join(' '); 345 const args = [ 346 '-NoLogo', 347 '-NoProfile', 348 '-NonInteractive', 349 '-ExecutionPolicy', 350 'Unrestricted', 351 '-Command', 352 pwshCommand 353 ]; 354 core.debug(`Using pwsh at path: ${pwshPath}`); 355 yield exec_1.exec(`"${pwshPath}"`, args); 356 } 357 else { 358 const powershellCommand = [ 359 `$ErrorActionPreference = 'Stop' ;`, 360 `try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ;`, 361 `if ((Get-Command -Name Expand-Archive -Module Microsoft.PowerShell.Archive -ErrorAction Ignore)) { Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force }`, 362 `else {[System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) }` 363 ].join(' '); 364 const args = [ 365 '-NoLogo', 366 '-Sta', 367 '-NoProfile', 368 '-NonInteractive', 369 '-ExecutionPolicy', 370 'Unrestricted', 371 '-Command', 372 powershellCommand 373 ]; 374 const powershellPath = yield io.which('powershell', true); 375 core.debug(`Using powershell at path: ${powershellPath}`); 376 yield exec_1.exec(`"${powershellPath}"`, args); 377 } 378 }); 379 } 380 function extractZipNix(file, dest) { 381 return __awaiter(this, void 0, void 0, function* () { 382 const unzipPath = yield io.which('unzip', true); 383 const args = [file]; 384 if (!core.isDebug()) { 385 args.unshift('-q'); 386 } 387 args.unshift('-o'); //overwrite with -o, otherwise a prompt is shown which freezes the run 388 yield exec_1.exec(`"${unzipPath}"`, args, { cwd: dest }); 389 }); 390 } 391 /** 392 * Caches a directory and installs it into the tool cacheDir 393 * 394 * @param sourceDir the directory to cache into tools 395 * @param tool tool name 396 * @param version version of the tool. semver format 397 * @param arch architecture of the tool. Optional. Defaults to machine architecture 398 */ 399 function cacheDir(sourceDir, tool, version, arch) { 400 return __awaiter(this, void 0, void 0, function* () { 401 version = semver.clean(version) || version; 402 arch = arch || os.arch(); 403 core.debug(`Caching tool ${tool} ${version} ${arch}`); 404 core.debug(`source dir: ${sourceDir}`); 405 if (!fs.statSync(sourceDir).isDirectory()) { 406 throw new Error('sourceDir is not a directory'); 407 } 408 // Create the tool dir 409 const destPath = yield _createToolPath(tool, version, arch); 410 // copy each child item. do not move. move can fail on Windows 411 // due to anti-virus software having an open handle on a file. 412 for (const itemName of fs.readdirSync(sourceDir)) { 413 const s = path.join(sourceDir, itemName); 414 yield io.cp(s, destPath, { recursive: true }); 415 } 416 // write .complete 417 _completeToolPath(tool, version, arch); 418 return destPath; 419 }); 420 } 421 exports.cacheDir = cacheDir; 422 /** 423 * Caches a downloaded file (GUID) and installs it 424 * into the tool cache with a given targetName 425 * 426 * @param sourceFile the file to cache into tools. Typically a result of downloadTool which is a guid. 427 * @param targetFile the name of the file name in the tools directory 428 * @param tool tool name 429 * @param version version of the tool. semver format 430 * @param arch architecture of the tool. Optional. Defaults to machine architecture 431 */ 432 function cacheFile(sourceFile, targetFile, tool, version, arch) { 433 return __awaiter(this, void 0, void 0, function* () { 434 version = semver.clean(version) || version; 435 arch = arch || os.arch(); 436 core.debug(`Caching tool ${tool} ${version} ${arch}`); 437 core.debug(`source file: ${sourceFile}`); 438 if (!fs.statSync(sourceFile).isFile()) { 439 throw new Error('sourceFile is not a file'); 440 } 441 // create the tool dir 442 const destFolder = yield _createToolPath(tool, version, arch); 443 // copy instead of move. move can fail on Windows due to 444 // anti-virus software having an open handle on a file. 445 const destPath = path.join(destFolder, targetFile); 446 core.debug(`destination file ${destPath}`); 447 yield io.cp(sourceFile, destPath); 448 // write .complete 449 _completeToolPath(tool, version, arch); 450 return destFolder; 451 }); 452 } 453 exports.cacheFile = cacheFile; 454 /** 455 * Finds the path to a tool version in the local installed tool cache 456 * 457 * @param toolName name of the tool 458 * @param versionSpec version of the tool 459 * @param arch optional arch. defaults to arch of computer 460 */ 461 function find(toolName, versionSpec, arch) { 462 if (!toolName) { 463 throw new Error('toolName parameter is required'); 464 } 465 if (!versionSpec) { 466 throw new Error('versionSpec parameter is required'); 467 } 468 arch = arch || os.arch(); 469 // attempt to resolve an explicit version 470 if (!isExplicitVersion(versionSpec)) { 471 const localVersions = findAllVersions(toolName, arch); 472 const match = evaluateVersions(localVersions, versionSpec); 473 versionSpec = match; 474 } 475 // check for the explicit version in the cache 476 let toolPath = ''; 477 if (versionSpec) { 478 versionSpec = semver.clean(versionSpec) || ''; 479 const cachePath = path.join(_getCacheDirectory(), toolName, versionSpec, arch); 480 core.debug(`checking cache: ${cachePath}`); 481 if (fs.existsSync(cachePath) && fs.existsSync(`${cachePath}.complete`)) { 482 core.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`); 483 toolPath = cachePath; 484 } 485 else { 486 core.debug('not found'); 487 } 488 } 489 return toolPath; 490 } 491 exports.find = find; 492 /** 493 * Finds the paths to all versions of a tool that are installed in the local tool cache 494 * 495 * @param toolName name of the tool 496 * @param arch optional arch. defaults to arch of computer 497 */ 498 function findAllVersions(toolName, arch) { 499 const versions = []; 500 arch = arch || os.arch(); 501 const toolPath = path.join(_getCacheDirectory(), toolName); 502 if (fs.existsSync(toolPath)) { 503 const children = fs.readdirSync(toolPath); 504 for (const child of children) { 505 if (isExplicitVersion(child)) { 506 const fullPath = path.join(toolPath, child, arch || ''); 507 if (fs.existsSync(fullPath) && fs.existsSync(`${fullPath}.complete`)) { 508 versions.push(child); 509 } 510 } 511 } 512 } 513 return versions; 514 } 515 exports.findAllVersions = findAllVersions; 516 function getManifestFromRepo(owner, repo, auth, branch = 'master') { 517 return __awaiter(this, void 0, void 0, function* () { 518 let releases = []; 519 const treeUrl = `https://api.github.com/repos/${owner}/${repo}/git/trees/${branch}`; 520 const http = new httpm.HttpClient('tool-cache'); 521 const headers = {}; 522 if (auth) { 523 core.debug('set auth'); 524 headers.authorization = auth; 525 } 526 const response = yield http.getJson(treeUrl, headers); 527 if (!response.result) { 528 return releases; 529 } 530 let manifestUrl = ''; 531 for (const item of response.result.tree) { 532 if (item.path === 'versions-manifest.json') { 533 manifestUrl = item.url; 534 break; 535 } 536 } 537 headers['accept'] = 'application/vnd.github.VERSION.raw'; 538 let versionsRaw = yield (yield http.get(manifestUrl, headers)).readBody(); 539 if (versionsRaw) { 540 // shouldn't be needed but protects against invalid json saved with BOM 541 versionsRaw = versionsRaw.replace(/^\uFEFF/, ''); 542 try { 543 releases = JSON.parse(versionsRaw); 544 } 545 catch (_a) { 546 core.debug('Invalid json'); 547 } 548 } 549 return releases; 550 }); 551 } 552 exports.getManifestFromRepo = getManifestFromRepo; 553 function findFromManifest(versionSpec, stable, manifest, archFilter = os.arch()) { 554 return __awaiter(this, void 0, void 0, function* () { 555 // wrap the internal impl 556 const match = yield mm._findMatch(versionSpec, stable, manifest, archFilter); 557 return match; 558 }); 559 } 560 exports.findFromManifest = findFromManifest; 561 function _createExtractFolder(dest) { 562 return __awaiter(this, void 0, void 0, function* () { 563 if (!dest) { 564 // create a temp dir 565 dest = path.join(_getTempDirectory(), v4_1.default()); 566 } 567 yield io.mkdirP(dest); 568 return dest; 569 }); 570 } 571 function _createToolPath(tool, version, arch) { 572 return __awaiter(this, void 0, void 0, function* () { 573 const folderPath = path.join(_getCacheDirectory(), tool, semver.clean(version) || version, arch || ''); 574 core.debug(`destination ${folderPath}`); 575 const markerPath = `${folderPath}.complete`; 576 yield io.rmRF(folderPath); 577 yield io.rmRF(markerPath); 578 yield io.mkdirP(folderPath); 579 return folderPath; 580 }); 581 } 582 function _completeToolPath(tool, version, arch) { 583 const folderPath = path.join(_getCacheDirectory(), tool, semver.clean(version) || version, arch || ''); 584 const markerPath = `${folderPath}.complete`; 585 fs.writeFileSync(markerPath, ''); 586 core.debug('finished caching tool'); 587 } 588 /** 589 * Check if version string is explicit 590 * 591 * @param versionSpec version string to check 592 */ 593 function isExplicitVersion(versionSpec) { 594 const c = semver.clean(versionSpec) || ''; 595 core.debug(`isExplicit: ${c}`); 596 const valid = semver.valid(c) != null; 597 core.debug(`explicit? ${valid}`); 598 return valid; 599 } 600 exports.isExplicitVersion = isExplicitVersion; 601 /** 602 * Get the highest satisfiying semantic version in `versions` which satisfies `versionSpec` 603 * 604 * @param versions array of versions to evaluate 605 * @param versionSpec semantic version spec to satisfy 606 */ 607 function evaluateVersions(versions, versionSpec) { 608 let version = ''; 609 core.debug(`evaluating ${versions.length} versions`); 610 versions = versions.sort((a, b) => { 611 if (semver.gt(a, b)) { 612 return 1; 613 } 614 return -1; 615 }); 616 for (let i = versions.length - 1; i >= 0; i--) { 617 const potential = versions[i]; 618 const satisfied = semver.satisfies(potential, versionSpec); 619 if (satisfied) { 620 version = potential; 621 break; 622 } 623 } 624 if (version) { 625 core.debug(`matched: ${version}`); 626 } 627 else { 628 core.debug('match not found'); 629 } 630 return version; 631 } 632 exports.evaluateVersions = evaluateVersions; 633 /** 634 * Gets RUNNER_TOOL_CACHE 635 */ 636 function _getCacheDirectory() { 637 const cacheDirectory = process.env['RUNNER_TOOL_CACHE'] || ''; 638 assert_1.ok(cacheDirectory, 'Expected RUNNER_TOOL_CACHE to be defined'); 639 return cacheDirectory; 640 } 641 /** 642 * Gets RUNNER_TEMP 643 */ 644 function _getTempDirectory() { 645 const tempDirectory = process.env['RUNNER_TEMP'] || ''; 646 assert_1.ok(tempDirectory, 'Expected RUNNER_TEMP to be defined'); 647 return tempDirectory; 648 } 649 /** 650 * Gets a global variable 651 */ 652 function _getGlobal(key, defaultValue) { 653 /* eslint-disable @typescript-eslint/no-explicit-any */ 654 const value = global[key]; 655 /* eslint-enable @typescript-eslint/no-explicit-any */ 656 return value !== undefined ? value : defaultValue; 657 } 658 /** 659 * Returns an array of unique values. 660 * @param values Values to make unique. 661 */ 662 function _unique(values) { 663 return Array.from(new Set(values)); 664 } 665 //# sourceMappingURL=tool-cache.js.map