Use the prefix id for keying into metrics rules

Fixes a bug where we were looking for incorrect keys for metrics rules.
Previously, we were using full language names in the keys. Now, we use
the short language names in the metric ids. This is done through a
simplification of the code.

Also, this change does two smaller things:

1. Prints out the baseline count to the logs
2. Adds the `assertNever` function to ensure we never miss a case in
   a switch statement. This function is borrowed from vscode-codeql.
This commit is contained in:
Andrew Eisenberg 2021-05-13 17:56:27 +00:00
parent 4c0671c518
commit e8b2a9884b
15 changed files with 168 additions and 116 deletions

View file

@ -2,60 +2,54 @@ import { LocDir } from "github-linguist";
import { Language } from "./languages";
import { Logger } from "./logging";
import { assertNever } from "./util";
// Language IDs used by codeql when specifying its metrics.
export type IdPrefixes = "cpp" | "cs" | "go" | "java" | "js" | "py" | "rb";
export type IdPrefix = "cpp" | "cs" | "go" | "java" | "js" | "py" | "rb";
// Map from linguist language names to language prefixes used in the action and codeql
const linguistToMetrics: Record<
string,
{ name: Language; prefix: IdPrefixes }
> = {
c: {
name: Language.cpp,
prefix: "cpp",
},
"c++": {
name: Language.cpp,
prefix: "cpp",
},
"c#": {
name: Language.csharp,
prefix: "cs",
},
go: {
name: Language.go,
prefix: "go",
},
java: {
name: Language.java,
prefix: "java",
},
javascript: {
name: Language.javascript,
prefix: "js",
},
python: {
name: Language.python,
prefix: "py",
},
typescript: {
name: Language.javascript,
prefix: "js",
},
const linguistToMetrics: Record<string, Language> = {
c: Language.cpp,
"c++": Language.cpp,
"c#": Language.csharp,
go: Language.go,
java: Language.java,
javascript: Language.javascript,
python: Language.python,
typescript: Language.javascript,
};
const nameToLinguist = Object.entries(linguistToMetrics).reduce(
(obj, [key, { name: action }]) => {
if (!obj[action]) {
obj[action] = [];
(obj, [key, name]) => {
if (!obj[name]) {
obj[name] = [];
}
obj[action].push(key);
obj[name].push(key);
return obj;
},
{} as Record<Language, string[]>
);
export function getIdPrefix(language: Language): IdPrefix {
switch (language) {
case Language.cpp:
return "cpp";
case Language.csharp:
return "cs";
case Language.go:
return "go";
case Language.java:
return "java";
case Language.javascript:
return "js";
case Language.python:
return "py";
default:
assertNever(language);
}
}
/**
* Count the lines of code of the specified language using the include
* and exclude glob paths.
@ -72,7 +66,7 @@ export async function countLoc(
exclude: string[],
dbLanguages: Language[],
logger: Logger
): Promise<Partial<Record<IdPrefixes, number>>> {
): Promise<Partial<Record<Language, number>>> {
const result = await new LocDir({
cwd,
include: ["**"].concat(include || []),
@ -86,12 +80,12 @@ export async function countLoc(
const lineCounts = Object.entries(result.languages).reduce(
(obj, [language, { code }]) => {
const metricsLanguage = linguistToMetrics[language];
if (metricsLanguage && dbLanguages.includes(metricsLanguage.name)) {
obj[metricsLanguage.prefix] = code + (obj[metricsLanguage.prefix] || 0);
if (metricsLanguage && dbLanguages.includes(metricsLanguage)) {
obj[metricsLanguage] = code + (obj[metricsLanguage] || 0);
}
return obj;
},
{} as Record<IdPrefixes, number>
{} as Record<Language, number>
);
if (Object.keys(lineCounts).length) {