Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Custom reporters support #1643

Merged
merged 31 commits into from
Sep 13, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
480da2b
adds support for custom reporters
mad-gooze Sep 5, 2021
f3bd668
fix tests for cspell-types
mad-gooze Sep 6, 2021
b0e2046
CR
mad-gooze Sep 7, 2021
26259c2
Merge remote-tracking branch 'origin/main' into customizable-reporters
mad-gooze Sep 9, 2021
685ea3d
simplify emitters types
mad-gooze Sep 9, 2021
70a7e6b
remove typecast from loadReporters
mad-gooze Sep 9, 2021
7e5a38a
add InMemoryReporter
mad-gooze Sep 9, 2021
0e7917e
update jsdoc
mad-gooze Sep 9, 2021
bf86e41
add ApplicationError
mad-gooze Sep 9, 2021
aeaca39
fix tests
mad-gooze Sep 9, 2021
265d8b4
make only result reporter async
mad-gooze Sep 9, 2021
9607d70
wip tests for cspell-json-reporter
mad-gooze Sep 9, 2021
d4c2158
simplify tests
mad-gooze Sep 10, 2021
b776570
fix lint
mad-gooze Sep 10, 2021
6d5a5a3
fix jest thorw check
mad-gooze Sep 10, 2021
cc431d3
complete tests for cspell-json-reporter
mad-gooze Sep 10, 2021
949cefa
fix lint && add docs
mad-gooze Sep 12, 2021
1c652ba
Merge remote-tracking branch 'origin/main' into customizable-reporters
mad-gooze Sep 12, 2021
fef8915
add getLoggerFromReporter
mad-gooze Sep 12, 2021
b408bb5
fix deps
mad-gooze Sep 12, 2021
eb7db0e
remove paths from snapshots
mad-gooze Sep 12, 2021
fb67ea7
add types for InMemoryReporter
mad-gooze Sep 12, 2021
86728a6
fix deps
mad-gooze Sep 12, 2021
25b84a0
fix ts && lint
mad-gooze Sep 12, 2021
8efbb5b
revert package-locks
mad-gooze Sep 12, 2021
80cee10
cspell-json-reporter: write example output to temp
mad-gooze Sep 12, 2021
524931a
fix tests for node 12
mad-gooze Sep 12, 2021
f055173
create output path if it does not exist
mad-gooze Sep 12, 2021
da53732
add some tests for reporters
mad-gooze Sep 12, 2021
029ac78
fix tests
mad-gooze Sep 12, 2021
ae6c53e
fix lint
mad-gooze Sep 12, 2021
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
35 changes: 35 additions & 0 deletions cspell.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,34 @@
},
"type": "array"
},
"ReporterSettings": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"type": "string"
},
"maxItems": 1,
"minItems": 1,
"type": "array"
},
{
"items": [
{
"type": "string"
},
{
}
],
"maxItems": 2,
"minItems": 2,
"type": "array"
}
],
"description": "reporter name or reporter name + reporter config"
},
"SimpleGlob": {
"description": "Simple Glob string, the root will be globRoot",
"type": "string"
Expand Down Expand Up @@ -858,6 +886,13 @@
"description": "Indicate that the configuration file should not be modified. This is used to prevent tools like the VS Code Spell Checker from modifying the file to add words and other configuration.",
"type": "boolean"
},
"reporters": {
"description": "Custom reporters configuration",
"items": {
"$ref": "#/definitions/ReporterSettings"
},
"type": "array"
},
"showStatus": {
"description": "Show status",
"type": "boolean"
Expand Down
21 changes: 21 additions & 0 deletions packages/cspell-json-reporter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# `@cspell/cspell-json-reporter`
Jason3S marked this conversation as resolved.
Show resolved Hide resolved

> CSpell reporter with JSON output

## Usage

Add this to cSpell.json:

```
reporters: [
['@cspell/cspell-json-reporter', { outFile: 'out.json' }]
]
```

## Output file format

TODO

## Settings

TODO
21 changes: 21 additions & 0 deletions packages/cspell-json-reporter/cSpell.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const path = require('path');

module.exports = {
version: '0.2',
id: 'cspell-project-config',
name: 'cspell Project Config',
language: 'en',
maxNumberOfProblems: 1000,
ignorePaths: [
'*.snap',
'node_modules',
'package-lock.json',
'coverage/**',
'dist/**',
'package.json',
'.cspell.json',
'.vscode/**',
],
ignoreWords: [],
reporters: [[path.join(__dirname, './dist/index'), { outFile: './out.json', debug: false }]],
};
1 change: 1 addition & 0 deletions packages/cspell-json-reporter/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../../jest.config');
49 changes: 49 additions & 0 deletions packages/cspell-json-reporter/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "@cspell/cspell-json-reporter",
"version": "5.9.0",
"description": "JSON reporter for CSpell",
"author": "Jason Dent",
"license": "MIT",
"bugs": {
"url": "https://github.com/streetsidesoftware/cspell/labels/cspell-json-reporter"
},
"homepage": "https://streetsidesoftware.github.io/cspell/tree/main/packages/cspell-json-reporter#readme",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"files": [
"dist",
"!**/__mocks__",
"!**/*.test.*",
"!**/*.spec.*",
"!**/*.map"
],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/streetsidesoftware/cspell.git"
},
"scripts": {
"clean": "rimraf dist temp coverage",
"build": "npm run compile",
"clean-build": "npm run clean && npm run build",
"compile": "tsc -p .",
"watch": "tsc --watch -p .",
"coverage": "jest --coverage",
"test-watch": "jest --watch",
"prepublishOnly": "npm run clean-build && npm test",
"test": "jest",
"update-snapshot": "jest --updateSnapshot"
},
"files:comment": "Due to a lerna bug, patterns like `!**/*.map` are not getting recursively honored",
"dependencies": {
"@cspell/cspell-types": "^5.9.0"
},
"devDependencies": {
"cspell": "^5.9.0"
},
"engines": {
"node": ">=12.0.0"
}
}
28 changes: 28 additions & 0 deletions packages/cspell-json-reporter/src/CSpellJSONReporterOutput.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ErrorLike, Issue, MessageType, ProgressFileComplete, ProgressItem, RunResult } from '@cspell/cspell-types';

