setup-cpp/src/utils/setup/setupBin.ts

78 lines
2.5 KiB
TypeScript
Raw Normal View History

import { find, downloadTool, cacheDir } from "@actions/tool-cache"
import { addPath, group, startGroup, endGroup, info } from "@actions/core"
2021-09-14 17:23:38 +08:00
import { join } from "path"
import { existsSync } from "fs"
import * as hasha from "hasha"
2021-09-14 19:38:58 +08:00
import { tmpdir } from "os"
2021-09-14 17:26:33 +08:00
/** A type that describes a package */
export type PackageInfo = {
2021-09-14 17:27:55 +08:00
/** Url to download the package */
url: string
2021-09-14 17:26:33 +08:00
/** The top folder name once it is extracted. It can be `""` if there is no top folder */
2021-09-14 17:23:38 +08:00
extractedFolderName: string
2021-09-14 17:26:33 +08:00
/** The relative directory in which the binary is located. It can be `""` if the exe is in the top folder */
binRelativeDir: string
2021-09-14 17:27:55 +08:00
/** The function to extract the downloaded archive. It can be `undefined`, if the binary itself is downloaded directly. */
extractFunction?: {
(file: string, dest: string): Promise<string>
}
}
/**
* A function that:
*
* - Downlodas and extracts a package
* - Adds the bin path of the package to PATH
* - Caches the dowloaded directory into tool cache for usage from other sessions
*
* @returns The installation directory
*/
export async function setupPackage(
name: string,
version: string,
getPackageInfo: (version: string, platform: NodeJS.Platform) => PackageInfo | Promise<PackageInfo>,
setupCppDir: string
): Promise<string> {
2021-09-14 19:38:58 +08:00
process.env.RUNNER_TEMP = process.env.RUNNER_TEMP ?? tmpdir()
// Restore from cache (if found).
const dir = find(name, version)
if (dir) {
info(`${name} ${version} was found in the cache.`)
addPath(dir)
return dir
}
const { url, binRelativeDir, extractedFolderName, extractFunction } = await getPackageInfo(version, process.platform)
// Get an unique output directory name from the URL.
const key: string = await hasha.async(url)
const installDir = join(setupCppDir, key)
// download ane extract the package into the installation directory.
if (!existsSync(installDir)) {
await group(`Download and extract ${name} ${version}`, async () => {
const downloaded = await downloadTool(url)
await extractFunction?.(downloaded, installDir)
})
}
// Adding the bin dir to the path
try {
/** The directory which the tool is installed to */
const binDir = join(installDir, extractedFolderName, binRelativeDir)
startGroup(`Add ${binDir} to PATH`)
addPath(binDir)
} finally {
endGroup()
}
// check if inside Github Actions. If so, cache the installation
if (typeof process.env.RUNNER_TOOL_CACHE === "string") {
await cacheDir(installDir, name, version)
}
return installDir
}