@atomist/sdm-core
Version:
Atomist Software Delivery Machine - Implementation
121 lines • 5.74 kB
JavaScript
/*
* Copyright © 2019 Atomist, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
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) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const automation_client_1 = require("@atomist/automation-client");
const configuration_1 = require("@atomist/automation-client/lib/configuration");
const sdm_1 = require("@atomist/sdm");
const fs = require("fs-extra");
const os = require("os");
const path = require("path");
const resolvePlaceholder_1 = require("../../machine/yaml/resolvePlaceholder");
const FileSystemGoalCacheArchiveStore_1 = require("./FileSystemGoalCacheArchiveStore");
/**
* Cache implementation that caches files produced by goals to an archive that can then be stored,
* using tar and gzip to create the archives per goal invocation (and classifier if present).
*/
class CompressingGoalCache {
constructor(store = new FileSystemGoalCacheArchiveStore_1.FileSystemGoalCacheArchiveStore()) {
this.store = store;
}
put(gi, project, files, classifier) {
return __awaiter(this, void 0, void 0, function* () {
const archiveName = "atomist-cache";
const teamArchiveFileName = path.join(os.tmpdir(), `${archiveName}.${automation_client_1.guid().slice(0, 7)}`);
const slug = `${gi.id.owner}/${gi.id.repo}`;
const tarResult = yield sdm_1.spawnLog("tar", ["-cf", teamArchiveFileName, ...files], {
log: gi.progressLog,
cwd: project.baseDir,
});
if (tarResult.code) {
const message = `Failed to create tar archive '${teamArchiveFileName}' for ${slug}`;
automation_client_1.logger.error(message);
gi.progressLog.write(message);
return;
}
const gzipResult = yield sdm_1.spawnLog("gzip", ["-3", teamArchiveFileName], {
log: gi.progressLog,
cwd: project.baseDir,
});
if (gzipResult.code) {
const message = `Failed to gzip tar archive '${teamArchiveFileName}' for ${slug}`;
automation_client_1.logger.error(message);
gi.progressLog.write(message);
return;
}
const resolvedClassifier = yield resolveClassifierPath(classifier, gi);
yield this.store.store(gi, resolvedClassifier, teamArchiveFileName + ".gz");
});
}
remove(gi, classifier) {
return __awaiter(this, void 0, void 0, function* () {
const resolvedClassifier = yield resolveClassifierPath(classifier, gi);
yield this.store.delete(gi, resolvedClassifier);
});
}
retrieve(gi, project, classifier) {
return __awaiter(this, void 0, void 0, function* () {
const archiveName = "atomist-cache";
const teamArchiveFileName = path.join(os.tmpdir(), `${archiveName}.${automation_client_1.guid().slice(0, 7)}`);
const resolvedClassifier = yield resolveClassifierPath(classifier, gi);
yield this.store.retrieve(gi, resolvedClassifier, teamArchiveFileName);
if (fs.existsSync(teamArchiveFileName)) {
yield sdm_1.spawnLog("tar", ["-xzf", teamArchiveFileName], {
log: gi.progressLog,
cwd: project.baseDir,
});
}
else {
throw Error("No cache entry");
}
});
}
}
exports.CompressingGoalCache = CompressingGoalCache;
/**
* Interpolate information from goal invocation into the classifier.
*/
function resolveClassifierPath(classifier, gi) {
return __awaiter(this, void 0, void 0, function* () {
if (!classifier) {
return gi.context.workspaceId;
}
const wrapper = { classifier };
yield configuration_1.resolvePlaceholders(wrapper, v => resolvePlaceholder_1.resolvePlaceholder(v, gi.goalEvent, gi, {}));
return gi.context.workspaceId + "/" + sanitizeClassifier(wrapper.classifier);
});
}
exports.resolveClassifierPath = resolveClassifierPath;
/**
* Sanitize classifier for use in path. Replace any characters
* which might cause problems on POSIX or MS Windows with "_",
* including path separators. Ensure resulting file is not "hidden".
*/
function sanitizeClassifier(classifier) {
return classifier.replace(/[^-.0-9A-Za-z_+]/g, "_")
.replace(/^\.+/, ""); // hidden
}
exports.sanitizeClassifier = sanitizeClassifier;
//# sourceMappingURL=CompressingGoalCache.js.map
;