UNPKG

@plugjs/plug

Version:
68 lines (67 loc) 2.61 kB
// 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