@atomist/sdm-pack-aspect
Version:
an Atomist SDM Extension Pack for visualizing drift across an organization
185 lines • 7.02 kB
JavaScript
"use strict";
/*
* 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.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const automation_client_1 = require("@atomist/automation-client");
/**
* Track the calculation of fingerprints from one aspect on one repo snapshot
*/
class AspectBeingTracked {
constructor(params) {
this.params = params;
this.moreFailures = [];
this.startedAt = new Date();
}
isThisYou(aspectName) {
return this.params.aspectName === aspectName;
}
failFingerprint(fp, error) {
this.moreFailures.push({ error, furtherDescription: "Failed on fingerprint: " + fp.name });
}
completed(fingerprintsFound) {
this.fingerprintsFound = fingerprintsFound;
this.completedAt = new Date();
}
failed(err) {
this.failedWith = err;
this.completedAt = new Date();
}
report() {
let error = this.failedWith;
if (!error && this.moreFailures.length === 1) {
error = this.moreFailures[0].error;
}
else if (error && this.moreFailures.length > 0) {
const allErrorMessages = (error ? error.message + "\n" : "") +
this.moreFailures.map(f => f.furtherDescription + ": " + f.error.message).join("\n");
error = new Error(`multiple errors: ${allErrorMessages}`);
}
return {
aspectName: this.params.aspectName,
visible: this.params.visible,
stage: this.params.aboutToRun,
millisTaken: this.completedAt ? this.completedAt.getTime() - this.startedAt.getTime() : undefined,
fingerprintsFound: this.fingerprintsFound || 0,
error,
};
}
}
exports.AspectBeingTracked = AspectBeingTracked;
class RepoBeingTracked {
constructor(params) {
this.params = params;
this.repoRef = undefined;
this.existingWasKept = false;
this.failureDetails = undefined;
this.aspects = [];
}
beganAnalysis() {
this.analysisStartMillis = new Date().getTime();
}
setRepoRef(repoRef) {
this.repoRef = repoRef;
}
keptExisting() {
this.millisTaken = new Date().getTime() - this.analysisStartMillis;
this.existingWasKept = true;
}
plan(aspect, aboutToRun) {
const newAspect = new AspectBeingTracked({
aspectName: aspect.name,
visible: !!aspect.displayName,
aboutToRun,
});
this.aspects.push(newAspect);
return newAspect;
}
failed(failureDetails) {
this.failureDetails = failureDetails;
this.millisTaken = this.millisTaken = new Date().getTime() - this.analysisStartMillis;
}
failFingerprint(fp, error) {
const a = this.aspects.find(n => n.isThisYou(fp.type));
if (!a) {
automation_client_1.logger.warn("Did not find aspect: " + fp.type);
return;
}
a.failFingerprint(fp, error);
}
skipped(skipReason) {
this.skipReason = skipReason || "unspecified reason";
this.millisTaken = this.millisTaken = new Date().getTime() - this.analysisStartMillis;
}
persisted(snapshotId) {
this.persistedSnapshotId = snapshotId;
this.millisTaken = this.millisTaken = new Date().getTime() - this.analysisStartMillis;
}
report() {
const isGoing = !!this.analysisStartMillis;
const isDone = this.existingWasKept || this.persistedSnapshotId || this.failureDetails || this.skipReason;
const errorFields = !this.failureDetails ? {} : {
errorMessage: `Failed while trying to ${this.failureDetails.whileTryingTo}\n${this.failureDetails.message || ""}`,
stackTrace: this.failureDetails.error ? this.failureDetails.error.stack : undefined,
};
return Object.assign(Object.assign(Object.assign({}, this.params), { progress: isDone ? "Stopped" : isGoing ? "Going" : "Planned", keptExisting: this.existingWasKept, millisTaken: this.millisTaken, snapshotId: this.persistedSnapshotId, aspects: this.aspects.map(a => a.report()) }), errorFields);
}
spiderResult() {
if (!this.repoRef) {
throw new Error("Can't return a SpiderResult until repoRef is set");
}
return {
repositoriesDetected: 1,
failed: this.failureDetails ? [{
repoUrl: this.repoRef.url,
whileTryingTo: this.failureDetails.whileTryingTo,
message: this.failureDetails.error ? this.failureDetails.error.message : this.failureDetails.message,
}] : [],
keptExisting: this.existingWasKept ? [this.repoRef.url] : [],
persistedAnalyses: this.persistedSnapshotId ? [this.repoRef.url] : [],
millisTaken: this.millisTaken,
};
}
}
exports.RepoBeingTracked = RepoBeingTracked;
// make the interface later
class AnalysisBeingTracked {
constructor(me) {
this.me = me;
this.repos = [];
this.repoCount = 0;
}
plan(repo) {
const newRepo = new RepoBeingTracked(Object.assign(Object.assign({}, repo), { repoKey: this.me.analysisKey + "/repo#" + this.repoCount++ }));
this.repos.push(newRepo);
return newRepo;
}
stop() {
this.completedAt = new Date();
this.me.progress = "Stopped";
}
failed(error) {
this.error = error;
this.me.progress = "Stopped";
}
report() {
return Object.assign(Object.assign({}, this.me), { error: this.error, repos: this.repos.map(s => s.report()), completedAt: this.completedAt });
}
}
exports.AnalysisBeingTracked = AnalysisBeingTracked;
/**
* Track analyses for display of status on a page.
* You want exactly one of these in your SDM.
*/
class AnalysisTracker {
constructor() {
this.counter = 1;
this.analyses = [];
}
// is there an "unpick" ?
startAnalysis(params) {
const analysisId = "analysis#" + this.counter++;
const newAnalysis = new AnalysisBeingTracked(Object.assign(Object.assign({}, params), { analysisKey: analysisId, progress: "Going" }));
this.analyses.push(newAnalysis);
return newAnalysis;
}
report() {
return {
analyses: this.analyses.map(a => a.report()),
};
}
}
exports.AnalysisTracker = AnalysisTracker;
//# sourceMappingURL=analysisTracker.js.map