Skip to content

Commit 18db831

Browse files
committed
feat(plugin-jsdocs): log initializer and runner steps
1 parent 2e70bf4 commit 18db831

File tree

15 files changed

+219
-58
lines changed

15 files changed

+219
-58
lines changed

code-pushup.preset.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ import eslintPlugin, {
1515
} from './packages/plugin-eslint/src/index.js';
1616
import jsPackagesPlugin from './packages/plugin-js-packages/src/index.js';
1717
import jsDocsPlugin from './packages/plugin-jsdocs/src/index.js';
18-
import {
19-
PLUGIN_SLUG,
20-
groups,
21-
} from './packages/plugin-jsdocs/src/lib/constants.js';
2218
import {
2319
lighthouseCategories,
2420
lighthouseGroupRef,
@@ -185,12 +181,14 @@ export function configureJsDocsPlugin(projectName?: string): CoreConfig {
185181
slug: 'docs',
186182
title: 'Documentation',
187183
description: 'Measures how much of your code is **documented**.',
188-
refs: groups.map(group => ({
189-
weight: 1,
190-
type: 'group',
191-
plugin: PLUGIN_SLUG,
192-
slug: group.slug,
193-
})),
184+
refs: [
185+
{
186+
type: 'group',
187+
plugin: 'jsdocs',
188+
slug: 'documentation-coverage',
189+
weight: 1,
190+
},
191+
],
194192
},
195193
],
196194
};