export type CSpellJSONReporterOutput = {
/**
* Found spelling issues
*/
issues: Array<Issue>;
/**
* CSpell execution logs
*/
info: Array<{ message: string; msgType: MessageType }>;
/**
* CSpell debug logs
*/
debug: Array<{ message: string }>;
/**
* CSpell error logs
*/
error: Array<{ message: string; error: ErrorLike }>;
/**
* CSpell file progress logs
*/
progress: Array<ProgressItem | ProgressFileComplete>;
/**
* Execution result
*/
result: RunResult;
};
24 changes: 24 additions & 0 deletions packages/cspell-json-reporter/src/CSpellJSONReporterSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* CSpell-json-reporter settings type definition
*/
export type CSpellJSONReporterSettings = {
/**
* Output JSON file path
*/
outFile: string;
/**
* Add more information about the files being checked and the configuration
* @default false
*/
verbose?: boolean;
/**
* Add information useful for debugging cspell.json files
* @default false
*/
debug?: boolean;
/**
* Add progress messages
mad-gooze marked this conversation as resolved.
Show resolved Hide resolved
* @default false
*/
progress?: boolean;
};
55 changes: 55 additions & 0 deletions packages/cspell-json-reporter/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import * as fs from 'fs/promises';
import * as path from 'path';

import { CSpellReporter, MessageTypes } from '@cspell/cspell-types';
import { validateSettings } from './utils/validateSettings';
import { setToJSONReplacer } from './utils/setToJSONReplacer';
import { CSpellJSONReporterOutput } from './CSpellJSONReporterOutput';

const noopReporter = () => undefined;

export function getReporter(settings: unknown): CSpellReporter {
validateSettings(settings);
const reportData: Omit<CSpellJSONReporterOutput, 'result'> = {
issues: [],
info: [],
debug: [],
error: [],
progress: [],
};
return {
issue: (issue) => {
reportData.issues.push(issue);
},
info: (message, msgType) => {
if (msgType === MessageTypes.Debug && !settings.debug) {
return;
}
if (msgType === MessageTypes.Info && !settings.verbose) {
return;
}
reportData.info.push({ message, msgType });
},
debug: settings.debug
? (message) => {
reportData.debug.push({ message });
}
: noopReporter,
error: (message, error) => {
reportData.error.push({ message, error });
},
progress: settings.progress
? (item) => {
reportData.progress.push(item);
}
: noopReporter,
result: (result) => {
const outFilePath = path.join(process.cwd(), settings.outFile);
const output = {
...reportData,
result,
};
return fs.writeFile(outFilePath, JSON.stringify(output, setToJSONReplacer, 4));
},
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`setToJSONReplacer converts Set to Array 1`] = `"{\\"foo\\":[\\"foo\\",\\"bar\\",123]}"`;

exports[`setToJSONReplacer ignores other values 1`] = `"{\\"123\\":\\"1\\",\\"foo\\":\\"bar\\",\\"obj\\":{\\"key\\":\\"value\\"},\\"array\\":[1,2,3]}"`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`validateSettings throws for invalid settings 1`] = `"cspell-json-reporter settings.outFile must be a string"`;

