Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/test-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ jobs:
config: ./fixtures/cspell.json
strict: false
inline: none
summary: true
- name: Show Results
uses: streetsidesoftware/actions/public/summary@v1
with:
Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"search.exclude": {
".git": true,
"**/.yarn": true,
"**/.pnp.*": true
},
"typescript.enablePromptUseWorkspaceTsdk": true,
"git.ignoreLimitWarning": true,
"editor.formatOnSave": false
"editor.formatOnSave": true
}
7 changes: 7 additions & 0 deletions action-src/src/ActionParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ export interface ActionParams {
* default: use default reporting.
*/
report: ReportChoices;

/**
* Include a summary of the results in the output.
*/
summary: TrueFalse;
}

const defaultActionParams: ActionParams = {
Expand All @@ -87,6 +92,7 @@ const defaultActionParams: ActionParams = {
use_cspell_files: 'false',
suggestions: 'false',
report: undefined,
summary: 'false',
};

type ValidationFunction = (params: ActionParamsInput) => string | undefined;
Expand Down Expand Up @@ -153,6 +159,7 @@ export function validateActionParams(
validateTrueFalse('suggestions'),
validateOptions('check_dot_files', ['true', 'false', 'explicit']),
validateOptions('report', ['all', 'simple', 'typos', 'flagged'], true),
validateTrueFalse('summary'),
];
const success = validations
.map((fn) => fn(params))
Expand Down
242 changes: 220 additions & 22 deletions action-src/src/__snapshots__/action.test.ts.snap

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions action-src/src/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,21 @@ function outputResult(runResult: RunResult) {
setOutput('number_of_files_checked', result.number_of_files_checked);
setOutput('number_of_issues', result.number_of_issues);
setOutput('number_of_files_with_issues', result.files_with_issues.length);
setOutput('files_with_issues', normalizeFiles(result.files_with_issues));
setOutput('files_with_issues', result.files_with_issues);
setOutput('number_of_files_skipped', result.number_of_files_skipped);
setOutput('number_of_files_cached', result.number_of_files_cached);
setOutput('result', result);
}

function normalizeResult(result: RunResult) {
const { issues: number_of_issues, files: number_of_files_checked, filesWithIssues } = result;
const { issues: number_of_issues, files, filesWithIssues, skippedFiles = 0, cachedFiles = 0 } = result;
return {
success: !number_of_issues && !result.errors,
errors: result.errors,
number_of_issues,
number_of_files_checked,
number_of_files_checked: files - skippedFiles,
number_of_files_skipped: skippedFiles,
number_of_files_cached: cachedFiles,
files_with_issues: normalizeFiles(filesWithIssues).slice(0, 1000),
};
}
Expand Down
12 changes: 6 additions & 6 deletions action-src/src/checkSpelling.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import { getDefaultLogger, type Logger } from './logger.js';
const { gatherFileGlobsFromContext } = __testing__;

vi.mock('./logger.js', async (importActual) => {
const f = () => {};
const logger: Logger = {
error: vi.fn(f),
debug: vi.fn(f),
info: vi.fn(f),
warning: vi.fn(f),
issueCommand: vi.fn(f),
error: vi.fn(),
debug: vi.fn(),
info: vi.fn(),
warning: vi.fn(),
issueCommand: vi.fn(),
summary: vi.fn(),
};

return {
Expand Down
1 change: 1 addition & 0 deletions action-src/src/checkSpelling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ async function checkSpelling(
const reporterOptions = {
verbose: params.verbose === 'true',
treatFlaggedWordsAsErrors: params.treat_flagged_words_as_errors === 'true',
summary: params.summary === 'true',
};

const collector = new CSpellReporterForGithubAction(params.inline, reporterOptions);
Expand Down
2 changes: 1 addition & 1 deletion action-src/src/getActionParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { tf } from './utils.js';

export function getActionParams(): ActionParamsInput {
const params: ActionParamsInput = {
// github_token: getInput('github_token', { required: true }),
files: getInput('files'),
incremental_files_only: tf(getInput('incremental_files_only')),
config: getInput('config'),
Expand All @@ -18,6 +17,7 @@ export function getActionParams(): ActionParamsInput {
use_cspell_files: tf(getInput('use_cspell_files')),
suggestions: tf(getInput('suggestions')),
report: getInput('report').toLowerCase(),
summary: tf(getInput('summary') || 'false'),
};
return applyDefaults(params);
}
39 changes: 35 additions & 4 deletions action-src/src/logger.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,40 @@
import { describe, expect, test } from 'vitest';
import { summary as coreSummary } from '@actions/core';
import { describe, expect, test, vi } from 'vitest';

import {} from './logger.js';
import { createLogger } from './logger.js';

vi.mock('@actions/core', async (_importActual) => {
return {
debug: vi.fn(),
info: vi.fn(),
warning: vi.fn(),
error: vi.fn(),
issueCommand: vi.fn(),
summary: {
addRaw: vi.fn(),
write: vi.fn(),
},
};
});

describe('Validate Logger', () => {
test('placeholder', () => {
expect(true).toBe(true);
test('createLogger', () => {
const logger = createLogger({ debug: vi.fn() });
expect(logger.debug).toBeDefined();
expect(logger.info).toBeDefined();
expect(logger.warning).toBeDefined();
expect(logger.error).toBeDefined();
expect(logger.issueCommand).toBeDefined();
expect(logger.summary).toBeDefined();

logger.debug('test debug');
expect(logger.debug).toHaveBeenCalledWith('test debug');
});

test('summary', () => {
const logger = createLogger();
logger.summary('test summary');
expect(coreSummary.addRaw).toHaveBeenCalledWith('test summary');
expect(coreSummary.write).toHaveBeenCalled();
});
});
10 changes: 8 additions & 2 deletions action-src/src/logger.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { debug, error, info, warning } from '@actions/core';
import { debug, error, info, summary as coreSummary, warning } from '@actions/core';
import { issueCommand } from '@actions/core/lib/command.js';

export type IssueCommandFn = typeof issueCommand;
Expand All @@ -14,10 +14,16 @@ export interface Logger {
warning: LogErrorFn;
error: LogErrorFn;
issueCommand: IssueCommandFn;
summary: LogFn;
}

function summary(message: string) {
coreSummary.addRaw(message);
coreSummary.write();
}

export function createLogger(logger?: Partial<Logger>): Logger {
return { debug, info, warning, error, issueCommand, ...logger };
return { debug, info, warning, error, issueCommand, summary, ...logger };
}

export function getDefaultLogger(): Logger {
Expand Down
84 changes: 45 additions & 39 deletions action-src/src/reporter.test.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import { describe, expect, test, vi } from 'vitest';
import type { RunResult } from '@cspell/cspell-types';
import { describe, expect, test } from 'vitest';

import { createLogger } from './logger.js';
import { CSpellReporterForGithubAction } from './reporter.js';
import { CSpellReporterForGithubAction, type ReporterOptions } from './reporter.js';
import { mockLogger } from './test/helper.js';

describe('Validate Reporter', () => {
const options: ReporterOptions = { verbose: false, treatFlaggedWordsAsErrors: false, summary: false };

test('Reporting Errors', () => {
const logger = createLogger({
debug: vi.fn(),
info: vi.fn(),
warning: vi.fn(),
error: vi.fn(),
});

const actionReporter = new CSpellReporterForGithubAction(
'none',
{ verbose: false, treatFlaggedWordsAsErrors: true },
logger,
);
const logger = mockLogger();

const actionReporter = new CSpellReporterForGithubAction('none', options, logger);
const reporter = actionReporter.reporter;

reporter.error?.('This is an error message', new Error('Test error'));
Expand All @@ -30,18 +24,9 @@ describe('Validate Reporter', () => {
${'Info'}
`('Info is ignored $msgType', ({ msgType }) => {
// Currently all "info" messages are ignored.
const logger = createLogger({
debug: vi.fn(),
info: vi.fn(),
warning: vi.fn(),
error: vi.fn(),
});

const actionReporter = new CSpellReporterForGithubAction(
'none',
{ verbose: false, treatFlaggedWordsAsErrors: true },
logger,
);
const logger = mockLogger();

const actionReporter = new CSpellReporterForGithubAction('none', options, logger);
const reporter = actionReporter.reporter;

reporter.info?.('This is an error message', msgType);
Expand All @@ -53,18 +38,9 @@ describe('Validate Reporter', () => {

test('Debug is ignored', () => {
// Currently all "debug" messages are ignored.
const logger = createLogger({
debug: vi.fn(),
info: vi.fn(),
warning: vi.fn(),
error: vi.fn(),
});

const actionReporter = new CSpellReporterForGithubAction(
'none',
{ verbose: false, treatFlaggedWordsAsErrors: true },
logger,
);
const logger = mockLogger();

const actionReporter = new CSpellReporterForGithubAction('none', options, logger);
const reporter = actionReporter.reporter;

reporter.debug?.('This is an error message');
Expand All @@ -73,4 +49,34 @@ describe('Validate Reporter', () => {
expect(logger.info).not.toHaveBeenCalled();
expect(logger.warning).not.toHaveBeenCalled();
});

test('Summary', () => {
const logger = mockLogger();

const actionReporter = new CSpellReporterForGithubAction('none', { ...options, summary: true }, logger);

const result: RunResult = {
/** Number of files processed. */
files: 22,
/** Set of files where issues were found. */
filesWithIssues: new Set<string>(),
/** Number of issues found. */
issues: 5,
/** Number of processing errors. */
errors: 1,
/** Number of files that used results from the cache. */
cachedFiles: 1,
/** Number of files that were skipped (not processed). */
skippedFiles: 2,
};
result.filesWithIssues.add('file1.ts');

actionReporter.reporter.result?.(result);

expect(logger.summary).toHaveBeenCalledWith(
expect.stringContaining(
'## CSpell Summary\n\n- **Files checked:** 20\n- **Issues found:** 5\n- **Files with issues:** 1\n',
),
);
});
});
32 changes: 32 additions & 0 deletions action-src/src/reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export type ReportIssueCommand = 'error' | 'warning' | 'none';
export interface ReporterOptions {
verbose: boolean;
treatFlaggedWordsAsErrors: boolean;
summary: boolean;
}

export class CSpellReporterForGithubAction {
Expand All @@ -42,6 +43,7 @@ export class CSpellReporterForGithubAction {
issues: -1,
errors: -1,
cachedFiles: 0,
skippedFiles: 0,
};
finished: boolean = false;
verbose: boolean;
Expand Down Expand Up @@ -133,6 +135,10 @@ ${error.stack}
);
console.warn('%s', `${relative(cwd, item.uri || '')}:${item.row}:${item.col} ${message}`);
});

if (this.options.summary) {
this.logger.summary(genSummary(this.result));
}
}

readonly reporter: CSpellReporter = {
Expand All @@ -154,3 +160,29 @@ function relative(cwd: string, fileUri: string) {
const fsPath = URI.parse(fileUri).fsPath;
return path.relative(cwd, fsPath);
}

function genSummary(result: RunResult): string {
const items = [
`- **Files checked:** ${result.files - (result.skippedFiles || 0)}`,
`- **Issues found:** ${result.issues}`,
`- **Files with issues:** ${result.filesWithIssues.size}`,
];

if (result.errors) {
items.push(`- **Errors encountered:** ${result.errors}`);
}

if (result.skippedFiles) {
items.push(`- **Files skipped:** ${result.skippedFiles}`);
}

if (result.cachedFiles) {
items.push(`- **Files using cache:** ${result.cachedFiles}`);
}

return `\
## CSpell Summary

${items.join('\n')}
`;
}
Loading
Loading