Skip to content

Commit

Permalink
fix: Update cspell and use the new CSpellReporter (#380)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason3S committed Sep 27, 2021
1 parent f147d33 commit 8a67338
Show file tree
Hide file tree
Showing 118 changed files with 4,028 additions and 2,541 deletions.
15 changes: 8 additions & 7 deletions action-src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,26 @@
"@pollyjs/adapter-node-http": "^5.1.1",
"@pollyjs/core": "^5.1.1",
"@pollyjs/persister-fs": "^5.1.1",
"@types/jest": "^27.0.1",
"@types/jest": "^27.0.2",
"@types/minimatch": "^3.0.5",
"@types/pollyjs__adapter-node-http": "^2.0.1",
"@types/pollyjs__core": "^4.3.3",
"@types/pollyjs__persister-fs": "^2.0.1",
"env-cmd": "^10.1.0",
"jest": "^27.1.0",
"jest": "^27.2.2",
"rimraf": "^3.0.2",
"standard-version": "^9.3.1",
"ts-jest": "^27.0.5",
"typescript": "^4.4.2"
"typescript": "^4.4.3"
},
"dependencies": {
"@actions/core": "^1.5.0",
"@actions/github": "^5.0.0",
"@octokit/core": "^3.5.1",
"@octokit/plugin-rest-endpoint-methods": "^5.8.0",
"@octokit/rest": "^18.9.1",
"cspell": "^5.9.0",
"cspell-glob": "^5.9.0"
"@octokit/plugin-rest-endpoint-methods": "^5.11.2",
"@octokit/rest": "^18.11.1",
"cspell": "^5.10.1",
"cspell-glob": "^5.10.0",
"vscode-uri": "^3.0.2"
}
}
8 changes: 4 additions & 4 deletions action-src/src/action.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ describe('Validate Action', () => {
timeout
);
test.each`
files | warningsExpected | expected
${'**'} | ${[]} | ${false}
${'**/*.md'} | ${[]} | ${true}
files | expected
${'**'} | ${false}
${'**/*.md'} | ${true}
`(
'check all $files',
async ({ files, warningsExpected, expected }) => {
async ({ files, expected }) => {
const warnings: string[] = [];
spyWarn.mockImplementation((msg: string) => warnings.push(msg));
const context = createContextFromFile('pull_request.json', {
Expand Down
38 changes: 11 additions & 27 deletions action-src/src/action.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import * as core from '@actions/core';
import { issueCommand } from '@actions/core/lib/command';
import { Context as GitHubContext } from '@actions/github/lib/context';
import { fetchFilesForCommits, getPullRequestFiles } from './github';
import { Octokit } from '@octokit/core';
import { lint, LintOptions } from './spell';
import * as path from 'path';
import { format } from 'util';
import { AppError } from './error';
import { RunResult } from 'cspell';
import * as glob from 'cspell-glob';
import { existsSync } from 'fs';
import { RunResult } from 'cspell';
import { format } from 'util';
import { AppError } from './error';
import { fetchFilesForCommits, getPullRequestFiles } from './github';
import { CSpellReporterForGithubAction } from './reporter';
import { lint, LintOptions } from './spell';

interface Context {
githubContext: GitHubContext;
Expand Down Expand Up @@ -81,26 +80,11 @@ async function checkSpelling(params: ValidActionParams, files: string[]): Promis
if (!files.length) {
return true;
}
const result = await lint(files, options, core);
if (params.inline !== 'none') {
const command = params.inline;
result.issues.forEach((item) => {
// format: ::warning file={name},line={line},col={col}::{message}
issueCommand(
command,
{
file: path.relative(process.cwd(), item.uri || ''),
line: item.row,
col: item.col,
},
`Unknown word (${item.text})`
);
console.warn(
`${path.relative(process.cwd(), item.uri || '')}:${item.row}:${item.col} Unknown word (${item.text})`
);
});
}
return result.result;

const collector = new CSpellReporterForGithubAction(params.inline, core);
await lint(files, options, collector.reporter);

return collector.result;
}

function friendlyEventName(eventName: EventNames | string): string {
Expand Down
2 changes: 1 addition & 1 deletion action-src/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import * as core from '@actions/core';
import { getOctokit } from '@actions/github';
import { Context } from '@actions/github/lib/context';
import { AppError, isAppError, isError } from './error';
import { isAppError, isError } from './error';
import { action } from './action';
import { format } from 'util';

Expand Down
134 changes: 134 additions & 0 deletions action-src/src/reporter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import * as core from '@actions/core';
import { issueCommand } from '@actions/core/lib/command';
import type {
CSpellReporter,
Issue,
MessageType,
ProgressItem,
RunResult,
ProgressFileComplete,
} from '@cspell/cspell-types';
import { URI } from 'vscode-uri';
import * as path from 'path';

export interface LintResult {
issues: Issue[];
result: RunResult;
}

type LogFn = (message: string) => void;
export interface Logger {
debug: LogFn;
info: LogFn;
warning: LogFn;
error: LogFn;
}

export interface LintOptions {
root: string;
config?: string;
}

function nullEmitter(_msg: string) {
/* Do Nothings */
}

export type ReportIssueCommand = 'error' | 'warning' | 'none';

export class CSpellReporterForGithubAction {
readonly issues: Issue[] = [];
readonly issueCounts = new Map<string, number>();
readonly result: RunResult = {
files: -1,
filesWithIssues: new Set(),
issues: -1,
errors: -1,
};
finished: boolean = false;

constructor(readonly reportIssueCommand: ReportIssueCommand, readonly logger: Logger = core) {}

_issue(issue: Issue) {
const { issues, issueCounts } = this;
const uri = issue.uri;
uri && issueCounts.set(uri, (issueCounts.get(uri) || 0) + 1);
issues.push(issue);
}

_info(message: string, _msgType: MessageType) {
this._debug(message);
}

_debug(message: string) {
nullEmitter(message);
// logger.debug(message);
}

_progress(progress: ProgressItem | ProgressFileComplete) {
if (!isProgressFileComplete(progress)) {
return;
}
const { issueCounts, logger } = this;

const issueCount = issueCounts.get(progress.filename) || 0;
const { fileNum, fileCount, filename, elapsedTimeMs } = progress;
const issues = issueCount ? ` issues: ${issueCount}` : '';
const timeMsg = elapsedTimeMs ? `(${elapsedTimeMs.toFixed(2)}ms)` : '-';
logger.info(`${fileNum}/${fileCount} ${filename}${issues} ${timeMsg}`);
}

_error(message: string, error: Error) {
const { logger } = this;
logger.error(`${message}
name: ${error.name}
msg: ${error.message}
stack:
${error.stack}
`);
return;
}

_result(result: RunResult) {
Object.assign(this.result, result);
this.finished = true;
const command = this.reportIssueCommand;

if (!['error', 'warning'].includes(command)) {
return;
}

const cwd = process.cwd();

this.issues.forEach((item) => {
// format: ::warning file={name},line={line},col={col}::{message}
issueCommand(
command,
{
file: relative(cwd, item.uri || ''),
line: item.row,
col: item.col,
},
`Unknown word (${item.text})`
);
console.warn(`${relative(cwd, item.uri || '')}:${item.row}:${item.col} Unknown word (${item.text})`);
});
}

readonly reporter: CSpellReporter = {
debug: (...args) => this._debug(...args),
error: (...args) => this._error(...args),
info: (...args) => this._info(...args),
issue: (...args) => this._issue(...args),
progress: (...args) => this._progress(...args),
result: (...args) => this._result(...args),
};
}

function isProgressFileComplete(p: ProgressItem): p is ProgressFileComplete {
return p.type === 'ProgressFileComplete';
}

function relative(cwd: string, fileUri: string) {
const fsPath = URI.parse(fileUri).fsPath;
return path.relative(cwd, fsPath);
}
8 changes: 5 additions & 3 deletions action-src/src/spell.test.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import * as spell from './spell';
import * as path from 'path';
import { root } from './test/helper';
import { CSpellReporterForGithubAction, Logger } from './reporter';

describe('Validate Spell Checking', () => {
test('Linting some files', async () => {
const options = {
root,
};
const f = () => {};
const emitters = {
const logger: Logger = {
error: jest.fn(f),
debug: jest.fn(f),
info: jest.fn(f),
warning: jest.fn(f),
};
const r = await spell.lint(['action-src/src/spell.ts', 'fixtures/sampleCode/ts/**/*.ts'], options, emitters);
const reporter = new CSpellReporterForGithubAction('none', logger);
await spell.lint(['action-src/src/spell.ts', 'fixtures/sampleCode/ts/**/*.ts'], options, reporter.reporter);
const r = reporter;
expect(r.result.files).toBe(2);
expect(r.result.issues).toBe(0);
expect(r.result.filesWithIssues.size).toBe(0);
Expand Down
92 changes: 9 additions & 83 deletions action-src/src/spell.ts
Original file line number Diff line number Diff line change
@@ -1,93 +1,19 @@
import * as cspellApp from 'cspell';
import {
Emitters,
MessageType,
Issue,
RunResult,
isProgressFileComplete,
ProgressItem,
ProgressFileComplete,
} from 'cspell';

export interface LintResult {
issues: Issue[];
result: RunResult;
}

type LogFn = (message: string) => void;
export interface Logger {
debug: LogFn;
info: LogFn;
warning: LogFn;
error: LogFn;
}
import { CSpellReporter } from 'cspell';

export interface LintOptions {
root: string;
config?: string;
}

function nullEmitter(_msg: string) {
/* Do Nothings */
}

/**
*
* @param files files or glob patterns to check
* @param root the root directory to scan
* @param logger logger functions.
* Spell check files.
* @param files - files or glob patterns to check
* @param root - the root directory to scan
* @param reporter - reporter to use.
*/
export async function lint(files: string[], lintOptions: LintOptions, logger: Logger): Promise<LintResult> {
const issues: Issue[] = [];

const issueCounts = new Map<string, number>();

function issue(issue: Issue) {
const uri = issue.uri;
uri && issueCounts.set(uri, (issueCounts.get(uri) || 0) + 1);
issues.push(issue);
}
function info(message: string, _msgType: MessageType) {
debug(message);
}
function debug(message: string) {
nullEmitter(message);
// logger.debug(message);
}
function progress(progress: ProgressItem | ProgressFileComplete) {
if (!isProgressFileComplete(progress)) {
return;
}

const issueCount = issueCounts.get(progress.filename) || 0;
const { fileNum, fileCount, filename, elapsedTimeMs } = progress;
const issues = issueCount ? ` issues: ${issueCount}` : '';
const timeMsg = elapsedTimeMs ? `(${elapsedTimeMs.toFixed(2)}ms)` : '-';
logger.info(`${fileNum}/${fileCount} ${filename}${issues} ${timeMsg}`);
}

function error(message: string, error: Error) {
logger.error(`${message}
name: ${error.name}
msg: ${error.message}
stack:
${error.stack}
`);
return;
}

const emitters: Emitters = {
issue,
info,
debug,
error,
progress,
};

const options: cspellApp.CSpellApplicationOptions = { ...lintOptions };
const result = await cspellApp.lint(files, options, emitters);
return {
issues,
result,
};
export async function lint(files: string[], lintOptions: LintOptions, reporter: CSpellReporter): Promise<void> {
const { root, config } = lintOptions;
const options: cspellApp.CSpellApplicationOptions = { root, config };
await cspellApp.lint(files, options, reporter);
}
Loading

0 comments on commit 8a67338

Please sign in to comment.