UNPKG

@atomist/sdm-pack-aspect

Version:

an Atomist SDM Extension Pack for visualizing drift across an organization

158 lines 8.71 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. */ Object.defineProperty(exports, "__esModule", { value: true }); const sdm_1 = require("@atomist/sdm"); const sdm_core_1 = require("@atomist/sdm-core"); const array_1 = require("@atomist/sdm-core/lib/util/misc/array"); const sdm_pack_fingerprint_1 = require("@atomist/sdm-pack-fingerprint"); const _ = require("lodash"); const pgClientFactory_1 = require("../analysis/offline/persist/pgClientFactory"); const analyzeCommand_1 = require("../analysis/offline/spider/analyzeCommand"); const analysisTracker_1 = require("../analysis/tracking/analysisTracker"); const classificationAspect_1 = require("../aspect/compose/classificationAspect"); const DefaultAspectRegistry_1 = require("../aspect/DefaultAspectRegistry"); const DeliveryAspect_1 = require("../aspect/delivery/DeliveryAspect"); const ScoredAspect_1 = require("../aspect/score/ScoredAspect"); const fingerprintTask_1 = require("../job/fingerprintTask"); const registerAspect_1 = require("../job/registerAspect"); const api_1 = require("../routes/api"); const webAppRoutes_1 = require("../routes/web-app/webAppRoutes"); const exposeFingerprintScore_1 = require("../scorer/support/exposeFingerprintScore"); const commonTaggers_1 = require("../tagger/commonTaggers"); const machine_1 = require("./machine"); /** * Default VirtualProjectFinder, which recognizes Maven, npm, * and Gradle projects and Python projects using requirements.txt. */ exports.DefaultVirtualProjectFinder = // Consider directories containing any of these files to be virtual projects sdm_pack_fingerprint_1.cachingVirtualProjectFinder(sdm_pack_fingerprint_1.fileNamesVirtualProjectFinder("package.json", "pom.xml", "build.gradle", "requirements.txt")); exports.DefaultScoreWeightings = { // Weight this to penalize projects with few other scorers anchor: 3, }; /** * Return an extension pack to add aspect support with the given aspects to an SDM. * If we're in local mode, expose analyzer commands and HTTP endpoints. */ function aspectSupport(options) { const scoringAspects = _.flatten(Object.getOwnPropertyNames(options.scorers || {}) .map(name => ScoredAspect_1.emitScoringAspect(name, array_1.toArray(options.scorers[name] || []), options.weightings))) .filter(a => !!a); const tagAspect = classificationAspect_1.projectClassificationAspect({ name: "tagger", displayName: "tagger", }, ...array_1.toArray(options.taggers) || []); const aspects = [...array_1.toArray(options.aspects || []), ...scoringAspects, tagAspect]; // Default the two display methods with some sensible defaults aspects.forEach(a => { if (!a.toDisplayableFingerprint) { a.toDisplayableFingerprint = fp => JSON.stringify(fp.data); } if (!a.toDisplayableFingerprintName) { a.toDisplayableFingerprintName = fn => fn; } }); return Object.assign(Object.assign({}, sdm_1.metadata()), { configure: sdm => { const cfg = sdm.configuration; const analysisTracking = new analysisTracker_1.AnalysisTracker(); if (sdm_core_1.isInLocalMode()) { // If we're in local mode, expose analyzer commands and // HTTP endpoints const analyzer = machine_1.createAnalyzer(aspects, options.virtualProjectFinder || exports.DefaultVirtualProjectFinder); sdm.addCommand(analyzeCommand_1.analyzeGitHubByQueryCommandRegistration(analyzer, analysisTracking)); sdm.addCommand(analyzeCommand_1.analyzeGitHubOrganizationCommandRegistration(analyzer, analysisTracking)); sdm.addCommand(analyzeCommand_1.analyzeLocalCommandRegistration(analyzer, analysisTracking)); } else { // Add command to calculate fingerprints as part of the initial onboarding // job and on subsequent runs of "analyze org" sdm.addCommand(fingerprintTask_1.calculateFingerprintTask(sdm, aspects)); // Register all aspects on startup sdm.addStartupListener(registerAspect_1.registerAspects(sdm, aspects)); } // Add support for calculating aspects on push and computing delivery aspects // This is only possible in local mode if we have a fingerprint publisher, // as we can't send to Atomist (the default) if (!!options.goals && (!sdm_core_1.isInLocalMode() || !!options.publishFingerprints)) { if (!!options.goals.pushImpact) { // Add supporting for calculating fingerprints on every push sdm.addExtensionPacks(sdm_pack_fingerprint_1.fingerprintSupport({ pushImpactGoal: options.goals.pushImpact, aspects, aspectsFactory: options.aspectsFactory, rebase: options.rebase, publishFingerprints: options.publishFingerprints, })); } aspects .filter(DeliveryAspect_1.isDeliveryAspect) .filter(a => a.canRegister(sdm, options.goals)) .forEach(da => da.register(sdm, options.goals, options.publishFingerprints)); } const exposeWeb = options.exposeWeb !== undefined ? options.exposeWeb : sdm_core_1.isInLocalMode(); if (exposeWeb) { const { customizers, routesToSuggestOnStartup } = orgVisualizationEndpoints(pgClientFactory_1.sdmConfigClientFactory(cfg), cfg, analysisTracking, options, aspects); cfg.http.customizers.push(...customizers); routesToSuggestOnStartup.forEach(rtsos => { cfg.logging.banner.contributors.push(suggestRoute(rtsos)); }); } } }); } exports.aspectSupport = aspectSupport; function suggestRoute({ title, route }) { return cfg => ({ title, body: `http://localhost:${cfg.http.port}${route}`, }); } function orgVisualizationEndpoints(dbClientFactory, configuration, analysisTracking, options, aspects) { const resultStore = machine_1.analysisResultStore(dbClientFactory); const fingerprintClassificationsFound = _.flatten(aspects.filter(classificationAspect_1.isClassificationAspect).map(ca => ca.classifierMetadata)); const scorerNames = Object.getOwnPropertyNames((options.scorers || {})); const aspectRegistry = new DefaultAspectRegistry_1.DefaultAspectRegistry({ idealStore: resultStore, problemStore: resultStore, aspects, undesirableUsageChecker: options.undesirableUsageChecker, scorers: array_1.toArray(options.inMemoryScorers || []).concat(scorerNames.map(exposeFingerprintScore_1.exposeFingerprintScore)), workspaceScorers: options.workspaceScorers, scoreWeightings: options.weightings || exports.DefaultScoreWeightings, configuration, }) .withTaggers(...array_1.toArray(options.inMemoryTaggers || [])) // Add in memory taggers for all classification fingerprints .withTaggers(...commonTaggers_1.tagsFromClassificationFingerprints(...fingerprintClassificationsFound)); if (options.secureWeb === undefined) { options.secureWeb = !sdm_core_1.isInLocalMode(); } const aboutTheApi = api_1.api(resultStore, aspectRegistry, options.secureWeb); if (!sdm_core_1.isInLocalMode() && !options.exposeWeb) { return { routesToSuggestOnStartup: aboutTheApi.routesToSuggestOnStartup, customizers: [aboutTheApi.customizer], }; } const aboutStaticPages = webAppRoutes_1.addWebAppRoutes(aspectRegistry, resultStore, analysisTracking, configuration.http.client.factory, options.instanceMetadata || sdm_1.metadata()); return { routesToSuggestOnStartup: [...aboutStaticPages.routesToSuggestOnStartup, ...aboutTheApi.routesToSuggestOnStartup], customizers: [aboutStaticPages.customizer, aboutTheApi.customizer], }; } //# sourceMappingURL=aspectSupport.js.map