UNPKG

@atomist/sdm-pack-aspect

Version:

an Atomist SDM Extension Pack for visualizing drift across an organization

205 lines 8.66 kB
"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. */ 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 Ideal_1 = require("@atomist/sdm-pack-fingerprint/lib/machine/Ideal"); const sunburst_1 = require("../tree/sunburst"); const treeUtils_1 = require("../tree/treeUtils"); const _ = require("lodash"); const treeMunging_1 = require("./support/treeMunging"); /** * Return a tree from fingerprint name -> instances -> repos * @return {Promise<PlantedTree>} */ function buildFingerprintTree(world, params) { return __awaiter(this, void 0, void 0, function* () { const { workspaceId, byName, fingerprintName, fingerprintType, otherLabel, byOrg, trim, showProgress } = params; const showPresence = !!otherLabel; const { store, aspectRegistry } = world; // Get the tree and then perform post processing on it let pt = yield store.fingerprintsToReposTree({ workspaceId, byName, otherLabel, rootName: fingerprintName, aspectName: fingerprintType, }); // logger.debug("Returning fingerprint tree '%s': %j", fingerprintName, pt); yield decorateProblemFingerprints(aspectRegistry, pt); const aspect = aspectRegistry.aspectOf(fingerprintType); if (!byName) { // Show all fingerprints in one aspect, splitting by fingerprint name pt = treeUtils_1.introduceClassificationLayer(pt, { descendantClassifier: l => { if (!l.sha) { return undefined; } const aspect2 = aspectRegistry.aspectOf(l.type); return !aspect2 || !aspect2.toDisplayableFingerprintName ? l.name : aspect2.toDisplayableFingerprintName(l.name); }, newLayerDepth: 1, newLayerMeaning: "fingerprint name", }); if (!!aspect) { pt.tree.name = aspect.displayName; } } else { // We are showing a particular fingerprint if (!!aspect) { pt.tree.name = aspect.toDisplayableFingerprintName ? aspect.toDisplayableFingerprintName(fingerprintName) : fingerprintName; } } resolveAspectNames(aspectRegistry, pt.tree); // if (!showPresence) { // // Suppress branches from aspects that use name "None" for not found // pt.tree = killChildren(pt.tree, c => c.name === "None"); // } if (byOrg) { pt = treeMunging_1.splitByOrg(pt); } if (showPresence) { pt.tree = treeUtils_1.groupSiblings(pt.tree, { parentSelector: parent => parent.children.some(c => c.sha), childClassifier: kid => kid.sha && kid.name !== "None" ? "Present" : "Absent", collapseUnderName: name => name === "Absent", }); } else if (showProgress) { const ideal = yield aspectRegistry.idealStore.loadIdeal(workspaceId, fingerprintType, fingerprintName); if (!ideal || !Ideal_1.isConcreteIdeal(ideal)) { throw new Error(`No ideal to aspire to for ${fingerprintType}/${fingerprintName} in workspace '${workspaceId}'`); } decorateToShowProgressToIdeal(aspectRegistry, pt, ideal); } if (!showPresence) { // Don't do this if we are looking at presence, as sized nodes will swamp absent nodes with default 1 applyTerminalSizing(aspect, pt.tree); } pt.tree = treeMunging_1.addRepositoryViewUrl(pt.tree); // Group all fingerprint nodes by their name at the first level pt.tree = treeUtils_1.groupSiblings(pt.tree, { parentSelector: parent => parent.children.some(c => c.sha), childClassifier: l => l.name, collapseUnderName: () => true, }); if (trim) { pt.tree = treeUtils_1.trimOuterRim(pt.tree); } else { putRepoPathInNameOfRepoLeaves(pt); } return pt; }); } exports.buildFingerprintTree = buildFingerprintTree; function resolveAspectNames(aspectRegistry, t) { treeUtils_1.visit(t, l => { if (l.sha) { const fp = l; // It's a fingerprint name const aspect = aspectRegistry.aspectOf(fp.type); if (aspect) { fp.name = aspect.toDisplayableFingerprint ? aspect.toDisplayableFingerprint(fp) : fp.data; } else if (!!fp.data && !!fp.data.displayValue) { fp.name = fp.data.displayValue; } else if (!!fp.displayValue) { fp.name = fp.displayValue; } } return true; }); } /** * Size terminal nodes by aspect stat if available */ function applyTerminalSizing(aspect, t) { if (aspect && aspect.stats && aspect.stats.basicStatsPath) { treeUtils_1.visit(t, l => { if (sunburst_1.isSunburstTree(l) && l.children.every(c => !sunburst_1.isSunburstTree(c) && c.owner)) { l.children.forEach(c => c.size = _.get(l, "data." + aspect.stats.basicStatsPath, 1)); } return true; }); } } function decorateProblemFingerprints(aspectRegistry, pt) { return __awaiter(this, void 0, void 0, function* () { const usageChecker = yield aspectRegistry.undesirableUsageCheckerFor("local"); // Flag bad fingerprints with a special color yield treeUtils_1.visitAsync(pt.tree, (l) => __awaiter(this, void 0, void 0, function* () { if (l.sha) { const problems = usageChecker ? usageChecker.check(l, "local") : undefined; if (problems && problems.length > 0) { l.color = "#810325"; l.problems = problems.map(problem => ({ // Need to dispense with the fingerprint, which would make this circular description: problem.description, severity: problem.severity, authority: problem.authority, url: problem.url, })); } } return true; })); }); } function decorateToShowProgressToIdeal(aspectRegistry, pt, ideal) { pt.tree = treeUtils_1.groupSiblings(pt.tree, { parentSelector: parent => parent.children.some(c => c.sha), childClassifier: kid => kid.sha === ideal.ideal.sha ? "Ideal" : "No", groupLayerDecorator: l => { if (l.name === "Ideal") { l.color = "#168115"; } else { l.color = "#811824"; } }, }); } /** * Show virtual repos * @param {PlantedTree} pt */ function putRepoPathInNameOfRepoLeaves(pt) { treeUtils_1.visit(pt.tree, l => { const en = l; if (!sunburst_1.isSunburstTree(en) && en.name && en.url && en.path) { // It's an eligible end node en.name = en.name + "/" + en.path; } return true; }); } exports.putRepoPathInNameOfRepoLeaves = putRepoPathInNameOfRepoLeaves; //# sourceMappingURL=buildFingerprintTree.js.map