exports[`validateSettings throws for invalid settings 2`] = `"cspell-json-reporter settings.outFile must be a string"`;

exports[`validateSettings throws for invalid settings 3`] = `"cspell-json-reporter settings.verbose must be a boolean"`;

exports[`validateSettings throws for invalid settings 4`] = `"cspell-json-reporter settings.debug must be a boolean"`;
20 changes: 20 additions & 0 deletions packages/cspell-json-reporter/src/utils/setToJSONReplacer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { setToJSONReplacer } from "./setToJSONReplacer";

describe('setToJSONReplacer', () => {
it('converts Set to Array', () => {
const input = {
foo: new Set(['foo', 'bar', 123]),
};
expect(JSON.stringify(input, setToJSONReplacer)).toMatchSnapshot();
});

it('ignores other values', () => {
const input = {
foo: 'bar',
'123': '1',
obj: { key: 'value' },
array: [1, 2, 3],
};
expect(JSON.stringify(input, setToJSONReplacer)).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions packages/cspell-json-reporter/src/utils/setToJSONReplacer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* JSON.stringify replacer which converts Set to Array to allow serialization
*/
export function setToJSONReplacer(_: string, value: unknown): unknown {
if (typeof value === 'object' && value instanceof Set) {
return [...value];
}
return value;
}
29 changes: 29 additions & 0 deletions packages/cspell-json-reporter/src/utils/validateSettings.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { CSpellJSONReporterSettings } from "../CSpellJSONReporterSettings";
import { validateSettings } from "./validateSettings";

describe('validateSettings', () => {
it('passes valid settings', () => {
mad-gooze marked this conversation as resolved.
Show resolved Hide resolved
const valid: CSpellJSONReporterSettings[] = [
{ outFile: 'foobar' },
{ outFile: 'foobar', verbose: true },
{ outFile: 'foobar', debug: false },
{ outFile: 'foobar', progress: true },
{ outFile: 'foobar', verbose: undefined },
];
valid.forEach((settings) => {
expect(validateSettings(settings)).toEqual(undefined);
});
});

it('throws for invalid settings', () => {
const invalid = [
{ },
{ outFile: 1 },
{ outFile: 'foobar', verbose: 123 },
{ outFile: 'foobar', debug: [] },
];
invalid.forEach((settings) => {
expect(() => validateSettings(settings)).toThrowErrorMatchingSnapshot();
});
});
});
39 changes: 39 additions & 0 deletions packages/cspell-json-reporter/src/utils/validateSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { AssertionError } from 'assert';
import { CSpellJSONReporterSettings } from '../CSpellJSONReporterSettings';

function assertBooleanOrUndefined(key: string, value: unknown): asserts value is boolean | undefined {
if (typeof value !== 'boolean' && value !== undefined) {
throw new AssertionError({
message: `cspell-json-reporter settings.${key} must be a boolean`,
actual: typeof value,
expected: 'boolean',
});
}
}

/**
* Throws an error if passed cspell-json-reporter settings are invalid
*/
export function validateSettings(settings: unknown): asserts settings is CSpellJSONReporterSettings {
mad-gooze marked this conversation as resolved.
Show resolved Hide resolved
if (!settings || typeof settings !== 'object') {
throw new AssertionError({
message: 'cspell-json-reporter settings must be an object',
actual: typeof settings,
expected: 'object',
});
}

const { outFile, debug, verbose, progress } = settings as CSpellJSONReporterSettings;

if (typeof outFile !== 'string') {
throw new AssertionError({
message: 'cspell-json-reporter settings.outFile must be a string',
actual: typeof outFile,
expected: 'string',
});
}

assertBooleanOrUndefined('verbose', verbose);
assertBooleanOrUndefined('debug', debug);
assertBooleanOrUndefined('progress', progress);
}
Loading