@atomist/sdm-pack-aspect
Version:
an Atomist SDM Extension Pack for visualizing drift across an organization
159 lines • 6.19 kB
JavaScript
;
/*
* 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) {
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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const automation_client_1 = require("@atomist/automation-client");
const codeMetrics_1 = require("../aspect/common/codeMetrics");
const codeOfConduct_1 = require("../aspect/community/codeOfConduct");
const license_1 = require("../aspect/community/license");
const globAspect_1 = require("../aspect/compose/globAspect");
const branchCount_1 = require("../aspect/git/branchCount");
const dateUtils_1 = require("../aspect/git/dateUtils");
const gitActivity_1 = require("../aspect/git/gitActivity");
const exposedSecrets_1 = require("../aspect/secret/exposedSecrets");
exports.Monorepo = {
name: "monorepo",
description: "Contains multiple virtual projects",
severity: "warn",
test: fp => !!fp.path && fp.path.length > 0,
};
exports.Vulnerable = {
name: "vulnerable",
description: "Has exposed secrets", test: fp => fp.type === exposedSecrets_1.ExposedSecrets.name,
severity: "error",
};
exports.HasLicense = {
name: "license",
description: "Repositories should have a license",
test: fp => license_1.isLicenseFingerprint(fp) && !license_1.hasNoLicense(fp.data),
};
exports.HasCodeOfConduct = {
name: "code-of-conduct",
description: "Repositories should have a code of conduct",
test: fp => fp.type === codeOfConduct_1.CodeOfConductType,
};
exports.HasChangeLog = globRequired({
name: "changelog",
description: "Repositories should have a changelog",
glob: "CHANGELOG.md",
});
exports.HasContributingFile = globRequired({
name: "contributing",
description: "Repositories should have a contributing",
glob: "CONTRIBUTING.md",
});
/**
* Tag projects as dead if they haven't been committed to recently
* @param {{days: number}} opts number of days at which to conclude a project is dead
* @return {Tagger}
*/
function dead(opts) {
return {
name: "dead?",
description: `No git activity in last ${opts.deadDays} days`,
severity: "error",
test: fp => {
if (fp.type === gitActivity_1.GitRecencyType) {
const date = new Date(fp.data);
return dateUtils_1.daysSince(date) > opts.deadDays;
}
return false;
},
};
}
exports.dead = dead;
exports.SoleCommitter = {
name: "sole-committer",
description: "Projects with one committer",
test: fp => fp.type === gitActivity_1.GitActivesType && fp.data.count === 1,
};
function excessiveBranchCount(opts) {
return {
name: `>${opts.maxBranches} branches`,
description: "git branch count",
severity: "warn",
test: fp => fp.type === branchCount_1.BranchCountType && fp.data.count > opts.maxBranches,
};
}
exports.excessiveBranchCount = excessiveBranchCount;
function lineCountTest(opts) {
return {
name: opts.name,
description: "Repo size",
test: fp => codeMetrics_1.isCodeMetricsFingerprint(fp) && opts.lineCountTest(fp.data.lines),
};
}
exports.lineCountTest = lineCountTest;
function globRequired(opts) {
return Object.assign({}, opts, { test: fp => globAspect_1.isGlobMatchFingerprint(fp) && fp.data.glob === opts.glob && fp.data.matches.length > 0 });
}
exports.globRequired = globRequired;
/**
* Flag repos with known undesirable usages
*/
exports.isProblematic = {
name: "problems",
create: (workspaceId, aspectRegistry) => __awaiter(this, void 0, void 0, function* () {
automation_client_1.logger.info("Creating problem tagger for workspace %s", workspaceId);
const checker = yield aspectRegistry.undesirableUsageCheckerFor(workspaceId);
return {
name: "problems",
description: "Undesirable usage",
severity: "error",
test: fp => {
const problem = checker.check(fp, workspaceId);
return !!problem;
},
};
}),
};
function gitHot(opts) {
return {
name: opts.name || "hot",
description: "How hot is git",
test: fps => {
const grt = fps.find(fp => fp.type === gitActivity_1.GitRecencyType);
const acc = fps.find(fp => fp.type === gitActivity_1.GitActivesType);
if (!!grt && !!acc) {
const days = dateUtils_1.daysSince(new Date(grt.data));
if (days < opts.hotDays && acc.data.count > opts.hotContributors) {
return true;
}
}
return false;
},
};
}
exports.gitHot = gitHot;
function inadequateReadme(opts) {
return {
name: "poor-readme",
description: "README is adequate",
severity: "warn",
test: fp => globAspect_1.isGlobMatchFingerprint(fp) &&
fp.data.glob === "README.md" && (fp.data.matches.length === 0 || fp.data.matches[0].size < opts.minLength),
};
}
exports.inadequateReadme = inadequateReadme;
//# sourceMappingURL=commonTaggers.js.map