diff --git a/src/cmake/cmake.ts b/src/cmake/cmake.ts index 60e557b0..c4301df7 100644 --- a/src/cmake/cmake.ts +++ b/src/cmake/cmake.ts @@ -1,21 +1,8 @@ -import { extractZip, extractTar, find, downloadTool, cacheDir } from "@actions/tool-cache" -import { getInput, addPath, group, startGroup, endGroup } from "@actions/core" -import { join, basename } from "path" -import { existsSync } from "fs" +import { extractZip, extractTar } from "@actions/tool-cache" +import { getInput } from "@actions/core" import semverLte from "semver/functions/lte" import semverCoerce from "semver/functions/coerce" -import * as hasha from "hasha" -import { tmpdir } from "os" -import { URL } from "url" - -interface PackageInfo { - url: string - binRelativePath: string - extractFunction: { - (url: string, outputPath: string): Promise - } - dropSuffix: string -} +import { setupBin, PackageInfo } from "../utils/setup/setup" /** Get the platform data for cmake */ function getCmakePlatformData(version: string, platform?: NodeJS.Platform): PackageInfo { @@ -32,7 +19,7 @@ function getCmakePlatformData(version: string, platform?: NodeJS.Platform): Pack osArchStr = isOld ? "win64-x64" : "windows-x86_64" } return { - binRelativePath: "bin/", + binRelativeDir: "bin/", dropSuffix: ".zip", extractFunction: extractZip, url: `https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}-${osArchStr}.zip`, @@ -42,7 +29,7 @@ function getCmakePlatformData(version: string, platform?: NodeJS.Platform): Pack const isOld = semverLte(semVersion, "v3.19.1") const osArchStr = isOld ? "Darwin-x86_64" : "macos-universal" return { - binRelativePath: "CMake.app/Contents/bin/", + binRelativeDir: "CMake.app/Contents/bin/", dropSuffix: ".tar.gz", extractFunction: extractTar, url: `https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}-${osArchStr}.tar.gz`, @@ -57,7 +44,7 @@ function getCmakePlatformData(version: string, platform?: NodeJS.Platform): Pack osArchStr = isOld ? "Linux-x86_64" : "linux-x86_64" } return { - binRelativePath: "bin/", + binRelativeDir: "bin/", dropSuffix: ".tar.gz", extractFunction: extractTar, url: `https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}-${osArchStr}.tar.gz`, @@ -69,44 +56,6 @@ function getCmakePlatformData(version: string, platform?: NodeJS.Platform): Pack } /** Setup cmake */ -export async function setupCmake(version: string): Promise { - // Build artifact name - const cmakeBin = process.platform === "win32" ? "cmake.exe" : "cmake" - - // Restore from cache (if found). - const cmakeDir = find("cmake", version) - if (cmakeDir) { - addPath(cmakeDir) - return join(cmakeDir, cmakeBin) - } - - const { url, dropSuffix, binRelativePath: binPath, extractFunction } = getCmakePlatformData(version, process.platform) - - // Get an unique output directory name from the URL. - const key: string = await hasha.async(url) - const finalDir = join(process.env.RUNNER_TEMP ?? tmpdir(), key) - - const { pathname } = new URL(url) - const dirName = basename(pathname) - const finalPath = join(finalDir, dirName.replace(dropSuffix, ""), binPath) - - const finalBinPath = join(finalPath, cmakeBin) - - if (!existsSync(finalDir)) { - await group("Download and extract CMake", async () => { - const downloaded = await downloadTool(url) - await extractFunction(downloaded, finalDir) - }) - } - - try { - startGroup(`Add CMake to PATH`) - addPath(finalPath) - } finally { - endGroup() - } - - await cacheDir(finalDir, "cmake", version) - - return finalBinPath +export function setupCmake(version: string): Promise { + return setupBin("cmake", version, getCmakePlatformData) } diff --git a/src/utils/setup/setup.ts b/src/utils/setup/setup.ts new file mode 100644 index 00000000..dc3341c5 --- /dev/null +++ b/src/utils/setup/setup.ts @@ -0,0 +1,63 @@ +import { find, downloadTool, cacheDir } from "@actions/tool-cache" +import { addPath, group, startGroup, endGroup } from "@actions/core" +import { join, basename } from "path" +import { existsSync } from "fs" +import * as hasha from "hasha" +import { tmpdir } from "os" +import { URL } from "url" + +export type PackageInfo = { + url: string + binRelativeDir: string + extractFunction: { + (url: string, outputPath: string): Promise + } + dropSuffix: string +} + +/** A function that downloads and installs a tool. Then it caches it in the tool-cache. */ +export async function setupBin( + name: string, + version: string, + getPlatformData: (version: string, platform: NodeJS.Platform) => PackageInfo +): Promise { + // Build artifact name + const binName = process.platform === "win32" ? `${name}.exe` : name + + // Restore from cache (if found). + const dir = find(name, version) + if (dir) { + addPath(dir) + return join(dir, binName) + } + + const { url, dropSuffix, binRelativeDir: binRelativePath, extractFunction } = getPlatformData(version, process.platform) + + // Get an unique output directory name from the URL. + const key: string = await hasha.async(url) + const workDir = join(process.env.RUNNER_TEMP ?? tmpdir(), key) + + const { pathname } = new URL(url) + const dirName = basename(pathname) + + /** The directory which the tool is installed to */ + const binDir = join(workDir, dirName.replace(dropSuffix, ""), binRelativePath) + + if (!existsSync(workDir)) { + await group(`Download and extract ${name}`, async () => { + const downloaded = await downloadTool(url) + await extractFunction(downloaded, workDir) + }) + } + + try { + startGroup(`Add ${name} to PATH`) + addPath(binDir) + } finally { + endGroup() + } + + await cacheDir(workDir, name, version) + + return join(binDir, binName) +}