e2e/plugin-jsdocs-e2e/tests/__snapshots__/collect.e2e.test.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ exports[`PLUGIN collect report with jsdocs-plugin NPM package > should run JSDoc
567567
],
568568
"icon": "folder-docs",
569569
"slug": "jsdocs",
570-
"title": "JSDoc coverage",
570+
"title": "JSDocs coverage",
571571
},
572572
],
573573
}

packages/plugin-coverage/src/lib/runner/lcov/lcov-runner.ts

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ import type { LCOVRecord } from 'parse-lcov';
33
import type { AuditOutputs, TableColumnObject } from '@code-pushup/models';
44
import {
55
type FileCoverage,
6+
aggregateCoverageStats,
67
capitalize,
78
exists,
89
formatAsciiTable,
10+
formatCoveragePercentage,
911
getGitRoot,
1012
logger,
1113
objectFromEntries,
@@ -210,7 +212,7 @@ function logLcovRecords(recordsPerReport: Record<string, LCOVRecord[]>): void {
210212
const stats: Record<CoverageType, string> = objectFromEntries(
211213
objectToEntries(groups).map(([type, files = []]) => [
212214
type,
213-
formatCoverageSum(files),
215+
formatCoveragePercentage(aggregateCoverageStats(files)),
214216
]),
215217
);
216218
const report = truncatedPaths[idx] ?? reportPath;
@@ -222,25 +224,6 @@ function logLcovRecords(recordsPerReport: Record<string, LCOVRecord[]>): void {
222224
logger.newline();
223225
}
224226

225-
function formatCoverageSum(files: FileCoverage[]): string {
226-
const { covered, total } = files.reduce<
227-
Pick<FileCoverage, 'covered' | 'total'>
228-
>(
229-
(acc, file) => ({
230-
covered: acc.covered + file.covered,
231-
total: acc.total + file.total,
232-
}),
233-
{ covered: 0, total: 0 },
234-
);
235-
236-
if (total === 0) {
237-
return 'n/a';
238-
}
239-
240-
const percentage = (covered / total) * 100;
241-
return `${percentage.toFixed(1)}%`;
242-
}
243-
244227
function logMergedRecords(counts: { before: number; after: number }): void {
245228
if (counts.before === counts.after) {
246229
logger.debug(

packages/plugin-jsdocs/src/lib/constants.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import type { Audit, Group } from '@code-pushup/models';
22
import type { AuditSlug } from './models.js';
33

44
export const PLUGIN_SLUG = 'jsdocs';
5+
export const PLUGIN_TITLE = 'JSDocs coverage';
6+
export const PLUGIN_DESCRIPTION = 'Official Code PushUp JSDoc coverage plugin.';
7+
export const PLUGIN_DOCS_URL =
8+
'https://www.npmjs.com/package/@code-pushup/jsdocs-plugin/';
59

610
export const AUDITS_MAP: Record<AuditSlug, Audit> = {
711
'classes-coverage': {
@@ -46,7 +50,7 @@ export const AUDITS_MAP: Record<AuditSlug, Audit> = {
4650
},
4751
} as const;
4852

49-
export const groups: Group[] = [
53+
export const GROUPS: Group[] = [
5054
{
5155
slug: 'documentation-coverage',
5256
title: 'Documentation coverage',
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { pluginMetaLogFormatter } from '@code-pushup/utils';
2+
import { PLUGIN_TITLE } from './constants.js';
3+
4+
export const formatMetaLog = pluginMetaLogFormatter(PLUGIN_TITLE);

packages/plugin-jsdocs/src/lib/jsdocs-plugin.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import { type PluginConfig, validate } from '@code-pushup/models';
22
import { type JsDocsPluginConfig, jsDocsPluginConfigSchema } from './config.js';
3-
import { PLUGIN_SLUG, groups } from './constants.js';
3+
import {
4+
GROUPS,
5+
PLUGIN_DESCRIPTION,
6+
PLUGIN_DOCS_URL,
7+
PLUGIN_SLUG,
8+
PLUGIN_TITLE,
9+
} from './constants.js';
410
import { createRunnerFunction } from './runner/runner.js';
511
import {
612
filterAuditsByPluginConfig,
713
filterGroupsByOnlyAudits,
14+
logAuditsAndGroups,
815
} from './utils.js';
916

10-
export const PLUGIN_TITLE = 'JSDoc coverage';
11-
12-
export const PLUGIN_DESCRIPTION = 'Official Code PushUp JSDoc coverage plugin.';
13-
14-
export const PLUGIN_DOCS_URL =
15-
'https://www.npmjs.com/package/@code-pushup/jsdocs-plugin/';
16-
1717
/**
1818
* Instantiates Code PushUp documentation coverage plugin for core config.
1919
*
@@ -34,14 +34,19 @@ export function jsDocsPlugin(config: JsDocsPluginConfig): PluginConfig {
3434
const jsDocsConfig = validate(jsDocsPluginConfigSchema, config);
3535
const scoreTargets = jsDocsConfig.scoreTargets;
3636

37+
const groups = filterGroupsByOnlyAudits(GROUPS, jsDocsConfig);
38+
const audits = filterAuditsByPluginConfig(jsDocsConfig);
39+
40+
logAuditsAndGroups(audits, groups);
41+
3742
return {
3843
slug: PLUGIN_SLUG,
3944
title: PLUGIN_TITLE,
4045
icon: 'folder-docs',
4146
description: PLUGIN_DESCRIPTION,
4247
docsUrl: PLUGIN_DOCS_URL,
43-
groups: filterGroupsByOnlyAudits(groups, jsDocsConfig),
44-
audits: filterAuditsByPluginConfig(jsDocsConfig),
48+
groups,
49+
audits,
4550
runner: createRunnerFunction(jsDocsConfig),
4651
...(scoreTargets && { scoreTargets }),
4752
};

packages/plugin-jsdocs/src/lib/jsdocs-plugin.unit.test.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
import { describe, expect, it, vi } from 'vitest';
22
import { pluginConfigSchema } from '@code-pushup/models';
3-
import { PLUGIN_SLUG, groups } from './constants.js';
43
import {
4+
GROUPS,
55
PLUGIN_DESCRIPTION,
66
PLUGIN_DOCS_URL,
7+
PLUGIN_SLUG,
78
PLUGIN_TITLE,
8-
jsDocsPlugin,
9-
} from './jsdocs-plugin.js';
9+
} from './constants.js';
10+
import { jsDocsPlugin } from './jsdocs-plugin.js';
1011
import { createRunnerFunction } from './runner/runner.js';
1112
import {
1213
filterAuditsByPluginConfig,
1314
filterGroupsByOnlyAudits,
1415
} from './utils.js';
1516

16-
vi.mock('./utils.js', () => ({
17+
vi.mock('./utils.js', async () => ({
18+
...(await vi.importActual('./utils.js')),
1719
filterAuditsByPluginConfig: vi.fn().mockReturnValue([
1820
{
1921
slug: 'mock-audit',
@@ -69,7 +71,7 @@ describe('jsDocsPlugin', () => {
6971
const config = { patterns: ['src/**/*.ts'] };
7072
jsDocsPlugin(config);
7173

72-
expect(filterGroupsByOnlyAudits).toHaveBeenCalledWith(groups, config);
74+
expect(filterGroupsByOnlyAudits).toHaveBeenCalledWith(GROUPS, config);
7375
});
7476

7577
it('should filter audits', async () => {

packages/plugin-jsdocs/src/lib/runner/doc-processor.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import type { CoverageType } from './models.js';
1616
import {
1717
createInitialCoverageTypesRecord,
1818
getCoverageTypeFromKind,
19+
logReport,
20+
logSourceFiles,
1921
singularCoverageType,
2022
} from './utils.js';
2123

@@ -29,7 +31,7 @@ type Node = {
2931

3032
/**
3133
* Gets the variables information from the variable statements
32-
* @param variableStatements - The variable statements to process
34+
* @param variableStatements The variable statements to process
3335
* @returns The variables information with the right methods to get the information
3436
*/
3537
export function getVariablesInformation(
@@ -54,15 +56,23 @@ export function getVariablesInformation(
5456

5557
/**
5658
* Processes documentation coverage for TypeScript files in the specified path
57-
* @param config - The configuration object containing patterns to include for documentation analysis
59+
* @param config The configuration object containing patterns to include for documentation analysis
5860
* @returns Object containing coverage statistics and undocumented items
5961
*/
6062
export function processJsDocs(
6163
config: JsDocsPluginTransformedConfig,
6264
): Record<CoverageType, FileCoverage[]> {
6365
const project = new Project();
6466
project.addSourceFilesAtPaths(config.patterns);
65-
return getDocumentationReport(project.getSourceFiles());
67+
const sourceFiles = project.getSourceFiles();
68+
69+
logSourceFiles(sourceFiles, config);
70+
71+
const report = getDocumentationReport(sourceFiles);
72+
73+
logReport(report);
74+
75+
return report;
6676
}
6777

6878
export function getAllNodesFromASourceFile(sourceFile: SourceFile) {
@@ -80,7 +90,7 @@ export function getAllNodesFromASourceFile(sourceFile: SourceFile) {
8090

8191
/**
8292
* Gets the documentation coverage report from the source files
83-
* @param sourceFiles - The source files to process
93+
* @param sourceFiles The source files to process
8494
* @returns The documentation coverage report
8595
*/
8696
export function getDocumentationReport(
@@ -101,8 +111,8 @@ export function getDocumentationReport(
101111

102112
/**
103113
* Gets the coverage from all nodes of a file
104-
* @param nodes - The nodes to process
105-
* @param filePath - The file path where the nodes are located
114+
* @param nodes The nodes to process
115+
* @param filePath The file path where the nodes are located
106116
* @returns The coverage report for the nodes
107117
*/
108118
function getCoverageFromAllNodesOfFile(nodes: Node[], filePath: string) {
@@ -145,7 +155,7 @@ function getCoverageFromAllNodesOfFile(nodes: Node[], filePath: string) {
145155

146156
/**
147157
* Gets the nodes from a class
148-
* @param classNodes - The class nodes to process
158+
* @param classNodes The class nodes to process
149159
* @returns The nodes from the class
150160
*/
151161
export function getClassNodes(classNodes: ClassDeclaration[]) {

packages/plugin-jsdocs/src/lib/runner/utils.ts

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
1-
import { SyntaxKind } from 'ts-morph';
1+
import { type SourceFile, SyntaxKind } from 'ts-morph';
2+
import {
3+
type FileCoverage,
4+
aggregateCoverageStats,
5+
capitalize,
6+
formatAsciiTable,
7+
formatCoveragePercentage,
8+
logger,
9+
objectToEntries,
10+
pluralize,
11+
pluralizeToken,
12+
toArray,
13+
} from '@code-pushup/utils';
14+
import type { JsDocsPluginTransformedConfig } from '../config.js';
215
import { SYNTAX_COVERAGE_MAP } from './constants.js';
316
import type { CoverageType } from './models.js';
417

@@ -70,3 +83,44 @@ export function singularCoverageType(type: CoverageType): string {
7083
return 'variable';
7184
}
7285
}
86+
87+
export function logSourceFiles(
88+
sourceFiles: SourceFile[],
89+
config: JsDocsPluginTransformedConfig,
90+
): void {
91+
const patterns = toArray(config.patterns);
92+
logger.info(
93+
`Found ${pluralizeToken('source file', sourceFiles.length)} matching ${pluralize('pattern', patterns.length)} ${patterns.join(' ')}`,
94+
);
95+
}
96+
97+
export function logReport(report: Record<CoverageType, FileCoverage[]>): void {
98+
const typesCount = Object.keys(report).length;
99+
logger.info(
100+
`Collected documentation coverage for ${pluralizeToken('type', typesCount)} of ${pluralize('entity', typesCount)}`,
101+
);
102+
if (!logger.isVerbose()) {
103+
return;
104+
}
105+
106+
logger.debug(
107+
formatAsciiTable({
108+
columns: [
109+
{ key: 'type', label: 'Entity', align: 'left' },
110+
{ key: 'covered', label: 'Hits', align: 'right' },
111+
{ key: 'total', label: 'Found', align: 'right' },
112+
{ key: 'coverage', label: 'Coverage', align: 'right' },
113+
],
114+
rows: objectToEntries(report)
115+
.map(([type, files]) => {
116+
const stats = aggregateCoverageStats(files);
117+
return {
118+
...stats,
119+
type: capitalize(type),
120+
coverage: formatCoveragePercentage(stats),
121+
};
122+
})
123+
.toSorted((a, b) => b.total - a.total),
124+
}),
125+
);
126+
}

packages/plugin-jsdocs/src/lib/utils.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type { Audit, Group } from '@code-pushup/models';
2+
import { logger, pluralizeToken } from '@code-pushup/utils';
23
import type { JsDocsPluginTransformedConfig } from './config.js';
3-
import { AUDITS_MAP } from './constants.js';
4+
import { AUDITS_MAP, GROUPS } from './constants.js';
5+
import { formatMetaLog } from './format.js';
46

57
/**
68
* Get audits based on the configuration.
@@ -50,3 +52,30 @@ export function filterGroupsByOnlyAudits(
5052
}))
5153
.filter(group => group.refs.length > 0);
5254
}
55+
56+
export function logAuditsAndGroups(audits: Audit[], groups: Group[]) {
57+
logger.info(
58+
formatMetaLog(
59+
`Created ${pluralizeToken('audit', audits.length)} and ${pluralizeToken('group', groups.length)}`,
60+
),
61+
);
62+
const skippedAudits = Object.keys(AUDITS_MAP).filter(
63+
slug => !audits.some(audit => audit.slug === slug),
64+
);
65+
const skippedGroups = GROUPS.filter(
66+
group => !groups.some(({ slug }) => slug === group.slug),
67+
);
68+
if (skippedAudits.length > 0) {
69+
logger.info(
70+
formatMetaLog(
71+
[
72+
`Skipped ${pluralizeToken('audit', skippedAudits.length)}`,
73+
skippedGroups.length > 0 &&
74+
pluralizeToken('group', skippedGroups.length),
75+
]
76+
.filter(Boolean)
77+
.join(' and '),
78+
),
79+
);
80+
}
81+
}

0 commit comments

Comments
 (0)