UNPKG

@atomist/automation-client

Version:
209 lines • 8.32 kB
"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 fs = require("fs-extra"); const gs = require("glob-stream"); const fpath = require("path"); const stream = require("stream"); const file_1 = require("../../internal/util/file"); const logger_1 = require("../../internal/util/logger"); const RepoId_1 = require("../../operations/common/RepoId"); const InMemoryProject_1 = require("../mem/InMemoryProject"); const AbstractProject_1 = require("../support/AbstractProject"); const projectUtils_1 = require("../support/projectUtils"); const LocalProject_1 = require("./LocalProject"); const NodeFsLocalFile_1 = require("./NodeFsLocalFile"); class NodeFsLocalProject extends AbstractProject_1.AbstractProject { /** * Note: this does not validate existence of the target * directory, so using it except in tests should be avoided * @param {RepoRef} ident identification of the repo * @param {string} baseDir * @param cleanup function that will release locks, delete temp directories etc */ constructor(ident, baseDir, cleanup = () => Promise.resolve()) { super(typeof ident === "string" ? new RepoId_1.SimpleRepoId(undefined, ident) : ident); this.cleanup = cleanup; // TODO not sure why app-root-path can return something weird and this coercion is necessary this.baseDir = "" + baseDir; } /** * Create a project from an existing directory. The directory must exist * @param {RepoRef} id * @param {string} baseDir * @param cleanup * @return {Promise<LocalProject>} */ static fromExistingDirectory(id, baseDir, cleanup = () => Promise.resolve()) { return fs.stat(baseDir).then(stat => { if (!stat.isDirectory()) { throw new Error(`No such directory: [${baseDir}] when trying to create LocalProject`); } else { return new NodeFsLocalProject(id, baseDir, cleanup); } }); } /** * Copy the contents of the other project to this project * @param {Project} other * @param {string} baseDir * @param newName new name of the project. Defaults to name of old project * @param cleanup * @returns {LocalProject} */ static copy(other, baseDir, cleanup = () => Promise.resolve()) { return fs.ensureDir(baseDir) .then(() => { if (LocalProject_1.isLocalProject(other)) { return fs.copy(other.baseDir, baseDir) .then(() => new NodeFsLocalProject(other.id, baseDir, cleanup)); } else { // We don't know what kind of project the other one is, // so we are going to need to copy the files one at a time const p = new NodeFsLocalProject(other.id, baseDir, cleanup); return projectUtils_1.copyFiles(other, p) .then(() => { // Add empty directories if necessary let prom = Promise.resolve(p); if (InMemoryProject_1.isInMemoryProject(other)) { other.addedDirectoryPaths.forEach(path => { prom = prom.then(() => p.addDirectory(path)); }); } return prom; }); } }); } release() { return this.cleanup(); } addFileSync(path, content) { const realName = this.baseDir + "/" + path; const dir = fpath.dirname(realName); if (!fs.existsSync(dir)) { fs.mkdirsSync(dir); } fs.writeFileSync(realName, content); } addFile(path, content) { const realName = this.baseDir + "/" + path; const dir = fpath.dirname(realName); return fs.pathExists(dir).then(exists => exists ? Promise.resolve() : fs.mkdirs(dir)) .then(() => fs.writeFile(realName, content)) .then(() => this); } addDirectory(path) { const realName = this.baseDir + "/" + path; return fs.mkdirp(realName) .then(() => this); } deleteDirectory(path) { return fs.remove(this.toRealPath(path)) .then(_ => this) .catch(err => { logger_1.logger.warn("Unable to delete directory '%s': %s", path, err); return this; }); } deleteDirectorySync(path) { const localPath = this.toRealPath(path); try { file_1.deleteFolderRecursive(localPath); fs.unlinkSync(localPath); } catch (e) { logger_1.logger.warn("Ignoring directory deletion error: " + e); } } deleteFileSync(path) { try { fs.unlinkSync(this.toRealPath(path)); } catch (e) { logger_1.logger.warn("Ignoring file deletion error: " + e); } } deleteFile(path) { return fs.unlink(this.toRealPath(path)).then(_ => this); } makeExecutable(path) { return fs.stat(this.toRealPath(path)) .then(stats => { logger_1.logger.debug("Starting mode: " + stats.mode); // tslint:disable-next-line:no-bitwise const newMode = stats.mode | fs.constants.S_IXUSR; logger_1.logger.debug("Setting mode to: " + newMode); return fs.chmod(this.toRealPath(path), newMode); }) .then(() => this); } makeExecutableSync(path) { throw new Error("makeExecutableSync not implemented."); } directoryExistsSync(path) { throw new Error("directoryExistsSync not implemented."); } fileExistsSync(path) { return fs.existsSync(this.baseDir + "/" + path); } findFile(path) { return fs.pathExists(this.baseDir + "/" + path) .then(exists => exists ? Promise.resolve(new NodeFsLocalFile_1.NodeFsLocalFile(this.baseDir, path)) : Promise.reject(fileNotFound(path))); } getFile(path) { return __awaiter(this, void 0, void 0, function* () { const exists = yield fs.pathExists(this.baseDir + "/" + path); return exists ? new NodeFsLocalFile_1.NodeFsLocalFile(this.baseDir, path) : undefined; }); } findFileSync(path) { if (!this.fileExistsSync(path)) { return undefined; } return new NodeFsLocalFile_1.NodeFsLocalFile(this.baseDir, path); } streamFilesRaw(globPatterns, opts) { // Fight arrow function "this" issue const baseDir = this.baseDir; const toFileTransform = new stream.Transform({ objectMode: true }); toFileTransform._transform = function (chunk, encoding, done) { const f = new NodeFsLocalFile_1.NodeFsLocalFile(baseDir, pathWithinArchive(baseDir, chunk.path)); this.push(f); done(); }; const optsToUse = Object.assign({ // We can override these defaults... nodir: true, allowEmpty: true }, opts, { // ...but we force this one cwd: this.baseDir }); return gs(globPatterns, optsToUse) .pipe(toFileTransform); } toRealPath(path) { return this.baseDir + "/" + path; } } exports.NodeFsLocalProject = NodeFsLocalProject; function pathWithinArchive(baseDir, rawPath) { return rawPath.substr(baseDir.length); } // construct a useful exception function fileNotFound(path) { const error = new Error(`File not found at ${path}`); error.code = "ENOENT"; return error; } //# sourceMappingURL=NodeFsLocalProject.js.map