@plugjs/plug
Version:
PlugJS Build System ===================
68 lines (67 loc) • 2.61 kB
JavaScript
// plugs/copy.ts
import { assert } from "../asserts.mjs";
import { Files } from "../files.mjs";
import { chmod, copyFile, fsConstants, mkdir } from "../fs.mjs";
import { $p } from "../logging.mjs";
import { assertAbsolutePath, getAbsoluteParent, resolveAbsolutePath } from "../paths.mjs";
import { install } from "../pipe.mjs";
install("copy", class Copy {
constructor(_directory, _options = {}) {
this._directory = _directory;
this._options = _options;
}
async pipe(files, context) {
const { mode, dirMode, overwrite = "fail", rename = (s) => s } = this._options;
const flags = overwrite === "overwrite" ? 0 : fsConstants.COPYFILE_EXCL;
const dmode = parseMode(dirMode);
const fmode = parseMode(mode);
const directory = context.resolve(this._directory);
const builder = Files.builder(directory);
for (const [relative, absolute] of files.pathMappings()) {
const target = resolveAbsolutePath(builder.directory, rename(relative));
if (target === absolute) {
context.log.warn("Cowardly refusing to copy same file", $p(absolute));
continue;
}
const directory2 = getAbsoluteParent(target);
const firstParent = await mkdir(directory2, { recursive: true });
if (firstParent && dmode !== void 0) {
assertAbsolutePath(firstParent);
for (let dir = directory2; ; dir = getAbsoluteParent(dir)) {
context.log.trace(`Setting mode ${stringifyMode(dmode)} for directory`, $p(dir));
await chmod(dir, dmode);
if (dir === firstParent) break;
}
}
context.log.trace(`Copying "${$p(absolute)}" to "${$p(target)}"`);
try {
await copyFile(absolute, target, flags);
if (fmode !== void 0) {
context.log.trace(`Setting mode ${stringifyMode(fmode)} for file`, $p(target));
await chmod(target, fmode);
}
builder.add(target);
} catch (error) {
if (error.code === "EEXIST" && overwrite === "skip") {
context.log.warn(`Not overwriting existing file ${$p(target)}`);
} else {
throw error;
}
}
}
const result = builder.build();
context.log.info("Copied", result.length, "files to", $p(builder.directory));
return result;
}
});
function parseMode(mode) {
if (mode === void 0) return void 0;
if (typeof mode === "number") return mode;
const parsed = parseInt(mode, 8);
assert(!isNaN(parsed), `Invalid mode "${mode}"`);
return parsed;
}
function stringifyMode(mode) {
return mode.toString(8).padStart(4, "0");
}
//# sourceMappingURL=copy.mjs.map