core/reporters/metric.reporter.ts
core/reporters/metric.reporter.ts is a file in GovLab Stats. 149 lines of code and 18 definitions.
import type { Derived, ReportInput } from "#types/report.types";
import { humanBytes, num, pct } from "#core/formatters/metric.formatter";
import type { DocArchStats } from "#types/document.types";
import type { FindingsStats } from "#types/pattern.types";
import type { MemoryStats } from "#types/agent.types";
import type { QualityStats } from "#types/catalog.types";
import type { WorkspaceStats } from "#types/manifest.types";
const COUNT_TABLE_DIVIDER = "| --- | ---: |";
const sortedCounts = function sortedCounts(map: Map<string, number>): [string, number][] {
return [...map.entries()].toSorted((a, b) => b[1] - a[1]);
};
const mapRows = function mapRows(map: Map<string, number>, code: (key: string) => string): string[] {
return sortedCounts(map).map(([key, count]) => `| ${code(key)} | ${num(count)} |`);
};
const fileTypeLines = function fileTypeLines(derived: Derived): string[] {
return [
"### File-type mix",
"",
"| Extension | Files | Lines | Blank | Size |",
"| --- | ---: | ---: | ---: | ---: |",
...derived.extRows.map(
([ext, bucket]) =>
`| \`${ext}\` | ${num(bucket.files)} | ${num(bucket.code)} | ${num(bucket.blank)} | ${humanBytes(bucket.bytes)} |`,
),
"",
];
};
const ratioLines = function ratioLines(input: ReportInput, derived: Derived): string[] {
const { workspace, memory, taxonomy } = input;
const sourceTotal = derived.sourceLines + derived.sourceBlank;
const sourceFiles = input.state.authored.get("source")?.files ?? 0;
const taxonomyRows = [
`| taxonomy conformance | ${pct(taxonomy.totals.conformant, taxonomy.totals.assessed)} | ${num(taxonomy.totals.conformant)} of ${num(taxonomy.totals.assessed)} governed |`,
`| over depth cap | ${pct(taxonomy.totals.overCap, taxonomy.totals.assessed)} | ${num(taxonomy.totals.overCap)} of ${num(taxonomy.totals.assessed)} |`,
`| at container root | ${pct(taxonomy.totals.atRoot, taxonomy.totals.assessed)} | ${num(taxonomy.totals.atRoot)} of ${num(taxonomy.totals.assessed)} |`,
];
return [
"### Ratios",
"",
"| Ratio | Value | Of |",
"| --- | ---: | --- |",
`| blank-line share | ${pct(derived.sourceBlank, sourceTotal)} | ${num(derived.sourceBlank)} of ${num(sourceTotal)} source lines |`,
`| test files | ${pct(input.state.testFiles, sourceFiles)} | ${num(input.state.testFiles)} of ${num(sourceFiles)} source |`,
...taxonomyRows,
`| modules with a docs block | ${pct(workspace.withDocs, workspace.total)} | ${num(workspace.withDocs)} of ${num(workspace.total)} |`,
`| modules with a README | ${pct(workspace.withReadme, workspace.total)} | ${num(workspace.withReadme)} of ${num(workspace.total)} |`,
`| modules declaring governance | ${pct(workspace.withGovernance, workspace.total)} | ${num(workspace.withGovernance)} of ${num(workspace.total)} |`,
`| memory files indexed | ${pct(memory.indexEntries, memory.files)} | ${num(memory.indexEntries)} of ${num(memory.files)} |`,
`| empty source files | ${num(derived.emptyFiles)} | — |`,
"",
];
};
const memorySection = function memorySection(memory: MemoryStats): string[] {
if (!memory.present) {
return [];
}
const types = sortedCounts(memory.byType)
.map(([key, count]) => `${key} ${num(count)}`)
.join(" · ");
return [
"### Memory",
"",
"| Metric | Value |",
"| --- | --- |",
`| location | \`${memory.dir.split("\\").join("/")}\` |`,
`| files | ${num(memory.files)} |`,
`| index entries | ${num(memory.indexEntries)} |`,
`| size | ${humanBytes(memory.bytes)} |`,
`| by type | ${types} |`,
"",
];
};
const docArchLines = function docArchLines(docs: DocArchStats): string[] {
return [
"### doc-arch",
"",
"| Form | Documents |",
COUNT_TABLE_DIVIDER,
...mapRows(docs.byForm, (key) => `\`${key}\``),
"",
"| Status | Documents |",
COUNT_TABLE_DIVIDER,
...mapRows(docs.byStatus, (key) => key),
"",
];
};
const workspaceLines = function workspaceLines(workspace: WorkspaceStats): string[] {
return [
"### Governed modules",
"",
"| Axis | Modules |",
COUNT_TABLE_DIVIDER,
...mapRows(workspace.byAxis, (key) => `\`${key}\``),
"",
"| Maturity | Modules |",
COUNT_TABLE_DIVIDER,
...mapRows(workspace.byMaturity, (key) => key),
"",
];
};
const structuralLines = function structuralLines(findings: FindingsStats, producer: string): string[] {
const head = ["### Structural findings", "", "| Metric | Value |", "| --- | ---: |"];
const base = [
`| producer | \`${producer}\` |`,
`| modules analyzed | ${num(findings.modules)} |`,
`| findings | ${num(findings.total)} |`,
];
if (findings.total === 0) {
return [...head, ...base, ""];
}
return [
...head,
...base,
`| modules with findings | ${num(findings.modulesWithFindings)} |`,
"",
"| Finding kind | Count |",
COUNT_TABLE_DIVIDER,
...mapRows(findings.byKind, (key) => `\`${key}\``),
"",
];
};
const qualityCatalogLines = function qualityCatalogLines(quality: QualityStats): string[] {
if (!quality.available) {
return [];
}
return [
"### Rule catalog",
"",
"| Metric | Value |",
COUNT_TABLE_DIVIDER,
`| producer | \`${quality.producer}\` |`,
`| rules | ${num(quality.totalRules)} |`,
`| tools · ecosystems | ${num(quality.tools)} · ${num(quality.ecosystems)} |`,
`| rules with a canonical concept | ${num(quality.canonicalMapped)} (${pct(quality.canonicalMapped, quality.totalRules)}) |`,
`| canonical concepts | ${num(quality.concepts)} |`,
"",
];
};
export const abstractionSection = function abstractionSection(input: ReportInput, derived: Derived): string[] {
return [
...fileTypeLines(derived),
...ratioLines(input, derived),
...structuralLines(input.findings, input.analysis.producer),
...workspaceLines(input.workspace),
...docArchLines(input.docs),
...memorySection(input.memory),
...qualityCatalogLines(input.quality),
];
};