@atomist/automation-client
Version:
Atomist API for software low-level client
111 lines • 4.08 kB
JavaScript
;
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