-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Only try zstd for specified version ranges of tar
- Loading branch information
Henry Mercer
committed
Aug 29, 2024
1 parent
cf64c3e
commit ffa1b05
Showing
6 changed files
with
201 additions
and
48 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| import { ToolRunner } from "@actions/exec/lib/toolrunner"; | ||
| import * as toolcache from "@actions/tool-cache"; | ||
| import { safeWhich } from "@chrisgavin/safe-which"; | ||
|
|
||
| import { Logger } from "./logging"; | ||
| import { assertNever } from "./util"; | ||
|
|
||
| const MIN_REQUIRED_BSD_TAR_VERSION = "3.4.3"; | ||
| const MIN_REQUIRED_GNU_TAR_VERSION = "1.31"; | ||
|
|
||
| type TarVersion = { | ||
| type: "gnu" | "bsd"; | ||
| version: string; | ||
| }; | ||
|
|
||
| async function getTarVersion(): Promise<TarVersion> { | ||
| const tar = await safeWhich("tar"); | ||
| let stdout = ""; | ||
| const exitCode = await new ToolRunner(tar, ["--version"], { | ||
| listeners: { | ||
| stdout: (data: Buffer) => { | ||
| stdout += data.toString(); | ||
| }, | ||
| }, | ||
| }).exec(); | ||
| if (exitCode !== 0) { | ||
| throw new Error("Failed to call tar --version"); | ||
| } | ||
| // Return whether this is GNU tar or BSD tar, and the version number | ||
| if (stdout.includes("GNU tar")) { | ||
| const match = stdout.match(/tar \(GNU tar\) ([0-9.]+)/); | ||
| if (!match || !match[1]) { | ||
| throw new Error("Failed to parse output of tar --version."); | ||
| } | ||
|
|
||
| return { type: "gnu", version: match[1] }; | ||
| } else if (stdout.includes("bsdtar")) { | ||
| const match = stdout.match(/bsdtar ([0-9.]+)/); | ||
| if (!match || !match[1]) { | ||
| throw new Error("Failed to parse output of tar --version."); | ||
| } | ||
|
|
||
| return { type: "bsd", version: match[1] }; | ||
| } else { | ||
| throw new Error("Unknown tar version"); | ||
| } | ||
| } | ||
|
|
||
| export async function isZstdAvailable(logger: Logger): Promise<boolean> { | ||
| try { | ||
| const { type, version } = await getTarVersion(); | ||
| logger.info(`Found ${type} tar version ${version}.`); | ||
| switch (type) { | ||
| case "gnu": | ||
| return version >= MIN_REQUIRED_GNU_TAR_VERSION; | ||
| case "bsd": | ||
| return version >= MIN_REQUIRED_BSD_TAR_VERSION; | ||
| default: | ||
| assertNever(type); | ||
| } | ||
| } catch (e) { | ||
| logger.error( | ||
| "Failed to determine tar version, therefore will assume zstd may not be available. " + | ||
| `The underlying error was: ${e}`, | ||
| ); | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| export type CompressionMethod = "gzip" | "zstd"; | ||
|
|
||
| export async function extract(path: string): Promise<{ | ||
| compressionMethod: CompressionMethod; | ||
| outputPath: string; | ||
| }> { | ||
| if (path.endsWith(".tar.gz")) { | ||
| return { | ||
| compressionMethod: "gzip", | ||
| // While we could also ask tar to autodetect the compression method, | ||
| // we defensively keep the gzip call identical as requesting a gzipped | ||
| // bundle will soon be a fallback option. | ||
| outputPath: await toolcache.extractTar(path), | ||
| }; | ||
| } | ||
| return { | ||
| compressionMethod: "zstd", | ||
| // By specifying only the "x" flag, we ask tar to autodetect the compression | ||
| // method. | ||
| outputPath: await toolcache.extractTar(path, undefined, "x"), | ||
| }; | ||
| } |