1
0
Fork 0
mirror of https://github.com/actions/setup-python.git synced 2024-11-30 03:45:17 +00:00
setup-python/node_modules/@actions/io/lib/io.js

262 lines
10 KiB
JavaScript
Raw Normal View History

2019-06-27 01:12:00 +00:00
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const childProcess = require("child_process");
const fs = require("fs");
const path = require("path");
const util_1 = require("util");
const ioUtil = require("./io-util");
const exec = util_1.promisify(childProcess.exec);
/**
* Copies a file or folder.
*
* @param source source path
* @param dest destination path
* @param options optional. See CopyOptions.
*/
function cp(source, dest, options = {}) {
return __awaiter(this, void 0, void 0, function* () {
yield move(source, dest, options, { deleteOriginal: false });
});
}
exports.cp = cp;
/**
* Moves a path.
*
* @param source source path
* @param dest destination path
* @param options optional. See CopyOptions.
*/
function mv(source, dest, options = {}) {
return __awaiter(this, void 0, void 0, function* () {
yield move(source, dest, options, { deleteOriginal: true });
});
}
exports.mv = mv;
/**
* Remove a path recursively with force
*
* @param inputPath path to remove
*/
function rmRF(inputPath) {
return __awaiter(this, void 0, void 0, function* () {
if (ioUtil.IS_WINDOWS) {
// Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another
// program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.
try {
if (yield ioUtil.isDirectory(inputPath, true)) {
yield exec(`rd /s /q "${inputPath}"`);
}
else {
yield exec(`del /f /a "${inputPath}"`);
}
}
catch (err) {
// if you try to delete a file that doesn't exist, desired result is achieved
// other errors are valid
if (err.code !== 'ENOENT')
throw err;
}
// Shelling out fails to remove a symlink folder with missing source, this unlink catches that
try {
yield ioUtil.unlink(inputPath);
}
catch (err) {
// if you try to delete a file that doesn't exist, desired result is achieved
// other errors are valid
if (err.code !== 'ENOENT')
throw err;
}
}
else {
let isDir = false;
try {
isDir = yield ioUtil.isDirectory(inputPath);
}
catch (err) {
// if you try to delete a file that doesn't exist, desired result is achieved
// other errors are valid
if (err.code !== 'ENOENT')
throw err;
return;
}
if (isDir) {
yield exec(`rm -rf "${inputPath}"`);
}
else {
yield ioUtil.unlink(inputPath);
}
}
});
}
exports.rmRF = rmRF;
/**
* Make a directory. Creates the full path with folders in between
* Will throw if it fails
*
* @param fsPath path to create
* @returns Promise<void>
*/
function mkdirP(fsPath) {
return __awaiter(this, void 0, void 0, function* () {
yield ioUtil.mkdirP(fsPath);
});
}
exports.mkdirP = mkdirP;
/**
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
* If you check and the tool does not exist, it will throw.
*
* @param tool name of the tool
* @param check whether to check if tool exists
* @returns Promise<string> path to tool
*/
function which(tool, check) {
return __awaiter(this, void 0, void 0, function* () {
if (!tool) {
throw new Error("parameter 'tool' is required");
}
// recursive when check=true
if (check) {
const result = yield which(tool, false);
if (!result) {
if (ioUtil.IS_WINDOWS) {
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`);
}
else {
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);
}
}
}
try {
// build the list of extensions to try
const extensions = [];
if (ioUtil.IS_WINDOWS && process.env.PATHEXT) {
for (const extension of process.env.PATHEXT.split(path.delimiter)) {
if (extension) {
extensions.push(extension);
}
}
}
// if it's rooted, return it if exists. otherwise return empty.
if (ioUtil.isRooted(tool)) {
const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions);
if (filePath) {
return filePath;
}
return '';
}
// if any path separators, return empty
if (tool.includes('/') || (ioUtil.IS_WINDOWS && tool.includes('\\'))) {
return '';
}
// build the list of directories
//
// Note, technically "where" checks the current directory on Windows. From a task lib perspective,
// it feels like we should not do this. Checking the current directory seems like more of a use
// case of a shell, and the which() function exposed by the task lib should strive for consistency
// across platforms.
const directories = [];
if (process.env.PATH) {
for (const p of process.env.PATH.split(path.delimiter)) {
if (p) {
directories.push(p);
}
}
}
// return the first match
for (const directory of directories) {
const filePath = yield ioUtil.tryGetExecutablePath(directory + path.sep + tool, extensions);
if (filePath) {
return filePath;
}
}
return '';
}
catch (err) {
throw new Error(`which failed with message ${err.message}`);
}
});
}
exports.which = which;
// Copies contents of source into dest, making any necessary folders along the way.
// Deletes the original copy if deleteOriginal is true
function copyDirectoryContents(source, dest, force, deleteOriginal = false) {
return __awaiter(this, void 0, void 0, function* () {
if (yield ioUtil.isDirectory(source)) {
if (yield ioUtil.exists(dest)) {
if (!(yield ioUtil.isDirectory(dest))) {
throw new Error(`${dest} is not a directory`);
}
}
else {
yield mkdirP(dest);
}
// Copy all child files, and directories recursively
const sourceChildren = yield ioUtil.readdir(source);
for (const newSource of sourceChildren) {
const newDest = path.join(dest, path.basename(newSource));
yield copyDirectoryContents(path.resolve(source, newSource), newDest, force, deleteOriginal);
}
if (deleteOriginal) {
yield ioUtil.rmdir(source);
}
}
else {
if (force) {
yield ioUtil.copyFile(source, dest);
}
else {
yield ioUtil.copyFile(source, dest, fs.constants.COPYFILE_EXCL);
}
if (deleteOriginal) {
yield ioUtil.unlink(source);
}
}
});
}
function move(source, dest, options = {}, moveOptions) {
return __awaiter(this, void 0, void 0, function* () {
const { force, recursive } = readCopyOptions(options);
if (yield ioUtil.isDirectory(source)) {
if (!recursive) {
throw new Error(`non-recursive cp failed, ${source} is a directory`);
}
// If directory exists, move source inside it. Otherwise, create it and move contents of source inside.
if (yield ioUtil.exists(dest)) {
if (!(yield ioUtil.isDirectory(dest))) {
throw new Error(`${dest} is not a directory`);
}
dest = path.join(dest, path.basename(source));
}
yield copyDirectoryContents(source, dest, force, moveOptions.deleteOriginal);
}
else {
if ((yield ioUtil.exists(dest)) && (yield ioUtil.isDirectory(dest))) {
dest = path.join(dest, path.basename(source));
}
if (force) {
yield ioUtil.copyFile(source, dest);
}
else {
yield ioUtil.copyFile(source, dest, fs.constants.COPYFILE_EXCL);
}
if (moveOptions.deleteOriginal) {
yield ioUtil.unlink(source);
}
}
});
}
function readCopyOptions(options) {
const force = options.force == null ? true : options.force;
const recursive = Boolean(options.recursive);
return { force, recursive };
}
//# sourceMappingURL=io.js.map