Skip to content

Commit

Permalink
Add github formatter (#6150)
Browse files Browse the repository at this point in the history
  • Loading branch information
ybiquitous committed Jun 20, 2022
1 parent 9420026 commit 2a89b2d
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 5 deletions.
1 change: 1 addition & 0 deletions docs/user-guide/usage/options.md
Expand Up @@ -81,6 +81,7 @@ Specify the formatter to format your results.
Options are:

- `compact` - generates output similar to ESLint's compact formatter
- `github` - generates messages via [workflow commands for GitHub Actions](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions)
- `json` (default for Node API) - generates [JSON](https://www.json.org) that can be consumed by another tool
- `string` (default for CLI) - generates human-readable strings
- `tap` - generates [Test Anything Protocol](http://testanything.org/) output
Expand Down
2 changes: 1 addition & 1 deletion lib/__tests__/__snapshots__/cli.test.js.snap
Expand Up @@ -89,7 +89,7 @@ exports[`CLI --help 1`] = `
--formatter, -f [default: \\"string\\"]
The output formatter: \\"compact\\", \\"json\\", \\"string\\", \\"tap\\", \\"unix\\" or \\"verbose\\".
The output formatter: \\"compact\\", \\"github\\", \\"json\\", \\"string\\", \\"tap\\", \\"unix\\" or \\"verbose\\".
--custom-formatter
Expand Down
2 changes: 1 addition & 1 deletion lib/__tests__/standalone-formatter.test.js
Expand Up @@ -43,6 +43,6 @@ it('standalone with invalid formatter option', async () => {
formatter: 'invalid',
}),
).rejects.toThrow(
'You must use a valid formatter option: "compact", "json", "string", "tap", "unix", "verbose" or a function',
'You must use a valid formatter option: "compact", "github", "json", "string", "tap", "unix", "verbose" or a function',
);
});
38 changes: 38 additions & 0 deletions lib/formatters/__tests__/githubFormatter.test.js
@@ -0,0 +1,38 @@
'use strict';

const githubFormatter = require('../githubFormatter');

test('githubFormatter', () => {
const results = [
{
source: 'path/to/file.css',
warnings: [
{
line: 1,
column: 2,
endLine: 1,
endColumn: 5,
rule: 'foo',
severity: 'error',
text: 'Unexpected "foo" (foo)',
},
],
},
{
source: 'a.css',
warnings: [
{
line: 10,
column: 20,
rule: 'bar',
severity: 'warning',
text: 'Unexpected "bar" (bar)',
},
],
},
];

expect(githubFormatter(results))
.toBe(`::error file=path/to/file.css,line=1,col=2,endLine=1,endColumn=5,title=Stylelint problem::Unexpected "foo" (foo)
::warning file=a.css,line=10,col=20,title=Stylelint problem::Unexpected "bar" (bar)`);
});
20 changes: 20 additions & 0 deletions lib/formatters/githubFormatter.js
@@ -0,0 +1,20 @@
'use strict';

/**
* @see https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions
*
* @type {import('stylelint').Formatter}
*/
module.exports = function githubFormatter(results) {
const title = 'Stylelint problem';

return results
.flatMap(({ source, warnings }) =>
warnings.map(({ line, column, endLine, endColumn, text, severity }) => {
return endLine === undefined
? `::${severity} file=${source},line=${line},col=${column},title=${title}::${text}`
: `::${severity} file=${source},line=${line},col=${column},endLine=${endLine},endColumn=${endColumn},title=${title}::${text}`;
}),
)
.join('\n');
};
1 change: 1 addition & 0 deletions lib/formatters/index.js
Expand Up @@ -7,6 +7,7 @@ const importLazy = _importLazy(require);
/** @type {typeof import('stylelint').formatters} */
const formatters = {
compact: importLazy('./compactFormatter'),
github: importLazy('./githubFormatter'),
json: importLazy('./jsonFormatter'),
string: importLazy('./stringFormatter'),
tap: importLazy('./tapFormatter'),
Expand Down
6 changes: 4 additions & 2 deletions lib/utils/__tests__/getFormatterOptionsText.test.js
Expand Up @@ -3,8 +3,10 @@
const getFormatterOptionsText = require('../getFormatterOptionsText');

it('getFormatterOptionsText', () => {
expect(getFormatterOptionsText()).toBe('"compact", "json", "string", "tap", "unix", "verbose"');
expect(getFormatterOptionsText()).toBe(
'"compact", "github", "json", "string", "tap", "unix", "verbose"',
);
expect(getFormatterOptionsText({ useOr: true })).toBe(
'"compact", "json", "string", "tap", "unix" or "verbose"',
'"compact", "github", "json", "string", "tap", "unix" or "verbose"',
);
});
9 changes: 8 additions & 1 deletion types/stylelint/index.d.ts
Expand Up @@ -128,7 +128,14 @@ declare module 'stylelint' {

export type Formatter = (results: LintResult[], returnValue?: LinterResult) => string;

export type FormatterType = 'compact' | 'json' | 'string' | 'tap' | 'unix' | 'verbose';
export type FormatterType =
| 'compact'
| 'github'
| 'json'
| 'string'
| 'tap'
| 'unix'
| 'verbose';

export type CustomSyntax = string | PostCSS.Syntax;

Expand Down

0 comments on commit 2a89b2d

Please sign in to comment.