UNPKG

@atomist/automation-client

Version:

Atomist API for software low-level client

111 lines 4.08 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs-extra"); const path = require("path"); const shutdown_1 = require("../../internal/util/shutdown"); const logger_1 = require("../../util/logger"); const DefaultOpts = { reuseDirectories: false, cleanOnExit: true, }; /** * Build a stable working directory structure. * Options determine whether it's cleared on exit. */ class StableDirectoryManager { constructor(pOpts) { this.directoriesUsed = 0; this.opts = Object.assign(Object.assign({}, DefaultOpts), pOpts); if (this.opts.cleanOnExit === true) { shutdown_1.registerShutdownHook(() => { logger_1.logger.debug("Cleaning up directories under '%s'", this.opts.baseDir); return fs.remove(this.opts.baseDir).then(() => 0); }, 3000, `directory cleanup: ${this.opts.baseDir}`); } } invalidate(existing) { return fs.remove(existing.path) .then(() => { logger_1.logger.debug("Deleted " + existing.path); }, err => { if (err.code === "ENOENT") { logger_1.logger.debug("Cleanup: deleting %s, but it's already gone", existing.path); return; } else { logger_1.logger.error("Unexpected error deleting directory %s: %s", existing.path, err); throw err; } }); } directoryFor(owner, repo, branch, opts) { if (this.opts.reuseDirectories) { // Attempt to reuse the directory return this.existingDirectoryFor(owner, repo, branch, opts) .then(existing => !!existing ? existing : this.freshDirectoryFor(owner, repo, branch, opts)); } else { return this.freshDirectoryFor(owner, repo, branch, opts); } } /** * Return undefined if not found */ existingDirectoryFor(owner, repo, branch, opts) { const expectedPath = this.pathFor(owner, repo); return fs.pathExists(expectedPath) .then(exists => { if (exists) { logger_1.logger.debug("%s directories used: Reusing path '%s'", this.directoriesUsed, expectedPath); return { path: expectedPath, type: "existing-directory", release: () => Promise.resolve(), invalidate: () => Promise.resolve(), transient: false, }; } else { // It doesn't exist return undefined; } }); } freshDirectoryFor(user, repo, branch, opts) { return this.createFreshDir(user, repo) .then((cdi) => { this.directoriesUsed++; logger_1.logger.debug("%s directories used: Returning new path '%s'", this.directoriesUsed, cdi); return { path: cdi, type: "empty-directory", release: () => Promise.resolve(), invalidate: () => Promise.resolve(), transient: false, }; }); } pathFor(owner, repo) { return path.join(this.opts.baseDir, "repos", "github.com", owner, repo); } createFreshDir(owner, repo) { const repoDir = this.pathFor(owner, repo); return fs.ensureDir(repoDir) .then(() => assureDirectoryIsEmpty(repoDir)) .then(() => repoDir); } } exports.StableDirectoryManager = StableDirectoryManager; function assureDirectoryIsEmpty(name) { return fs.readdir(name).then(files => { if (files.length > 0) { return fs.remove(name) .then(() => fs.ensureDir(name)) .catch(err => { throw new Error("I tried to make this directory be empty: " + name + " but it didn't work: " + err.message); }); } }); } //# sourceMappingURL=StableDirectoryManager.js.map