UNPKG

@atomist/sdm-pack-aspect

Version:

an Atomist SDM Extension Pack for visualizing drift across an organization

85 lines (77 loc) 3.02 kB
/* * 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. */ import { FP } from "@atomist/sdm-pack-fingerprint"; import * as _ from "lodash"; import { FingerprintKind, ProjectAnalysisResultStore, } from "../persist/ProjectAnalysisResultStore"; /** * Retrieve all fingerprints, then compute and store fingerprint_analytics for the whole workspace */ export async function computeAnalytics(persister: ProjectAnalysisResultStore, workspaceId: string): Promise<void> { const allFingerprints = await persister.fingerprintsInWorkspace(workspaceId, false); const fingerprintKinds = await persister.distinctFingerprintKinds(workspaceId); const persistThese = fingerprintKinds.map((kind: FingerprintKind) => { const fingerprintsOfKind = allFingerprints.filter(f => f.type === kind.type && f.name === kind.name); const cohortAnalysis = analyzeCohort(fingerprintsOfKind); return { workspaceId, kind, cohortAnalysis }; }); await persister.persistAnalytics(persistThese); } /** * Calculate and persist entropy for one fingerprint kind */ export async function computeAnalyticsForFingerprintKind(persister: ProjectAnalysisResultStore, workspaceId: string, type: string, name: string): Promise<void> { const fingerprints = await persister.fingerprintsInWorkspace(workspaceId, false, type, name); if (fingerprints.length === 0) { return; } const cohortAnalysis = analyzeCohort(fingerprints); await persister.persistAnalytics([{ workspaceId, kind: { type, name }, cohortAnalysis }]); } /** * Result of analyzing a cohort of fingerprints. */ export interface CohortAnalysis { count: number; variants: number; entropy: number; compliance: number; } /** * Analyze a cohort of the same kind of fingerprints */ export function analyzeCohort(fps: FP[]): CohortAnalysis { const groups: Record<string, FP[]> = _.groupBy(fps, fp => fp.sha); const count: number = fps.length; const entropy = -1 * Object.values(groups).reduce( (agg, fp: FP[]) => { const p: number = fp.length / count; return agg + p * Math.log(p); }, 0, ); return { entropy, variants: Object.values(groups).length, count, compliance: undefined, }; }