UNPKG

@atomist/sdm-pack-aspect

Version:

an Atomist SDM Extension Pack for visualizing drift across an organization

112 lines (98 loc) 3.6 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 { Aspect, fingerprintOf, FP, sha256 } from "@atomist/sdm-pack-fingerprint"; import { firstFileFound } from "../../util/fileUtils"; import { ContentClassifier } from "./ContentClassifier"; export const NoLicense = "None"; export const LicenseType = "license"; export function hasNoLicense(ld: LicenseData): boolean { return ld.classification === NoLicense; } export function isLicenseFingerprint(fp: FP): fp is FP<LicenseData> { return fp.type === LicenseType && !!fp.data.classification; } export interface LicenseData { /** * Path to the license file */ path: string; /** * What we've classified the license as by parsing the license file. */ classification: string; } const defaultClassifier: ContentClassifier = content => content.trim().split("\n")[0].trim(); /** * License aspect. Every repository gets a license fingerprint, which may have unknown * as a license. * @param opts provides classifier function, taking the license content and returning * a classificiation */ export function license(opts: { classifier: ContentClassifier } = { classifier: defaultClassifier }): Aspect<LicenseData> { return { name: LicenseType, displayName: "License", baseOnly: true, extract: async p => { const licenseFile = await firstFileFound(p, "LICENSE", "LICENSE.txt", "license.txt", "LICENSE.md"); let classification: string = NoLicense; let content: string; if (!!licenseFile) { content = await licenseFile.getContent(); classification = opts.classifier(content); } const data: LicenseData = { classification, path: licenseFile ? licenseFile.path : undefined }; return fingerprintOf({ type: LicenseType, data, }); }, toDisplayableFingerprintName: () => "License", toDisplayableFingerprint: fp => { return fp.data.classification === NoLicense ? "None" : `${fp.data.path}:${fp.data.classification}`; }, stats: { defaultStatStatus: { entropy: false, }, }, }; } export const LicensePresenceType: string = "license-presence"; /** * Does this repository have a license? * Works with data from the license aspect. */ export const LicensePresence: Aspect<{ present: boolean }> = { name: LicensePresenceType, displayName: "License presence", extract: async () => [], consolidate: async fps => { const lfp = fps.find(isLicenseFingerprint); const present = !!lfp && !hasNoLicense(lfp.data); const data = { present }; return { name: LicensePresenceType, type: LicensePresenceType, data, sha: sha256(JSON.stringify(data)), }; }, toDisplayableFingerprint: fp => fp.data.present ? "Yes" : "No", };