255 lines
11 KiB
JavaScript
Raw Normal View History

2022-07-12 09:00:22 +02:00
"use strict";
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 __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const exec_1 = require("@actions/exec");
const io = __importStar(require("@actions/io"));
const fs_1 = require("fs");
const path = __importStar(require("path"));
const utils = __importStar(require("./cacheUtils"));
const constants_1 = require("./constants");
2022-10-29 10:03:51 +02:00
const IS_WINDOWS = process.platform === 'win32';
2023-02-22 17:47:24 -08:00
// Returns tar path and type: BSD or GNU
function getTarPath() {
2022-07-12 09:00:22 +02:00
return __awaiter(this, void 0, void 0, function* () {
switch (process.platform) {
case 'win32': {
2023-02-22 17:47:24 -08:00
const gnuTar = yield utils.getGnuTarPathOnWindows();
const systemTar = constants_1.SystemTarPathOnWindows;
if (gnuTar) {
// Use GNUtar as default on windows
return { path: gnuTar, type: constants_1.ArchiveToolType.GNU };
2022-07-12 09:00:22 +02:00
}
else if (fs_1.existsSync(systemTar)) {
2023-02-22 17:47:24 -08:00
return { path: systemTar, type: constants_1.ArchiveToolType.BSD };
2022-07-12 09:00:22 +02:00
}
break;
}
case 'darwin': {
const gnuTar = yield io.which('gtar', false);
if (gnuTar) {
// fix permission denied errors when extracting BSD tar archive with GNU tar - https://github.com/actions/cache/issues/527
2023-02-22 17:47:24 -08:00
return { path: gnuTar, type: constants_1.ArchiveToolType.GNU };
}
else {
return {
path: yield io.which('tar', true),
type: constants_1.ArchiveToolType.BSD
};
2022-07-12 09:00:22 +02:00
}
}
default:
break;
}
2023-02-22 17:47:24 -08:00
// Default assumption is GNU tar is present in path
return {
path: yield io.which('tar', true),
type: constants_1.ArchiveToolType.GNU
};
});
}
// Return arguments for tar as per tarPath, compressionMethod, method type and os
function getTarArgs(tarPath, compressionMethod, type, archivePath = '') {
return __awaiter(this, void 0, void 0, function* () {
const args = [`"${tarPath.path}"`];
const cacheFileName = utils.getCacheFileName(compressionMethod);
const tarFile = 'cache.tar';
const workingDirectory = getWorkingDirectory();
// Speficic args for BSD tar on windows for workaround
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
compressionMethod !== constants_1.CompressionMethod.Gzip &&
IS_WINDOWS;
// Method specific args
switch (type) {
case 'create':
args.push('--posix', '-cf', BSD_TAR_ZSTD
? tarFile
: cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '--exclude', BSD_TAR_ZSTD
? tarFile
: cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P', '-C', workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '--files-from', constants_1.ManifestFilename);
break;
case 'extract':
args.push('-xf', BSD_TAR_ZSTD
? tarFile
: archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P', '-C', workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'));
break;
case 'list':
args.push('-tf', BSD_TAR_ZSTD
? tarFile
: archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P');
break;
}
// Platform specific args
if (tarPath.type === constants_1.ArchiveToolType.GNU) {
switch (process.platform) {
case 'win32':
args.push('--force-local');
break;
case 'darwin':
args.push('--delay-directory-restore');
break;
}
}
return args;
2022-07-12 09:00:22 +02:00
});
}
2023-02-22 17:47:24 -08:00
// Returns commands to run tar and compression program
function getCommands(compressionMethod, type, archivePath = '') {
2022-07-12 09:00:22 +02:00
return __awaiter(this, void 0, void 0, function* () {
2023-02-22 17:47:24 -08:00
let args;
const tarPath = yield getTarPath();
const tarArgs = yield getTarArgs(tarPath, compressionMethod, type, archivePath);
const compressionArgs = type !== 'create'
? yield getDecompressionProgram(tarPath, compressionMethod, archivePath)
: yield getCompressionProgram(tarPath, compressionMethod);
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
compressionMethod !== constants_1.CompressionMethod.Gzip &&
IS_WINDOWS;
if (BSD_TAR_ZSTD && type !== 'create') {
args = [[...compressionArgs].join(' '), [...tarArgs].join(' ')];
2022-07-12 09:00:22 +02:00
}
2023-02-22 17:47:24 -08:00
else {
args = [[...tarArgs].join(' '), [...compressionArgs].join(' ')];
2022-07-12 09:00:22 +02:00
}
2023-02-22 17:47:24 -08:00
if (BSD_TAR_ZSTD) {
return args;
}
return [args.join(' ')];
2022-07-12 09:00:22 +02:00
});
}
function getWorkingDirectory() {
var _a;
return (_a = process.env['GITHUB_WORKSPACE']) !== null && _a !== void 0 ? _a : process.cwd();
}
2022-10-29 10:03:51 +02:00
// Common function for extractTar and listTar to get the compression method
2023-02-22 17:47:24 -08:00
function getDecompressionProgram(tarPath, compressionMethod, archivePath) {
return __awaiter(this, void 0, void 0, function* () {
// -d: Decompress.
// unzstd is equivalent to 'zstd -d'
// --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
// Using 30 here because we also support 32-bit self-hosted runners.
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
compressionMethod !== constants_1.CompressionMethod.Gzip &&
IS_WINDOWS;
switch (compressionMethod) {
case constants_1.CompressionMethod.Zstd:
return BSD_TAR_ZSTD
? [
'zstd -d --long=30 --force -o',
constants_1.TarFilename,
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
]
: [
'--use-compress-program',
IS_WINDOWS ? '"zstd -d --long=30"' : 'unzstd --long=30'
];
case constants_1.CompressionMethod.ZstdWithoutLong:
return BSD_TAR_ZSTD
? [
'zstd -d --force -o',
constants_1.TarFilename,
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
]
: ['--use-compress-program', IS_WINDOWS ? '"zstd -d"' : 'unzstd'];
default:
return ['-z'];
}
});
2022-10-29 10:03:51 +02:00
}
2023-02-22 17:47:24 -08:00
// Used for creating the archive
// -T#: Compress using # working thread. If # is 0, attempt to detect and use the number of physical CPU cores.
// zstdmt is equivalent to 'zstd -T0'
// --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
// Using 30 here because we also support 32-bit self-hosted runners.
// Long range mode is added to zstd in v1.3.2 release, so we will not use --long in older version of zstd.
function getCompressionProgram(tarPath, compressionMethod) {
return __awaiter(this, void 0, void 0, function* () {
const cacheFileName = utils.getCacheFileName(compressionMethod);
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
compressionMethod !== constants_1.CompressionMethod.Gzip &&
IS_WINDOWS;
switch (compressionMethod) {
case constants_1.CompressionMethod.Zstd:
return BSD_TAR_ZSTD
? [
'zstd -T0 --long=30 --force -o',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
constants_1.TarFilename
]
: [
'--use-compress-program',
IS_WINDOWS ? '"zstd -T0 --long=30"' : 'zstdmt --long=30'
];
case constants_1.CompressionMethod.ZstdWithoutLong:
return BSD_TAR_ZSTD
? [
'zstd -T0 --force -o',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
constants_1.TarFilename
]
: ['--use-compress-program', IS_WINDOWS ? '"zstd -T0"' : 'zstdmt'];
default:
return ['-z'];
}
});
}
// Executes all commands as separate processes
function execCommands(commands, cwd) {
return __awaiter(this, void 0, void 0, function* () {
for (const command of commands) {
try {
yield exec_1.exec(command, undefined, {
cwd,
env: Object.assign(Object.assign({}, process.env), { MSYS: 'winsymlinks:nativestrict' })
});
}
catch (error) {
throw new Error(`${command.split(' ')[0]} failed with error: ${error === null || error === void 0 ? void 0 : error.message}`);
}
}
});
}
// List the contents of a tar
2022-10-29 10:03:51 +02:00
function listTar(archivePath, compressionMethod) {
return __awaiter(this, void 0, void 0, function* () {
2023-02-22 17:47:24 -08:00
const commands = yield getCommands(compressionMethod, 'list', archivePath);
yield execCommands(commands);
2022-10-29 10:03:51 +02:00
});
}
exports.listTar = listTar;
2023-02-22 17:47:24 -08:00
// Extract a tar
2022-07-12 09:00:22 +02:00
function extractTar(archivePath, compressionMethod) {
return __awaiter(this, void 0, void 0, function* () {
// Create directory to extract tar into
const workingDirectory = getWorkingDirectory();
yield io.mkdirP(workingDirectory);
2023-02-22 17:47:24 -08:00
const commands = yield getCommands(compressionMethod, 'extract', archivePath);
yield execCommands(commands);
2022-07-12 09:00:22 +02:00
});
}
exports.extractTar = extractTar;
2023-02-22 17:47:24 -08:00
// Create a tar
2022-07-12 09:00:22 +02:00
function createTar(archiveFolder, sourceDirectories, compressionMethod) {
return __awaiter(this, void 0, void 0, function* () {
// Write source directories to manifest.txt to avoid command length limits
2023-02-22 17:47:24 -08:00
fs_1.writeFileSync(path.join(archiveFolder, constants_1.ManifestFilename), sourceDirectories.join('\n'));
const commands = yield getCommands(compressionMethod, 'create');
yield execCommands(commands, archiveFolder);
2022-07-12 09:00:22 +02:00
});
}
exports.createTar = createTar;
//# sourceMappingURL=tar.js.map