Permalink
Cannot retrieve contributors at this time
665 lines (665 sloc)
25.9 KB
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
codeql-action/node_modules/@actions/tool-cache/lib/tool-cache.js
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"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()); | |
}); | |
}; | |
var __importDefault = (this && this.__importDefault) || function (mod) { | |
return (mod && mod.__esModule) ? mod : { "default": mod }; | |
}; | |
Object.defineProperty(exports, "__esModule", { value: true }); | |
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; | |
const core = __importStar(require("@actions/core")); | |
const io = __importStar(require("@actions/io")); | |
const fs = __importStar(require("fs")); | |
const mm = __importStar(require("./manifest")); | |
const os = __importStar(require("os")); | |
const path = __importStar(require("path")); | |
const httpm = __importStar(require("@actions/http-client")); | |
const semver = __importStar(require("semver")); | |
const stream = __importStar(require("stream")); | |
const util = __importStar(require("util")); | |
const assert_1 = require("assert"); | |
const v4_1 = __importDefault(require("uuid/v4")); | |
const exec_1 = require("@actions/exec/lib/exec"); | |
const retry_helper_1 = require("./retry-helper"); | |
class HTTPError extends Error { | |
constructor(httpStatusCode) { | |
super(`Unexpected HTTP response: ${httpStatusCode}`); | |
this.httpStatusCode = httpStatusCode; | |
Object.setPrototypeOf(this, new.target.prototype); | |
} | |
} | |
exports.HTTPError = HTTPError; | |
const IS_WINDOWS = process.platform === 'win32'; | |
const IS_MAC = process.platform === 'darwin'; | |
const userAgent = 'actions/tool-cache'; | |
/** | |
* Download a tool from an url and stream it into a file | |
* | |
* @param url url of tool to download | |
* @param dest path to download tool | |
* @param auth authorization header | |
* @param headers other headers | |
* @returns path to downloaded tool | |
*/ | |
function downloadTool(url, dest, auth, headers) { | |
return __awaiter(this, void 0, void 0, function* () { | |
dest = dest || path.join(_getTempDirectory(), v4_1.default()); | |
yield io.mkdirP(path.dirname(dest)); | |
core.debug(`Downloading ${url}`); | |
core.debug(`Destination ${dest}`); | |
const maxAttempts = 3; | |
const minSeconds = _getGlobal('TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS', 10); | |
const maxSeconds = _getGlobal('TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS', 20); | |
const retryHelper = new retry_helper_1.RetryHelper(maxAttempts, minSeconds, maxSeconds); | |
return yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () { | |
return yield downloadToolAttempt(url, dest || '', auth, headers); | |
}), (err) => { | |
if (err instanceof HTTPError && err.httpStatusCode) { | |
// Don't retry anything less than 500, except 408 Request Timeout and 429 Too Many Requests | |
if (err.httpStatusCode < 500 && | |
err.httpStatusCode !== 408 && | |
err.httpStatusCode !== 429) { | |
return false; | |
} | |
} | |
// Otherwise retry | |
return true; | |
}); | |
}); | |
} | |
exports.downloadTool = downloadTool; | |
function downloadToolAttempt(url, dest, auth, headers) { | |
return __awaiter(this, void 0, void 0, function* () { | |
if (fs.existsSync(dest)) { | |
throw new Error(`Destination file path ${dest} already exists`); | |
} | |
// Get the response headers | |
const http = new httpm.HttpClient(userAgent, [], { | |
allowRetries: false | |
}); | |
if (auth) { | |
core.debug('set auth'); | |
if (headers === undefined) { | |
headers = {}; | |
} | |
headers.authorization = auth; | |
} | |
const response = yield http.get(url, headers); | |
if (response.message.statusCode !== 200) { | |
const err = new HTTPError(response.message.statusCode); | |
core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); | |
throw err; | |
} | |
// Download the response body | |
const pipeline = util.promisify(stream.pipeline); | |
const responseMessageFactory = _getGlobal('TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY', () => response.message); | |
const readStream = responseMessageFactory(); | |
let succeeded = false; | |
try { | |
yield pipeline(readStream, fs.createWriteStream(dest)); | |
core.debug('download complete'); | |
succeeded = true; | |
return dest; | |
} | |
finally { | |
// Error, delete dest before retry | |
if (!succeeded) { | |
core.debug('download failed'); | |
try { | |
yield io.rmRF(dest); | |
} | |
catch (err) { | |
core.debug(`Failed to delete '${dest}'. ${err.message}`); | |
} | |
} | |
} | |
}); | |
} | |
/** | |
* Extract a .7z file | |
* | |
* @param file path to the .7z file | |
* @param dest destination directory. Optional. | |
* @param _7zPath path to 7zr.exe. Optional, for long path support. Most .7z archives do not have this | |
* problem. If your .7z archive contains very long paths, you can pass the path to 7zr.exe which will | |
* gracefully handle long paths. By default 7zdec.exe is used because it is a very small program and is | |
* bundled with the tool lib. However it does not support long paths. 7zr.exe is the reduced command line | |
* interface, it is smaller than the full command line interface, and it does support long paths. At the | |
* time of this writing, it is freely available from the LZMA SDK that is available on the 7zip website. | |
* Be sure to check the current license agreement. If 7zr.exe is bundled with your action, then the path | |
* to 7zr.exe can be pass to this function. | |
* @returns path to the destination directory | |
*/ | |
function extract7z(file, dest, _7zPath) { | |
return __awaiter(this, void 0, void 0, function* () { | |
assert_1.ok(IS_WINDOWS, 'extract7z() not supported on current OS'); | |
assert_1.ok(file, 'parameter "file" is required'); | |
dest = yield _createExtractFolder(dest); | |
const originalCwd = process.cwd(); | |
process.chdir(dest); | |
if (_7zPath) { | |
try { | |
const logLevel = core.isDebug() ? '-bb1' : '-bb0'; | |
const args = [ | |
'x', | |
logLevel, | |
'-bd', | |
'-sccUTF-8', | |
file | |
]; | |
const options = { | |
silent: true | |
}; | |
yield exec_1.exec(`"${_7zPath}"`, args, options); | |
} | |
finally { | |
process.chdir(originalCwd); | |
} | |
} | |
else { | |
const escapedScript = path | |
.join(__dirname, '..', 'scripts', 'Invoke-7zdec.ps1') | |
.replace(/'/g, "''") | |
.replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines | |
const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); | |
const escapedTarget = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); | |
const command = `& '${escapedScript}' -Source '${escapedFile}' -Target '${escapedTarget}'`; | |
const args = [ | |
'-NoLogo', | |
'-Sta', | |
'-NoProfile', | |
'-NonInteractive', | |
'-ExecutionPolicy', | |
'Unrestricted', | |
'-Command', | |
command | |
]; | |
const options = { | |
silent: true | |
}; | |
try { | |
const powershellPath = yield io.which('powershell', true); | |
yield exec_1.exec(`"${powershellPath}"`, args, options); | |
} | |
finally { | |
process.chdir(originalCwd); | |
} | |
} | |
return dest; | |
}); | |
} | |
exports.extract7z = extract7z; | |
/** | |
* Extract a compressed tar archive | |
* | |
* @param file path to the tar | |
* @param dest destination directory. Optional. | |
* @param flags flags for the tar command to use for extraction. Defaults to 'xz' (extracting gzipped tars). Optional. | |
* @returns path to the destination directory | |
*/ | |
function extractTar(file, dest, flags = 'xz') { | |
return __awaiter(this, void 0, void 0, function* () { | |
if (!file) { | |
throw new Error("parameter 'file' is required"); | |
} | |
// Create dest | |
dest = yield _createExtractFolder(dest); | |
// Determine whether GNU tar | |
core.debug('Checking tar --version'); | |
let versionOutput = ''; | |
yield exec_1.exec('tar --version', [], { | |
ignoreReturnCode: true, | |
silent: true, | |
listeners: { | |
stdout: (data) => (versionOutput += data.toString()), | |
stderr: (data) => (versionOutput += data.toString()) | |
} | |
}); | |
core.debug(versionOutput.trim()); | |
const isGnuTar = versionOutput.toUpperCase().includes('GNU TAR'); | |
// Initialize args | |
let args; | |
if (flags instanceof Array) { | |
args = flags; | |
} | |
else { | |
args = [flags]; | |
} | |
if (core.isDebug() && !flags.includes('v')) { | |
args.push('-v'); | |
} | |
let destArg = dest; | |
let fileArg = file; | |
if (IS_WINDOWS && isGnuTar) { | |
args.push('--force-local'); | |
destArg = dest.replace(/\\/g, '/'); | |
// Technically only the dest needs to have `/` but for aesthetic consistency | |
// convert slashes in the file arg too. | |
fileArg = file.replace(/\\/g, '/'); | |
} | |
if (isGnuTar) { | |
// Suppress warnings when using GNU tar to extract archives created by BSD tar | |
args.push('--warning=no-unknown-keyword'); | |
args.push('--overwrite'); | |
} | |
args.push('-C', destArg, '-f', fileArg); | |
yield exec_1.exec(`tar`, args); | |
return dest; | |
}); | |
} | |
exports.extractTar = extractTar; | |
/** | |
* Extract a xar compatible archive | |
* | |
* @param file path to the archive | |
* @param dest destination directory. Optional. | |
* @param flags flags for the xar. Optional. | |
* @returns path to the destination directory | |
*/ | |
function extractXar(file, dest, flags = []) { | |
return __awaiter(this, void 0, void 0, function* () { | |
assert_1.ok(IS_MAC, 'extractXar() not supported on current OS'); | |
assert_1.ok(file, 'parameter "file" is required'); | |
dest = yield _createExtractFolder(dest); | |
let args; | |
if (flags instanceof Array) { | |
args = flags; | |
} | |
else { | |
args = [flags]; | |
} | |
args.push('-x', '-C', dest, '-f', file); | |
if (core.isDebug()) { | |
args.push('-v'); | |
} | |
const xarPath = yield io.which('xar', true); | |
yield exec_1.exec(`"${xarPath}"`, _unique(args)); | |
return dest; | |
}); | |
} | |
exports.extractXar = extractXar; | |
/** | |
* Extract a zip | |
* | |
* @param file path to the zip | |
* @param dest destination directory. Optional. | |
* @returns path to the destination directory | |
*/ | |
function extractZip(file, dest) { | |
return __awaiter(this, void 0, void 0, function* () { | |
if (!file) { | |
throw new Error("parameter 'file' is required"); | |
} | |
dest = yield _createExtractFolder(dest); | |
if (IS_WINDOWS) { | |
yield extractZipWin(file, dest); | |
} | |
else { | |
yield extractZipNix(file, dest); | |
} | |
return dest; | |
}); | |
} | |
exports.extractZip = extractZip; | |
function extractZipWin(file, dest) { | |
return __awaiter(this, void 0, void 0, function* () { | |
// build the powershell command | |
const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines | |
const escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); | |
const pwshPath = yield io.which('pwsh', false); | |
//To match the file overwrite behavior on nix systems, we use the overwrite = true flag for ExtractToDirectory | |
//and the -Force flag for Expand-Archive as a fallback | |
if (pwshPath) { | |
//attempt to use pwsh with ExtractToDirectory, if this fails attempt Expand-Archive | |
const pwshCommand = [ | |
`$ErrorActionPreference = 'Stop' ;`, | |
`try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`, | |
`try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) }`, | |
`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 $_ } } ;` | |
].join(' '); | |
const args = [ | |
'-NoLogo', | |
'-NoProfile', | |
'-NonInteractive', | |
'-ExecutionPolicy', | |
'Unrestricted', | |
'-Command', | |
pwshCommand | |
]; | |
core.debug(`Using pwsh at path: ${pwshPath}`); | |
yield exec_1.exec(`"${pwshPath}"`, args); | |
} | |
else { | |
const powershellCommand = [ | |
`$ErrorActionPreference = 'Stop' ;`, | |
`try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ;`, | |
`if ((Get-Command -Name Expand-Archive -Module Microsoft.PowerShell.Archive -ErrorAction Ignore)) { Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force }`, | |
`else {[System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) }` | |
].join(' '); | |
const args = [ | |
'-NoLogo', | |
'-Sta', | |
'-NoProfile', | |
'-NonInteractive', | |
'-ExecutionPolicy', | |
'Unrestricted', | |
'-Command', | |
powershellCommand | |
]; | |
const powershellPath = yield io.which('powershell', true); | |
core.debug(`Using powershell at path: ${powershellPath}`); | |
yield exec_1.exec(`"${powershellPath}"`, args); | |
} | |
}); | |
} | |
function extractZipNix(file, dest) { | |
return __awaiter(this, void 0, void 0, function* () { | |
const unzipPath = yield io.which('unzip', true); | |
const args = [file]; | |
if (!core.isDebug()) { | |
args.unshift('-q'); | |
} | |
args.unshift('-o'); //overwrite with -o, otherwise a prompt is shown which freezes the run | |
yield exec_1.exec(`"${unzipPath}"`, args, { cwd: dest }); | |
}); | |
} | |
/** | |
* Caches a directory and installs it into the tool cacheDir | |
* | |
* @param sourceDir the directory to cache into tools | |
* @param tool tool name | |
* @param version version of the tool. semver format | |
* @param arch architecture of the tool. Optional. Defaults to machine architecture | |
*/ | |
function cacheDir(sourceDir, tool, version, arch) { | |
return __awaiter(this, void 0, void 0, function* () { | |
version = semver.clean(version) || version; | |
arch = arch || os.arch(); | |
core.debug(`Caching tool ${tool} ${version} ${arch}`); | |
core.debug(`source dir: ${sourceDir}`); | |
if (!fs.statSync(sourceDir).isDirectory()) { | |
throw new Error('sourceDir is not a directory'); | |
} | |
// Create the tool dir | |
const destPath = yield _createToolPath(tool, version, arch); | |
// copy each child item. do not move. move can fail on Windows | |
// due to anti-virus software having an open handle on a file. | |
for (const itemName of fs.readdirSync(sourceDir)) { | |
const s = path.join(sourceDir, itemName); | |
yield io.cp(s, destPath, { recursive: true }); | |
} | |
// write .complete | |
_completeToolPath(tool, version, arch); | |
return destPath; | |
}); | |
} | |
exports.cacheDir = cacheDir; | |
/** | |
* Caches a downloaded file (GUID) and installs it | |
* into the tool cache with a given targetName | |
* | |
* @param sourceFile the file to cache into tools. Typically a result of downloadTool which is a guid. | |
* @param targetFile the name of the file name in the tools directory | |
* @param tool tool name | |
* @param version version of the tool. semver format | |
* @param arch architecture of the tool. Optional. Defaults to machine architecture | |
*/ | |
function cacheFile(sourceFile, targetFile, tool, version, arch) { | |
return __awaiter(this, void 0, void 0, function* () { | |
version = semver.clean(version) || version; | |
arch = arch || os.arch(); | |
core.debug(`Caching tool ${tool} ${version} ${arch}`); | |
core.debug(`source file: ${sourceFile}`); | |
if (!fs.statSync(sourceFile).isFile()) { | |
throw new Error('sourceFile is not a file'); | |
} | |
// create the tool dir | |
const destFolder = yield _createToolPath(tool, version, arch); | |
// copy instead of move. move can fail on Windows due to | |
// anti-virus software having an open handle on a file. | |
const destPath = path.join(destFolder, targetFile); | |
core.debug(`destination file ${destPath}`); | |
yield io.cp(sourceFile, destPath); | |
// write .complete | |
_completeToolPath(tool, version, arch); | |
return destFolder; | |
}); | |
} | |
exports.cacheFile = cacheFile; | |
/** | |
* Finds the path to a tool version in the local installed tool cache | |
* | |
* @param toolName name of the tool | |
* @param versionSpec version of the tool | |
* @param arch optional arch. defaults to arch of computer | |
*/ | |
function find(toolName, versionSpec, arch) { | |
if (!toolName) { | |
throw new Error('toolName parameter is required'); | |
} | |
if (!versionSpec) { | |
throw new Error('versionSpec parameter is required'); | |
} | |
arch = arch || os.arch(); | |
// attempt to resolve an explicit version | |
if (!isExplicitVersion(versionSpec)) { | |
const localVersions = findAllVersions(toolName, arch); | |
const match = evaluateVersions(localVersions, versionSpec); | |
versionSpec = match; | |
} | |
// check for the explicit version in the cache | |
let toolPath = ''; | |
if (versionSpec) { | |
versionSpec = semver.clean(versionSpec) || ''; | |
const cachePath = path.join(_getCacheDirectory(), toolName, versionSpec, arch); | |
core.debug(`checking cache: ${cachePath}`); | |
if (fs.existsSync(cachePath) && fs.existsSync(`${cachePath}.complete`)) { | |
core.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`); | |
toolPath = cachePath; | |
} | |
else { | |
core.debug('not found'); | |
} | |
} | |
return toolPath; | |
} | |
exports.find = find; | |
/** | |
* Finds the paths to all versions of a tool that are installed in the local tool cache | |
* | |
* @param toolName name of the tool | |
* @param arch optional arch. defaults to arch of computer | |
*/ | |
function findAllVersions(toolName, arch) { | |
const versions = []; | |
arch = arch || os.arch(); | |
const toolPath = path.join(_getCacheDirectory(), toolName); | |
if (fs.existsSync(toolPath)) { | |
const children = fs.readdirSync(toolPath); | |
for (const child of children) { | |
if (isExplicitVersion(child)) { | |
const fullPath = path.join(toolPath, child, arch || ''); | |
if (fs.existsSync(fullPath) && fs.existsSync(`${fullPath}.complete`)) { | |
versions.push(child); | |
} | |
} | |
} | |
} | |
return versions; | |
} | |
exports.findAllVersions = findAllVersions; | |
function getManifestFromRepo(owner, repo, auth, branch = 'master') { | |
return __awaiter(this, void 0, void 0, function* () { | |
let releases = []; | |
const treeUrl = `https://api.github.com/repos/${owner}/${repo}/git/trees/${branch}`; | |
const http = new httpm.HttpClient('tool-cache'); | |
const headers = {}; | |
if (auth) { | |
core.debug('set auth'); | |
headers.authorization = auth; | |
} | |
const response = yield http.getJson(treeUrl, headers); | |
if (!response.result) { | |
return releases; | |
} | |
let manifestUrl = ''; | |
for (const item of response.result.tree) { | |
if (item.path === 'versions-manifest.json') { | |
manifestUrl = item.url; | |
break; | |
} | |
} | |
headers['accept'] = 'application/vnd.github.VERSION.raw'; | |
let versionsRaw = yield (yield http.get(manifestUrl, headers)).readBody(); | |
if (versionsRaw) { | |
// shouldn't be needed but protects against invalid json saved with BOM | |
versionsRaw = versionsRaw.replace(/^\uFEFF/, ''); | |
try { | |
releases = JSON.parse(versionsRaw); | |
} | |
catch (_a) { | |
core.debug('Invalid json'); | |
} | |
} | |
return releases; | |
}); | |
} | |
exports.getManifestFromRepo = getManifestFromRepo; | |
function findFromManifest(versionSpec, stable, manifest, archFilter = os.arch()) { | |
return __awaiter(this, void 0, void 0, function* () { | |
// wrap the internal impl | |
const match = yield mm._findMatch(versionSpec, stable, manifest, archFilter); | |
return match; | |
}); | |
} | |
exports.findFromManifest = findFromManifest; | |
function _createExtractFolder(dest) { | |
return __awaiter(this, void 0, void 0, function* () { | |
if (!dest) { | |
// create a temp dir | |
dest = path.join(_getTempDirectory(), v4_1.default()); | |
} | |
yield io.mkdirP(dest); | |
return dest; | |
}); | |
} | |
function _createToolPath(tool, version, arch) { | |
return __awaiter(this, void 0, void 0, function* () { | |
const folderPath = path.join(_getCacheDirectory(), tool, semver.clean(version) || version, arch || ''); | |
core.debug(`destination ${folderPath}`); | |
const markerPath = `${folderPath}.complete`; | |
yield io.rmRF(folderPath); | |
yield io.rmRF(markerPath); | |
yield io.mkdirP(folderPath); | |
return folderPath; | |
}); | |
} | |
function _completeToolPath(tool, version, arch) { | |
const folderPath = path.join(_getCacheDirectory(), tool, semver.clean(version) || version, arch || ''); | |
const markerPath = `${folderPath}.complete`; | |
fs.writeFileSync(markerPath, ''); | |
core.debug('finished caching tool'); | |
} | |
/** | |
* Check if version string is explicit | |
* | |
* @param versionSpec version string to check | |
*/ | |
function isExplicitVersion(versionSpec) { | |
const c = semver.clean(versionSpec) || ''; | |
core.debug(`isExplicit: ${c}`); | |
const valid = semver.valid(c) != null; | |
core.debug(`explicit? ${valid}`); | |
return valid; | |
} | |
exports.isExplicitVersion = isExplicitVersion; | |
/** | |
* Get the highest satisfiying semantic version in `versions` which satisfies `versionSpec` | |
* | |
* @param versions array of versions to evaluate | |
* @param versionSpec semantic version spec to satisfy | |
*/ | |
function evaluateVersions(versions, versionSpec) { | |
let version = ''; | |
core.debug(`evaluating ${versions.length} versions`); | |
versions = versions.sort((a, b) => { | |
if (semver.gt(a, b)) { | |
return 1; | |
} | |
return -1; | |
}); | |
for (let i = versions.length - 1; i >= 0; i--) { | |
const potential = versions[i]; | |
const satisfied = semver.satisfies(potential, versionSpec); | |
if (satisfied) { | |
version = potential; | |
break; | |
} | |
} | |
if (version) { | |
core.debug(`matched: ${version}`); | |
} | |
else { | |
core.debug('match not found'); | |
} | |
return version; | |
} | |
exports.evaluateVersions = evaluateVersions; | |
/** | |
* Gets RUNNER_TOOL_CACHE | |
*/ | |
function _getCacheDirectory() { | |
const cacheDirectory = process.env['RUNNER_TOOL_CACHE'] || ''; | |
assert_1.ok(cacheDirectory, 'Expected RUNNER_TOOL_CACHE to be defined'); | |
return cacheDirectory; | |
} | |
/** | |
* Gets RUNNER_TEMP | |
*/ | |
function _getTempDirectory() { | |
const tempDirectory = process.env['RUNNER_TEMP'] || ''; | |
assert_1.ok(tempDirectory, 'Expected RUNNER_TEMP to be defined'); | |
return tempDirectory; | |
} | |
/** | |
* Gets a global variable | |
*/ | |
function _getGlobal(key, defaultValue) { | |
/* eslint-disable @typescript-eslint/no-explicit-any */ | |
const value = global[key]; | |
/* eslint-enable @typescript-eslint/no-explicit-any */ | |
return value !== undefined ? value : defaultValue; | |
} | |
/** | |
* Returns an array of unique values. | |
* @param values Values to make unique. | |
*/ | |
function _unique(values) { | |
return Array.from(new Set(values)); | |
} | |
//# sourceMappingURL=tool-cache.js.map |