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: support async formatter #15243

Merged
merged 12 commits into from Nov 24, 2021
2 changes: 1 addition & 1 deletion docs/developer-guide/nodejs-api.md
Expand Up @@ -404,7 +404,7 @@ This edit information means replacing the range of the `range` property by the `

The `Formatter` value is the object to convert the [LintResult] objects to text. The [eslint.loadFormatter()][eslint-loadformatter] method returns it. It has the following method:

* `format` (`(results: LintResult[]) => string`)<br>
* `format` (`(results: LintResult[]) => string | Promise<string>`)<br>
The method to convert the [LintResult] objects to text.

---
Expand Down
10 changes: 10 additions & 0 deletions docs/developer-guide/working-with-custom-formatters.md
Expand Up @@ -11,6 +11,16 @@ module.exports = function(results) {
};
```

Formatter can also be an async function (from ESLint 8.2.0), the following shows a simple example:
fengzilong marked this conversation as resolved.
Show resolved Hide resolved

```js
//my-awesome-formatter.js
module.exports = async function(results) {
const formatted = await asyncTask();
return formatted;
};
```

To run ESLint with this formatter, you can use the `-f` (or `--format`) command line flag:

```bash
Expand Down
2 changes: 1 addition & 1 deletion lib/cli.js
Expand Up @@ -178,7 +178,7 @@ async function printResults(engine, results, format, outputFile) {
return false;
}

const output = formatter.format(results);
const output = await formatter.format(results);

if (output) {
if (outputFile) {
Expand Down
4 changes: 4 additions & 0 deletions tests/fixtures/async-formatter.js
@@ -0,0 +1,4 @@
/*global module*/
module.exports = function(results) {
return Promise.resolve('from async formatter');
};
11 changes: 11 additions & 0 deletions tests/lib/cli.js
Expand Up @@ -287,6 +287,17 @@ describe("cli", () => {
});
});

describe("when given an async formatter path", () => {
it("should execute without any errors", async () => {
const formatterPath = getFixturePath("async-formatter.js");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const formatterPath = getFixturePath("async-formatter.js");
const formatterPath = getFixturePath("formatters", "async-formatter.js");

Can we move this file to fixtures/formatters/, where the other formatters are?

Copy link
Contributor Author

@fengzilong fengzilong Nov 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did it before, but putting that file to fixtures/formatters/ made other tests fail, not sure why. I'll try it again

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears that we're using files in fixtures/formatters/ as source code files in some tests, so whenever we add a fixture formatter to test how the formatters feature works, we have to update some unrelated tests that are linting those files.

I'll fix this in a follow-up.

const filePath = getFixturePath("passing.js");
const exit = await cli.execute(`-f ${formatterPath} ${filePath}`);

assert.strictEqual(log.info.getCall(0).args[0], "from async formatter");
assert.strictEqual(exit, 0);
});
});

describe("when executing a file with a lint error", () => {
it("should exit with error", async () => {
const filePath = getFixturePath("undef.js");
Expand Down