Skip to content
This repository was archived by the owner on Sep 28, 2020. It is now read-only.
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: webpack-contrib/eslint-loader
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f9d48ea55138c64231890f2c2825e3a454345836
Choose a base ref
...
head repository: webpack-contrib/eslint-loader
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: e732cb578afaf9cd72e44ab21fe0211dd0cf8780
Choose a head ref

Commits on Jan 31, 2019

  1. Copy the full SHA
    d763726 View commit details
  2. 2.1.2

    ThomasKientz committed Jan 31, 2019
    Copy the full SHA
    02c1e76 View commit details

Commits on Jun 28, 2019

  1. feat: add eslint 6 support (#275)

    HDuck authored and evilebottnawi committed Jun 28, 2019
    Copy the full SHA
    b6c3938 View commit details

Commits on Jul 2, 2019

  1. docs: formatting (#250)

    * Update README.md
    MattGurney authored and ricardogobbosouza committed Jul 2, 2019
    Copy the full SHA
    310b8f4 View commit details
  2. Update LICENSE (#278)

    Closes #277
    MoOx authored Jul 2, 2019
    Copy the full SHA
    db82922 View commit details

Commits on Jul 3, 2019

  1. Copy the full SHA
    f611fdb View commit details
  2. Copy the full SHA
    bc2216e View commit details

Commits on Jul 4, 2019

  1. Copy the full SHA
    8601da9 View commit details
  2. Copy the full SHA
    2a72daa View commit details
  3. docs: update gotchas (#284)

    ricardogobbosouza authored and evilebottnawi committed Jul 4, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    8cb02a6 View commit details
  4. Copy the full SHA
    997cce5 View commit details

Commits on Jul 10, 2019

  1. Copy the full SHA
    4204560 View commit details

Commits on Jul 22, 2019

  1. Copy the full SHA
    dcbac5f View commit details

Commits on Aug 20, 2019

  1. chore(release): 3.0.0

    ricardogobbosouza authored and evilebottnawi committed Aug 20, 2019
    Copy the full SHA
    fc8b4e4 View commit details

Commits on Aug 23, 2019

  1. ci: fix (#291)

    evilebottnawi authored Aug 23, 2019
    Copy the full SHA
    78626bb View commit details

Commits on Aug 24, 2019

  1. chore(release): 3.0.0

    alexander-akait committed Aug 24, 2019
    Copy the full SHA
    4895987 View commit details

Commits on Sep 24, 2019

  1. Copy the full SHA
    360e69c View commit details

Commits on Sep 25, 2019

  1. Copy the full SHA
    0821e14 View commit details
  2. Copy the full SHA
    c6b7c12 View commit details
  3. Copy the full SHA
    311399a View commit details
  4. Copy the full SHA
    f9b4628 View commit details

Commits on Sep 26, 2019

  1. Copy the full SHA
    16e9ccf View commit details
  2. Copy the full SHA
    7d1d1fe View commit details

Commits on Sep 27, 2019

  1. Copy the full SHA
    fce6f88 View commit details

Commits on Oct 9, 2019

  1. docs: formatting

    ricardogobbosouza authored Oct 9, 2019
    Copy the full SHA
    2dd8b43 View commit details

Commits on Dec 4, 2019

  1. docs: formatting

    ricardogobbosouza committed Dec 4, 2019
    Copy the full SHA
    2346ff8 View commit details
  2. chore: update deps

    ricardogobbosouza committed Dec 4, 2019
    Copy the full SHA
    356c8e2 View commit details
  3. Copy the full SHA
    dab6d65 View commit details
  4. docs: update

    ricardogobbosouza authored Dec 4, 2019
    Copy the full SHA
    f06c9e8 View commit details
  5. Copy the full SHA
    7793ccf View commit details

Commits on Dec 6, 2019

  1. Copy the full SHA
    6bb1fa6 View commit details
  2. Copy the full SHA
    c0a9d0c View commit details
  3. Copy the full SHA
    ee68817 View commit details
  4. Copy the full SHA
    23695fc View commit details
  5. docs: formatting

    ricardogobbosouza authored Dec 6, 2019
    Copy the full SHA
    3f422bf View commit details

Commits on Feb 28, 2020

  1. Copy the full SHA
    929800d View commit details
  2. Copy the full SHA
    e04f743 View commit details

Commits on Mar 30, 2020

  1. fix: #316 updating loader-fs-cache min version (#317)

    * Fix #316 updating loader-fs-cache min version
    
    Fix #316 updating loader-fs-cache min version.
    The new version of loader-fs-cache has support for a new version of minimist which has not the prototype pollution vuln (CVE-2020-7598).
    
    * fix: fix #316 update loader-fs-cache also in package-lock
    neokeld authored Mar 30, 2020
    Copy the full SHA
    796e3d1 View commit details
  2. chore: update deps

    ricardogobbosouza committed Mar 30, 2020
    Copy the full SHA
    d7be477 View commit details

Commits on Apr 2, 2020

  1. chore: update deps

    ricardogobbosouza committed Apr 2, 2020
    Copy the full SHA
    acecce6 View commit details
  2. Copy the full SHA
    953d140 View commit details
  3. Copy the full SHA
    6c6a87a View commit details

Commits on Apr 3, 2020

  1. chore: v4.0.0 (#319)

    * test: set default timeout
    
    * style: formatting
    
    * chore: update deps
    
    * ci: update
    
    * chore: minimum required nodejs version is 10.13.0
    
    * test: set testEnvironment  `node`
    ricardogobbosouza authored Apr 3, 2020
    Copy the full SHA
    1a12052 View commit details
  2. Copy the full SHA
    c086892 View commit details

Commits on Apr 19, 2020

  1. refactor: new cache implementation (#320)

    * refactor: new cache implementation
    
    add Filesystem Cache implementation instead of loader-fs-cache
    
    * chore: remove unused devDependencies
    aaharu authored Apr 19, 2020
    Copy the full SHA
    acae2be View commit details

Commits on Apr 24, 2020

  1. Copy the full SHA
    ba37e29 View commit details
  2. Copy the full SHA
    7febae0 View commit details
  3. Copy the full SHA
    e732cb5 View commit details
Showing with 16,523 additions and 6,664 deletions.
  1. +4 −7 .editorconfig
  2. +5 −4 .eslintignore
  3. +8 −0 .eslintrc.js
  4. +4 −0 .gitattributes
  5. +6 −0 .github/CODEOWNERS
  6. +160 −0 .github/CONTRIBUTING.md
  7. +1 −0 .github/FUNDING.yml
  8. +16 −0 .github/ISSUE_TEMPLATE.md
  9. +50 −0 .github/ISSUE_TEMPLATE/BUG.md
  10. +28 −0 .github/ISSUE_TEMPLATE/DOCS.md
  11. +25 −0 .github/ISSUE_TEMPLATE/FEATURE.md
  12. +27 −0 .github/ISSUE_TEMPLATE/MODIFICATION.md
  13. +8 −0 .github/ISSUE_TEMPLATE/SUPPORT.md
  14. +35 −0 .github/PULL_REQUEST_TEMPLATE.md
  15. +19 −2 .gitignore
  16. +6 −0 .prettierignore
  17. +5 −0 .prettierrc.js
  18. +0 −28 .travis.yml
  19. +94 −0 CHANGELOG.md
  20. +17 −18 LICENSE
  21. +210 −120 README.md
  22. +200 −0 azure-pipelines.yml
  23. +19 −0 babel.config.js
  24. +3 −0 commitlint.config.js
  25. +6 −0 husky.config.js
  26. +0 −254 index.js
  27. +4 −0 jest.config.js
  28. +4 −0 lint-staged.config.js
  29. +14,143 −0 package-lock.json
  30. +73 −49 package.json
  31. +7 −0 src/ESLintError.js
  32. +207 −0 src/Linter.js
  33. +187 −0 src/cache.js
  34. +35 −0 src/cacheLoader.js
  35. +3 −0 src/cjs.js
  36. +17 −0 src/createEngine.js
  37. +46 −0 src/getOptions.js
  38. +19 −0 src/index.js
  39. +64 −0 src/options.json
  40. +31 −0 test/Linter.test.js
  41. +0 −56 test/autofix-stop.js
  42. +36 −0 test/autofix-stop.test.js
  43. +0 −47 test/autofix.js
  44. +27 −0 test/autofix.test.js
  45. +0 −268 test/cache.js
  46. +168 −0 test/cache.test.js
  47. +8 −0 test/cjs.test.js
  48. +0 −25 test/error.js
  49. +12 −0 test/error.test.js
  50. +0 −39 test/eslint-path.js
  51. +16 −0 test/eslint-path.test.js
  52. +0 −29 test/eslintignore.js
  53. +12 −0 test/eslintignore.test.js
  54. +0 −62 test/fail-on-error-async-and-emit.js
  55. +30 −0 test/fail-on-error.test.js
  56. +30 −0 test/fail-on-warning.test.js
  57. +2 −0 test/fixtures/fixable.js
  58. +1 −3 test/fixtures/good-semi.js
  59. +0 −2 test/fixtures/good.js
  60. +1 −1 test/fixtures/ignore.js
  61. +2 −2 test/fixtures/warn.js
  62. +0 −32 test/force-emit-error.js
  63. +13 −0 test/force-emit-error.test.js
  64. +0 −32 test/force-emit-warning.js
  65. +13 −0 test/force-emit-warning.test.js
  66. +0 −37 test/formatter-custom.js
  67. +23 −0 test/formatter-custom.test.js
  68. +0 −29 test/formatter-eslint.js
  69. +12 −0 test/formatter-eslint.test.js
  70. +0 −59 test/formatter-multiple-entries.js
  71. +41 −0 test/formatter-multiple-entries.test.js
  72. +12 −0 test/formatter-official.test.js
  73. +0 −60 test/formatter-write.js
  74. +51 −0 test/formatter-write.test.js
  75. +49 −24 test/mock/eslint/index.js
  76. +3 −0 test/mock/eslint/lib/cli-engine/formatters/stylish.js
  77. +3 −3 test/mock/eslint/lib/formatters/stylish.js
  78. +4 −0 test/mock/eslint/package.json
  79. +0 −52 test/multiple-engines.js
  80. +52 −0 test/multiple-engines.test.js
  81. +15 −0 test/no-eslint-configuration.test.js
  82. +0 −24 test/ok.js
  83. +13 −0 test/ok.test.js
  84. +0 −33 test/parameters.js
  85. +13 −0 test/parameters.test.js
  86. +0 −40 test/quiet.js
  87. +13 −0 test/quiet.test.js
  88. +32 −51 test/utils/conf.js
  89. +7 −0 test/utils/pack.js
  90. +0 −3 test/utils/version.js
  91. +0 −31 test/warning.js
  92. +13 −0 test/warning.test.js
  93. +0 −5,138 yarn.lock
11 changes: 4 additions & 7 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
# editorconfig.org
root = true

[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
insert_final_newline = true
trim_trailing_whitespace = false

[Makefile]
indent_style = tab
9 changes: 5 additions & 4 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules

test/fixtures/
test/output/
/coverage
/dist
/node_modules
/test/fixtures
/test/output
8 changes: 8 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
root: true,
extends: ['@webpack-contrib/eslint-config-webpack', 'prettier'],
rules: {
'global-require': 'off',
'import/no-dynamic-require': 'off',
},
};
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
* text=auto
bin/* eol=lf
package-lock.json -diff
yarn.lock -diff
6 changes: 6 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# These are the default owners for everything in
# webpack-contrib
@webpack-contrib/org-maintainers

# Add repository specific users / groups
# below here for libs that are not maintained by the org.
160 changes: 160 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Contributing in @webpack-contrib

We'd always love contributions to further improve the webpack / webpack-contrib ecosystem!
Here are the guidelines we'd like you to follow:

- [Questions and Problems](#question)
- [Issues and Bugs](#issue)
- [Feature Requests](#feature)
- [Pull Request Submission Guidelines](#submit-pr)
- [Commit Message Conventions](#commit)

## <a name="question"></a> Got a Question or Problem?

Please submit support requests and questions to StackOverflow using the tag [[webpack]](http://stackoverflow.com/tags/webpack).
StackOverflow is better suited for this kind of support though you may also inquire in [Webpack Gitter](https://gitter.im/webpack/webpack).
The issue tracker is for bug reports and feature discussions.

## <a name="issue"></a> Found an Issue or Bug?

Before you submit an issue, please search the issue tracker, maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available.

We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it. In order to reproduce bugs, we ask that you to provide a minimal reproduction scenario (github repo or failing test case). Having a live, reproducible scenario gives us a wealth of important information without going back & forth to you with additional questions like:

- version of Webpack used
- version of the loader / plugin you are creating a bug report for
- the use-case that fails

A minimal reproduce scenario allows us to quickly confirm a bug (or point out config problems) as well as confirm that we are fixing the right problem.

We will be insisting on a minimal reproduce scenario in order to save maintainers time and ultimately be able to fix more bugs. We understand that sometimes it might be hard to extract essentials bits of code from a larger code-base but we really need to isolate the problem before we can fix it.

Unfortunately, we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you we are going to close an issue that doesn't have enough info to be reproduced.

## <a name="feature"></a> Feature Requests?

You can _request_ a new feature by creating an issue on Github.

If you would like to _implement_ a new feature, please submit an issue with a proposal for your work `first`, to be sure that particular makes sense for the project.

## <a name="submit-pr"></a> Pull Request Submission Guidelines

Before you submit your Pull Request (PR) consider the following guidelines:

- Search Github for an open or closed PR that relates to your submission. You don't want to duplicate effort.
- Commit your changes using a descriptive commit message that follows our [commit message conventions](#commit). Adherence to these conventions is necessary because release notes are automatically generated from these messages.
- Fill out our `Pull Request Template`. Your pull request will not be considered if it is ignored.
- Please sign the `Contributor License Agreement (CLA)` when a pull request is opened. We cannot accept your pull request without this. Make sure you sign with the primary email address associated with your local / github account.

## <a name="commit"></a> Webpack Contrib Commit Conventions

Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
format that includes a **type**, a **scope** and a **subject**:

```
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```

The **header** is mandatory and the **scope** of the header is optional.

Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
to read on GitHub as well as in various git tools.

The footer should contain a [closing reference to an issue](https://help.github.com/articles/closing-issues-via-commit-messages/) if any.

Examples:

```
docs(readme): update install instructions
```

```
fix: refer to the `entrypoint` instead of the first `module`
```

### Revert

If the commit reverts a previous commit, it should begin with `revert:`, followed by the header of the reverted commit.
In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.

### Type

Must be one of the following:

- **build**: Changes that affect the build system or external dependencies (example scopes: babel, npm)
- **chore**: Changes that fall outside of build / docs that do not effect source code (example scopes: package, defaults)
- **ci**: Changes to our CI configuration files and scripts (example scopes: circleci, travis)
- **docs**: Documentation only changes (example scopes: readme, changelog)
- **feat**: A new feature
- **fix**: A bug fix
- **perf**: A code change that improves performance
- **refactor**: A code change that neither fixes a bug nor adds a feature
- **revert**: Used when reverting a committed change
- **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons)
- **test**: Addition of or updates to Jest tests

### Scope

The scope is subjective & depends on the `type` see above. A good example would be a change to a particular class / module.

### Subject

The subject contains a succinct description of the change:

- use the imperative, present tense: "change" not "changed" nor "changes"
- don't capitalize the first letter
- no dot (.) at the end

### Body

Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
The body should include the motivation for the change and contrast this with previous behavior.

### Footer

The footer should contain any information about **Breaking Changes** and is also the place to
reference GitHub issues that this commit **Closes**.

**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.

Example

```
BREAKING CHANGE: Updates to `Chunk.mapModules`.
This release is not backwards compatible with `Webpack 2.x` due to breaking changes in webpack/webpack#4764
Migration: see webpack/webpack#5225
```

## Testing Your Pull Request

You may have the need to test your changes in a real-world project or dependent
module. Thankfully, Github provides a means to do this. Add a dependency to the
`package.json` for such a project as follows:

```json
{
"devDependencies": {
"eslint-loader": "webpack-contrib/eslint-loader#{id}/head"
}
}
```

Where `{id}` is the # ID of your Pull Request.

## Contributor License Agreement

When submitting your contribution, a CLA (Contributor License Agreement) bot will come by to verify that you signed the [CLA](https://cla.js.foundation/webpack-contrib/eslint-loader).
If it is your first time, it will link you to the right place to sign it.
However, if you have committed your contributions using an email that is not the same as your email used on GitHub, the CLA bot can't accept your contribution.

Run `git config user.email` to see your Git email, and verify it with [your GitHub email](https://github.com/settings/emails).

## Thanks

For your interest, time, understanding, and for following this simple guide.
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
open_collective: webpack
16 changes: 16 additions & 0 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!--
👉🏽 Need support, advice, or help? Don't open an issue!
Head to StackOverflow or https://gitter.im/webpack/webpack.
Hey there!
You arrived at this template because you felt none of the other options
matched the kind of issue you'd like to report. Please use this opportunity to
tell us about your particular type of issue so we can try to accomodate
similar issues in the future.
PLEASE do note, if you're using this to report an issue already covered by the
existing template types, your issue may be closed as invalid. Our issue
templates contain fields that help us help you, and without that important
info, we might as well be ice-skating uphill, carrying a wooly mammoth.
-->
50 changes: 50 additions & 0 deletions .github/ISSUE_TEMPLATE/BUG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
name: 🐛 Bug Report
about: Something went awry and you'd like to tell us about it.
---

<!--
Issues are so 🔥
If you remove or skip this template, you'll make the 🐼 sad and the mighty god
of Github will appear and pile-drive the close button from a great height
while making animal noises.
👉🏽 Need support, advice, or help? Don't open an issue!
Head to StackOverflow or https://gitter.im/webpack/webpack.
-->

- Operating System:
- Node Version:
- NPM Version:
- webpack Version:
- eslint-loader Version:

### Expected Behavior

<!-- Remove this section if not reporting a bug or modification request. -->

### Actual Behavior

<!-- Remove this section if not reporting a bug or modification request. -->

### Code

```js
// webpack.config.js
// If your code blocks are over 20 lines, please paste a link to a gist
// (https://gist.github.com).
```

```js
// additional code, HEY YO remove this block if you don't need it
```

### How Do We Reproduce?

<!--
Remove this section if not reporting a bug.
If your webpack config is over 50 lines long, please provide a URL to a repo
for your beefy 🍖 app that we can use to reproduce.
-->
28 changes: 28 additions & 0 deletions .github/ISSUE_TEMPLATE/DOCS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
name: 📚 Documentation
about: Are the docs lacking or missing something? Do they need some new 🔥 hotness? Tell us here.
---

<!--
Issues are so 🔥
If you remove or skip this template, you'll make the 🐼 sad and the mighty god
of Github will appear and pile-drive the close button from a great height
while making animal noises.
👉🏽 Need support, advice, or help? Don't open an issue!
Head to StackOverflow or https://gitter.im/webpack/webpack.
-->

Documentation Is:

<!-- Please place an x (no spaces!) in all [ ] that apply -->

- [ ] Missing
- [ ] Needed
- [ ] Confusing
- [ ] Not Sure?

### Please Explain in Detail...

### Your Proposal for Changes
25 changes: 25 additions & 0 deletions .github/ISSUE_TEMPLATE/FEATURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
name: ✨ Feature Request
about: Suggest an idea for this project
---

<!--
Issues are so 🔥
If you remove or skip this template, you'll make the 🐼 sad and the mighty god
of Github will appear and pile-drive the close button from a great height
while making animal noises.
👉🏽 Need support, advice, or help? Don't open an issue!
Head to StackOverflow or https://gitter.im/webpack/webpack.
-->

- Operating System:
- Node Version:
- NPM Version:
- webpack Version:
- eslint-loader Version:

### Feature Proposal

### Feature Use Case
27 changes: 27 additions & 0 deletions .github/ISSUE_TEMPLATE/MODIFICATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
name: 🔧 Modification Request
about: Would you like something work differently? Have an alternative approach? This is the template for you.
---

<!--
Issues are so 🔥
If you remove or skip this template, you'll make the 🐼 sad and the mighty god
of Github will appear and pile-drive the close button from a great height
while making animal noises.
👉🏽 Need support, advice, or help? Don't open an issue!
Head to StackOverflow or https://gitter.im/webpack/webpack.
-->

- Operating System:
- Node Version:
- NPM Version:
- webpack Version:
- eslint-loader Version:

### Expected Behavior / Situation

### Actual Behavior / Situation

### Modification Proposal
8 changes: 8 additions & 0 deletions .github/ISSUE_TEMPLATE/SUPPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
name: 🆘 Support, Help, and Advice
about: 👉🏽 Need support, help, or advice? Don't open an issue! Head to StackOverflow or https://gitter.im/webpack/webpack.
---

Hey there! If you need support, help, or advice then this is not the place to ask.
Please visit [StackOverflow](https://stackoverflow.com/questions/tagged/webpack)
or [the Webpack Gitter](https://gitter.im/webpack/webpack) instead.
35 changes: 35 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!--
HOLY CRAP a Pull Request. We ❤️ those!
If you remove or skip this template, you'll make the 🐼 sad and the mighty god
of Github will appear and pile-drive the close button from a great height
while making animal noises.
Please place an x (no spaces!) in all [ ] that apply
-->

This PR contains a:

- [ ] **bugfix**
- [ ] new **feature**
- [ ] **code refactor**
- [ ] **test update** <!-- if bug or feature is checked, this should be too -->
- [ ] **typo fix**
- [ ] **metadata update**

### Motivation / Use-Case

<!--
Please explain the motivation or use-case for your change.
What existing problem does the PR solve?
If this PR addresses an issue, please link to the issue.
-->

### Breaking Changes

<!--
If this PR introduces a breaking change, please describe the impact and a
migration path for existing applications.
-->

### Additional Info
21 changes: 19 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
node_modules
logs
*.log
npm-debug.log*
yarn-debug.log*
.eslintcache

test/output/
/coverage
/dist
/local
/reports
/node_modules
/test/output

.DS_Store
Thumbs.db
.idea
.vscode
*.sublime-project
*.sublime-workspace
*.iml
6 changes: 6 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/coverage
/dist
/node_modules
/test/fixtures
/test/output
CHANGELOG.md
5 changes: 5 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
singleQuote: true,
trailingComma: 'es5',
arrowParens: 'always',
};
28 changes: 0 additions & 28 deletions .travis.yml

This file was deleted.

94 changes: 94 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,97 @@
# Changelog

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [4.0.2](https://github.com/webpack-contrib/eslint-loader/compare/v3.0.4...v4.0.2) (2020-04-24)


### Bug Fixes

* use fs-extra ^8.1.0 ([7febae0](https://github.com/webpack-contrib/eslint-loader/commit/7febae056ac6271c4cf76b8e387f8fae5800a879))

### [4.0.1](https://github.com/webpack-contrib/eslint-loader/compare/v3.0.4...v4.0.1) (2020-04-24)

### Refactor

* new cache implementation ([#320](https://github.com/webpack-contrib/eslint-loader/pull/320)) ([6bb1fa6](https://github.com/webpack-contrib/eslint-loader/commit/acae2be88678228e6589b40122a93f88437b8e47))

## [4.0.0](https://github.com/webpack-contrib/eslint-loader/compare/v3.0.4...v4.0.0) (2020-04-03)

### Breaking Changes

* drop support for Node < 10.13.0
* minimum supported eslint version is 6

### [3.0.4](https://github.com/webpack-contrib/eslint-loader/compare/v3.0.3...v3.0.4) (2020-04-02)


### Bug Fixes

* [#316](https://github.com/webpack-contrib/eslint-loader/issues/316) updating loader-fs-cache min version ([#317](https://github.com/webpack-contrib/eslint-loader/issues/317)) ([796e3d1](https://github.com/webpack-contrib/eslint-loader/commit/796e3d130a030ce48e14ee3421809ca40d25cde1))

### [3.0.3](https://github.com/webpack-contrib/eslint-loader/compare/v3.0.2...v3.0.3) (2019-12-06)


### Bug Fixes

* check result object ([#311](https://github.com/webpack-contrib/eslint-loader/issues/311)) ([6bb1fa6](https://github.com/webpack-contrib/eslint-loader/commit/6bb1fa68d043f00de63cda4d9babd3a2c9a50d58))
* support webpack 5 ([#312](https://github.com/webpack-contrib/eslint-loader/issues/312)) ([c0a9d0c](https://github.com/webpack-contrib/eslint-loader/commit/c0a9d0c118155c56c41dc344460f333a9e969eaf))

### [3.0.2](https://github.com/webpack-contrib/eslint-loader/compare/v3.0.1...v3.0.2) (2019-09-27)


### Bug Fixes

* check if contain results ([#300](https://github.com/webpack-contrib/eslint-loader/issues/300)) ([7d1d1fe](https://github.com/webpack-contrib/eslint-loader/commit/7d1d1fe))
* ensure output file path ([#299](https://github.com/webpack-contrib/eslint-loader/issues/299)) ([16e9ccf](https://github.com/webpack-contrib/eslint-loader/commit/16e9ccf))

### [3.0.1](https://github.com/webpack-contrib/eslint-loader/compare/v3.0.0...v3.0.1) (2019-09-25)


### Bug Fixes

* module build failed error at Linter.parseResults ([#294](https://github.com/webpack-contrib/eslint-loader/issues/294)) ([360e69c](https://github.com/webpack-contrib/eslint-loader/commit/360e69c))

### [3.0.0](https://github.com/webpack-contrib/eslint-loader/compare/v2.2.1...v3.0.0) (2019-08-24)


### Bugfix

* fix corrupted filenames if cwd == "/"
* cannot use string formatter in outputReport
* no Output Report in File when build fails under webpack 4
* add posibility to use absolute file path in outputReport.filePath
* it should be possible to use absolute file path in outputReport.filePath
* try load official formatter ([#285](https://github.com/webpack-contrib/eslint-loader/issues/285)) ([997cce5](https://github.com/webpack-contrib/eslint-loader/commit/997cce5))
* emit warning/error if no config was found/given ([#286](https://github.com/webpack-contrib/eslint-loader/issues/286)) ([4204560](https://github.com/webpack-contrib/eslint-loader/commit/4204560))


### Features

* validate schema options


### Breaking Changes

* drop support for Node < 8.9.0
* minimum supported webpack version is 4
* minimum supported eslint version is 5



# 2.2.1 - 2019-07-04

- Fixed: path to eslint version for cache
([#282](https://github.com/webpack-contrib/eslint-loader/issues/282) - @ricardogobbosouza)

# 2.2.0 - 2019-07-03

- [Add ESLint 6 support](https://github.com/webpack-contrib/eslint-loader/commit/b6c3938aae61c0390ac8d941af50cf36df14cfc3) by @HDuck

# 2.1.2 - 2019-01-31

- [Fix autofix for eslint < 5](https://github.com/webpack-contrib/eslint-loader/commit/d76372676b8badf57df3d6a22be5739d19e25637) by @eschablowski

# 2.1.1 - 2018-09-19

- [Stop autofixing infinite loop](https://github.com/webpack-contrib/eslint-loader/commit/704024864f737a487ec0b9f9c9b00b11881f2558) by @eschablowski
35 changes: 17 additions & 18 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
The MIT License (MIT)
Copyright JS Foundation and other contributors

Copyright (c) 2015 Maxime Thirouin
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
330 changes: 210 additions & 120 deletions README.md

Large diffs are not rendered by default.

200 changes: 200 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
trigger:
- master
- next

variables:
npm_config_cache: $(Pipeline.Workspace)/.npm

jobs:
- job: Lint
pool:
vmImage: ubuntu-latest
steps:
- task: NodeTool@0
inputs:
versionSpec: ^10.13.0
displayName: 'Install Node.js'
- task: Npm@1
inputs:
command: custom
customCommand: i -g npm@latest
displayName: 'Install latest NPM'
- script: |
node -v
npm -v
displayName: 'Print versions'
- task: CacheBeta@1
inputs:
key: npm | $(Agent.OS) | package-lock.json
path: $(npm_config_cache)
displayName: 'Cache npm'
- script: npm ci
displayName: 'Install dependencies'
- script: npm run lint
displayName: 'Run lint'
- script: npm run security
displayName: 'Run NPM audit'
- script: ./node_modules/.bin/commitlint-azure-pipelines
displayName: 'Run lint commit message'

- job: Linux
pool:
vmImage: ubuntu-latest
strategy:
maxParallel: 4
matrix:
node-13:
node_version: ^13.0.0
webpack_version: latest
node-12:
node_version: ^12.0.0
webpack_version: latest
node-10:
node_version: ^10.13.0
webpack_version: latest
node-10-canary:
node_version: ^10.13.0
webpack_version: next
steps:
- task: NodeTool@0
inputs:
versionSpec: $(node_version)
displayName: 'Install Node.js $(node_version)'
- task: Npm@1
inputs:
command: custom
customCommand: i -g npm@latest
displayName: 'Install latest NPM'
- script: |
node -v
npm -v
displayName: 'Print versions'
- task: CacheBeta@1
inputs:
key: npm | $(Agent.OS) | package-lock.json
path: $(npm_config_cache)
displayName: 'Cache npm'
- script: npm ci
displayName: 'Install dependencies'
- script: npm i webpack@$(webpack_version)
displayName: 'Install "webpack@$(webpack_version)"'
- script: npm run test:coverage -- --ci --reporters="default" --reporters="jest-junit" || $(continue_on_error)
displayName: 'Run tests with coverage'
- task: PublishTestResults@2
inputs:
testRunTitle: 'Linux with Node.js $(node_version)'
testResultsFiles: '**/junit.xml'
condition: succeededOrFailed()
displayName: 'Publish test results'
- script: curl -s https://codecov.io/bash | bash -s -- -t $(CODECOV_TOKEN)
condition: succeededOrFailed()
displayName: 'Submit coverage data to codecov'

- job: macOS
pool:
vmImage: macOS-latest
strategy:
maxParallel: 4
matrix:
node-13:
node_version: ^13.0.0
webpack_version: latest
node-12:
node_version: ^12.0.0
webpack_version: latest
node-10:
node_version: ^10.13.0
webpack_version: latest
node-10-canary:
node_version: ^10.13.0
webpack_version: next
steps:
- task: NodeTool@0
inputs:
versionSpec: $(node_version)
displayName: 'Install Node.js $(node_version)'
- task: Npm@1
inputs:
command: custom
customCommand: i -g npm@latest
displayName: 'Install latest NPM'
- script: |
node -v
npm -v
displayName: 'Print versions'
- task: CacheBeta@1
inputs:
key: npm | $(Agent.OS) | package-lock.json
path: $(npm_config_cache)
displayName: 'Cache npm'
- script: npm ci
displayName: 'Install dependencies'
- script: npm i webpack@$(webpack_version)
displayName: 'Install "webpack@$(webpack_version)"'
- script: npm run test:coverage -- --ci --reporters="default" --reporters="jest-junit" || $(continue_on_error)
displayName: 'Run tests with coverage'
- task: PublishTestResults@2
inputs:
testRunTitle: 'Linux with Node.js $(node_version)'
testResultsFiles: '**/junit.xml'
condition: succeededOrFailed()
displayName: 'Publish test results'
- script: curl -s https://codecov.io/bash | bash -s -- -t $(CODECOV_TOKEN)
condition: succeededOrFailed()
displayName: 'Submit coverage data to codecov'

- job: Windows
pool:
vmImage: windows-latest
strategy:
maxParallel: 4
matrix:
node-13:
node_version: ^13.0.0
webpack_version: latest
node-12:
node_version: ^12.0.0
webpack_version: latest
node-10:
node_version: ^10.13.0
webpack_version: latest
node-10-canary:
node_version: ^10.13.0
webpack_version: next
steps:
- script: 'git config --global core.autocrlf input'
displayName: 'Config git core.autocrlf'
- checkout: self
- task: NodeTool@0
inputs:
versionSpec: $(node_version)
displayName: 'Install Node.js $(node_version)'
- task: Npm@1
inputs:
command: custom
customCommand: i -g npm@latest
displayName: 'Install latest NPM'
- script: |
node -v
npm -v
displayName: 'Print versions'
- task: CacheBeta@1
inputs:
key: npm | $(Agent.OS) | package-lock.json
path: $(npm_config_cache)
displayName: 'Cache npm'
- script: npm ci
displayName: 'Install dependencies'
- script: npm i webpack@$(webpack_version)
displayName: 'Install "webpack@$(webpack_version)"'
- script: npm run test:coverage -- --ci --reporters="default" --reporters="jest-junit" || $(continue_on_error)
displayName: 'Run tests with coverage'
- task: PublishTestResults@2
inputs:
testRunTitle: 'Linux with Node.js $(node_version)'
testResultsFiles: '**/junit.xml'
condition: succeededOrFailed()
displayName: 'Publish test results'
- script: curl -s https://codecov.io/bash | bash -s -- -t $(CODECOV_TOKEN)
condition: succeededOrFailed()
displayName: 'Submit coverage data to codecov'
19 changes: 19 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const MIN_BABEL_VERSION = 7;

module.exports = (api) => {
api.assertVersion(MIN_BABEL_VERSION);
api.cache(true);

return {
presets: [
[
'@babel/preset-env',
{
targets: {
node: '10.13.0',
},
},
],
],
};
};
3 changes: 3 additions & 0 deletions commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
};
6 changes: 6 additions & 0 deletions husky.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
hooks: {
'pre-commit': 'lint-staged',
'commit-msg': 'commitlint -E HUSKY_GIT_PARAMS',
},
};
254 changes: 0 additions & 254 deletions index.js

This file was deleted.

4 changes: 4 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
testEnvironment: 'node',
testTimeout: 30000,
};
4 changes: 4 additions & 0 deletions lint-staged.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
'*.js': ['prettier --write', 'eslint --fix', 'git add'],
'*.{json,md,yml,css}': ['prettier --write', 'git add'],
};
14,143 changes: 14,143 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

122 changes: 73 additions & 49 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,61 +1,85 @@
{
"name": "eslint-loader",
"version": "2.1.1",
"description": "eslint loader (for webpack)",
"keywords": [
"lint",
"linter",
"eslint",
"loader",
"webpack"
],
"repository": "https://github.com/webpack-contrib/eslint-loader.git",
"author": "Maxime Thirouin",
"version": "4.0.2",
"description": "A ESlint loader for webpack",
"license": "MIT",
"repository": "webpack-contrib/eslint-loader",
"author": "Maxime Thirouin",
"contributors": [
"Ricardo Gobbo de Souza <ricardogobbosouza@yahoo.com.br>"
],
"homepage": "https://github.com/webpack-contrib/eslint-loader",
"bugs": "https://github.com/webpack-contrib/eslint-loader/issues",
"main": "dist/cjs.js",
"engines": {
"node": ">= 10.13.0"
},
"scripts": {
"start": "npm run build -- -w",
"clean": "del-cli dist",
"prebuild": "npm run clean",
"build": "cross-env NODE_ENV=production babel src -d dist --copy-files",
"commitlint": "commitlint --from=master",
"security": "npm audit",
"lint:prettier": "prettier \"{**/*,*}.{js,json,md,yml,css,ts}\" --list-different",
"lint:js": "eslint --cache .",
"lint": "npm-run-all -l -p \"lint:**\"",
"test:only": "cross-env NODE_ENV=test jest",
"test:watch": "npm run test:only -- --watch",
"test:coverage": "npm run test:only -- --collectCoverageFrom=\"src/**/*.js\" --coverage",
"pretest": "npm run lint",
"test": "npm run test:coverage",
"prepare": "npm run build",
"release": "standard-version",
"defaults": "webpack-defaults"
},
"files": [
"index.js"
"dist"
],
"peerDependencies": {
"eslint": ">=1.6.0 <6.0.0",
"webpack": ">=2.0.0 <5.0.0"
"eslint": "^6.0.0 || ^7.0.0",
"webpack": "^4.0.0 || ^5.0.0"
},
"dependencies": {
"loader-fs-cache": "^1.0.0",
"loader-utils": "^1.0.2",
"object-assign": "^4.0.1",
"object-hash": "^1.1.4",
"rimraf": "^2.6.1"
"find-cache-dir": "^3.3.1",
"fs-extra": "^8.1.0",
"loader-utils": "^2.0.0",
"object-hash": "^2.0.3",
"schema-utils": "^2.6.5"
},
"devDependencies": {
"ava": "^0.17.0",
"eslint": "^5.1.0",
"eslint-config-i-am-meticulous": "^11.0.0",
"eslint-friendly-formatter": "^2.0.4",
"husky": "^0.14.3",
"mkdirp": "^0.5.1",
"npmpub": "^4.0.1",
"prettier": "^1.13.7",
"pretty-quick": "^1.6.0",
"webpack": "^4.0.0"
},
"scripts": {
"precommit": "pretty-quick --staged",
"lint": "eslint .",
"ava": "ava",
"test": "npm run lint && npm run ava",
"release": "npmpub"
},
"eslintConfig": {
"extends": "eslint-config-i-am-meticulous",
"rules": {
"no-var": 0,
"prefer-const": 0
}
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.0",
"@commitlint/cli": "^8.3.5",
"@commitlint/config-conventional": "^8.3.4",
"@webpack-contrib/defaults": "^6.3.0",
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^25.2.6",
"chokidar": "^3.3.1",
"commitlint-azure-pipelines-cli": "^1.0.3",
"cross-env": "^7.0.2",
"del": "^5.1.0",
"del-cli": "^3.0.0",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.1",
"eslint-friendly-formatter": "^4.0.1",
"eslint-plugin-import": "^2.20.2",
"husky": "^4.2.3",
"jest": "^25.2.6",
"jest-junit": "^10.0.0",
"lint-staged": "^10.1.1",
"npm-run-all": "^4.1.5",
"prettier": "^2.0.2",
"standard-version": "^7.1.0",
"webpack": "^4.42.1"
},
"ava": {
"files": [
"test/*.js"
],
"verbose": true
}
"keywords": [
"eslint",
"lint",
"linter",
"loader",
"webpack"
]
}
7 changes: 7 additions & 0 deletions src/ESLintError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default class ESLintError extends Error {
constructor(messages) {
super(messages);
this.name = 'ESLintError';
this.stack = false;
}
}
207 changes: 207 additions & 0 deletions src/Linter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
import process from 'process';
import { isAbsolute, join } from 'path';

import { writeFileSync, ensureFileSync } from 'fs-extra';
import { interpolateName } from 'loader-utils';

import ESLintError from './ESLintError';
import createEngine from './createEngine';

export default class Linter {
constructor(loaderContext, options) {
this.loaderContext = loaderContext;
this.options = options;
this.resourcePath = this.parseResourcePath();

const { CLIEngine, engine } = createEngine(options);
this.CLIEngine = CLIEngine;
this.engine = engine;
}

parseResourcePath() {
const cwd = process.cwd();
let { resourcePath } = this.loaderContext;

// remove cwd from resource path in case webpack has been started from project
// root, to allow having relative paths in .eslintignore
// istanbul ignore next
if (resourcePath.indexOf(cwd) === 0) {
resourcePath = resourcePath.substr(cwd.length + (cwd === '/' ? 0 : 1));
}

return resourcePath;
}

lint(content) {
try {
return this.engine.executeOnText(content, this.resourcePath, true);
} catch (_) {
this.getEmitter(false)(_);

return { src: content };
}
}

printOutput(data) {
const { options } = this;

// skip ignored file warning
if (this.constructor.skipIgnoredFileWarning(data)) {
return;
}

// quiet filter done now
// eslint allow rules to be specified in the input between comments
// so we can found warnings defined in the input itself
const res = this.filter(data);

// if enabled, use eslint auto-fixing where possible
if (options.fix) {
this.autoFix(res);
}

// skip if no errors or warnings
if (res.errorCount < 1 && res.warningCount < 1) {
return;
}

const results = this.parseResults(res);

// Do not analyze if there are no results or eslint config
if (!results) {
return;
}

const messages = options.formatter(results);

this.reportOutput(results, messages);
this.failOnErrorOrWarning(res, messages);

const emitter = this.getEmitter(res);
emitter(new ESLintError(messages));
}

static skipIgnoredFileWarning(res) {
return (
res &&
res.warningCount === 1 &&
res.results &&
res.results[0] &&
res.results[0].messages[0] &&
res.results[0].messages[0].message &&
res.results[0].messages[0].message.indexOf('ignore') > 1
);
}

filter(data) {
const res = data;

// quiet filter done now
// eslint allow rules to be specified in the input between comments
// so we can found warnings defined in the input itself
if (
this.options.quiet &&
res &&
res.warningCount &&
res.results &&
res.results[0]
) {
res.warningCount = 0;
res.results[0].warningCount = 0;
res.results[0].messages = res.results[0].messages.filter(
(message) => message.severity !== 1
);
}

return res;
}

autoFix(res) {
if (
res &&
res.results &&
res.results[0] &&
(res.results[0].output !== res.src ||
res.results[0].fixableErrorCount > 0 ||
res.results[0].fixableWarningCount > 0)
) {
this.CLIEngine.outputFixes(res);
}
}

parseResults({ results }) {
// add filename for each results so formatter can have relevant filename
if (results) {
results.forEach((r) => {
// eslint-disable-next-line no-param-reassign
r.filePath = this.loaderContext.resourcePath;
});
}

return results;
}

reportOutput(results, messages) {
const { outputReport } = this.options;

if (!outputReport || !outputReport.filePath) {
return;
}

let content = messages;

// if a different formatter is passed in as an option use that
if (outputReport.formatter) {
content = outputReport.formatter(results);
}

let filePath = interpolateName(this.loaderContext, outputReport.filePath, {
content,
});

if (!isAbsolute(filePath)) {
filePath = join(
// eslint-disable-next-line no-underscore-dangle
this.loaderContext._compiler.options.output.path,
filePath
);
}

ensureFileSync(filePath);
writeFileSync(filePath, content);
}

failOnErrorOrWarning({ errorCount, warningCount }, messages) {
const { failOnError, failOnWarning } = this.options;

if (failOnError && errorCount) {
throw new ESLintError(
`Module failed because of a eslint error.\n${messages}`
);
}

if (failOnWarning && warningCount) {
throw new ESLintError(
`Module failed because of a eslint warning.\n${messages}`
);
}
}

getEmitter({ errorCount }) {
const { options, loaderContext } = this;

// default behavior: emit error only if we have errors
let emitter = errorCount
? loaderContext.emitError
: loaderContext.emitWarning;

// force emitError or emitWarning if user want this
if (options.emitError) {
emitter = loaderContext.emitError;
} else if (options.emitWarning) {
emitter = loaderContext.emitWarning;
}

return emitter;
}
}
187 changes: 187 additions & 0 deletions src/cache.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/**
* Original Filesystem Cache implementation by babel-loader
* Licensed under the MIT License
*
* @see https://github.com/babel/babel-loader/commits/master/src/fs-cache.js
* @see https://github.com/babel/babel-loader/commits/master/src/cache.js
*/

/**
* Filesystem Cache
*
* Given a file and a transform function, cache the result into files
* or retrieve the previously cached files if the given file is already known.
*
* @see https://github.com/babel/babel-loader/issues/34
* @see https://github.com/babel/babel-loader/pull/41
*/
import fs from 'fs';
import os from 'os';
import { join } from 'path';
import { promisify } from 'util';
import zlib from 'zlib';
import { createHash } from 'crypto';

import findCacheDir from 'find-cache-dir';

// Lazily instantiated when needed
let defaultCacheDirectory = null;

const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);
const gunzip = promisify(zlib.gunzip);
const gzip = promisify(zlib.gzip);

/**
* Read the contents from the compressed file.
*
* @async
* @params {String} filename
* @params {Boolean} compress
*/
const read = async (filename, compress) => {
const data = await readFile(filename + (compress ? '.gz' : ''));
const content = compress ? await gunzip(data) : data;

return JSON.parse(content.toString());
};

/**
* Write contents into a compressed file.
*
* @async
* @params {String} filename
* @params {Boolean} compress
* @params {String} result
*/
const write = async (filename, compress, result) => {
const content = JSON.stringify(result);

const data = compress ? await gzip(content) : content;
return writeFile(filename + (compress ? '.gz' : ''), data);
};

/**
* Build the filename for the cached file
*
* @params {String} source File source code
* @params {String} identifier
* @params {Object} options Options used
*
* @return {String}
*/
const filename = (source, identifier, options) => {
const hash = createHash('md4');

const contents = JSON.stringify({ source, options, identifier });

hash.update(contents);

return `${hash.digest('hex')}.json`;
};

/**
* Handle the cache
*
* @params {String} directory
* @params {Object} params
*/
const handleCache = async (directory, params) => {
const {
source,
options = {},
transform,
cacheIdentifier,
cacheDirectory,
cacheCompression,
} = params;

const file = join(directory, filename(source, cacheIdentifier, options));

try {
// No errors mean that the file was previously cached
// we just need to return it
return await read(file, cacheCompression);
// eslint-disable-next-line no-empty
} catch (err) {}

const fallback =
typeof cacheDirectory !== 'string' && directory !== os.tmpdir();

// Make sure the directory exists.
try {
fs.mkdirSync(directory, { recursive: true });
} catch (err) {
if (fallback) {
return handleCache(os.tmpdir(), params);
}

throw err;
}

// Otherwise just transform the file
// return it to the user asap and write it in cache
const result = await transform(source, options);

try {
await write(file, cacheCompression, result);
} catch (err) {
if (fallback) {
// Fallback to tmpdir if node_modules folder not writable
return handleCache(os.tmpdir(), params);
}

throw err;
}

return result;
};

/**
* Retrieve file from cache, or create a new one for future reads
*
* @async
* @param {Object} params
* @param {String} params.cacheDirectory Directory to store cached files
* @param {String} params.cacheIdentifier Unique identifier to bust cache
* @param {Boolean} params.cacheCompression
* @param {String} params.source Original contents of the file to be cached
* @param {Object} params.options Options to be given to the transform fn
* @param {Function} params.transform Function that will transform the
* original file and whose result will be
* cached
*
* @example
*
* cache({
* cacheDirectory: '.tmp/cache',
* cacheIdentifier: 'babel-loader-cachefile',
* cacheCompression: true,
* source: *source code from file*,
* options: {
* experimental: true,
* runtime: true
* },
* transform: function(source, options) {
* var content = *do what you need with the source*
* return content;
* }
* });
*/

module.exports = async (params) => {
let directory;

if (typeof params.cacheDirectory === 'string') {
directory = params.cacheDirectory;
} else {
if (defaultCacheDirectory === null) {
defaultCacheDirectory =
findCacheDir({ name: 'eslint-loader' }) || os.tmpdir();
}

directory = defaultCacheDirectory;
}

return handleCache(directory, params);
};
35 changes: 35 additions & 0 deletions src/cacheLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { version } from '../package.json';

import cache from './cache';

export default function cacheLoader(linter, content, map) {
const { loaderContext, options, CLIEngine } = linter;
const callback = loaderContext.async();
const cacheIdentifier = JSON.stringify({
'eslint-loader': version,
eslint: CLIEngine.version,
});

cache({
cacheDirectory: options.cache,
cacheIdentifier,
cacheCompression: true,
options,
source: content,
transform() {
return linter.lint(content);
},
})
.then((res) => {
try {
linter.printOutput({ ...res, src: content });
} catch (error) {
return callback(error, content, map);
}
return callback(null, content, map);
})
.catch((err) => {
// istanbul ignore next
return callback(err);
});
}
3 changes: 3 additions & 0 deletions src/cjs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const loader = require('./index');

module.exports = loader.default;
17 changes: 17 additions & 0 deletions src/createEngine.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import objectHash from 'object-hash';

const engines = {};

export default function createEngine(options) {
const { CLIEngine } = require(options.eslintPath);
const hash = objectHash(options);

if (!engines[hash]) {
engines[hash] = new CLIEngine(options);
}

return {
CLIEngine,
engine: engines[hash],
};
}
46 changes: 46 additions & 0 deletions src/getOptions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import loaderUtils from 'loader-utils';
import validateOptions from 'schema-utils';

import schema from './options.json';

export default function getOptions(loaderContext) {
const options = {
eslintPath: 'eslint',
...loaderUtils.getOptions(loaderContext),
};

validateOptions(schema, options, {
name: 'ESLint Loader',
baseDataPath: 'options',
});

const { CLIEngine } = require(options.eslintPath);

options.formatter = getFormatter(CLIEngine, options.formatter);

if (options.outputReport && options.outputReport.formatter) {
options.outputReport.formatter = getFormatter(
CLIEngine,
options.outputReport.formatter
);
}

return options;
}

function getFormatter(CLIEngine, formatter) {
if (typeof formatter === 'function') {
return formatter;
}

// Try to get oficial formatter
if (typeof formatter === 'string') {
try {
return CLIEngine.getFormatter(formatter);
} catch (e) {
// ignored
}
}

return CLIEngine.getFormatter('stylish');
}
19 changes: 19 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import getOptions from './getOptions';
import Linter from './Linter';
import cacheLoader from './cacheLoader';

export default function loader(content, map) {
const options = getOptions(this);
const linter = new Linter(this, options);

this.cacheable();

// return early if cached
if (options.cache) {
cacheLoader(linter, content, map);
return;
}

linter.printOutput(linter.lint(content));
this.callback(null, content, map);
}
64 changes: 64 additions & 0 deletions src/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"type": "object",
"additionalProperties": true,
"properties": {
"cache": {
"description": "This option will enable caching of the linting results into a file. This is particularly useful in reducing linting time when doing a full build.",
"anyOf": [{ "type": "boolean" }, { "type": "string" }]
},
"eslintPath": {
"description": "Path to `eslint` instance that will be used for linting. If the `eslintPath` is a folder like a official eslint, or specify a `formatter` option. now you dont have to install `eslint` .",
"type": "string"
},
"formatter": {
"description": "Loader accepts a function that will have one argument: an array of eslint messages (object). The function must return the output as a string.",
"anyOf": [{ "type": "string" }, { "instanceof": "Function" }]
},
"fix": {
"description": "This option will enable ESLint autofix feature",
"type": "boolean"
},
"emitError": {
"description": "Loader will always return errors if this option is set to `true`.",
"type": "boolean"
},
"emitWarning": {
"description": "Loader will always return warnings if option is set to `true`. If you're using hot module replacement, you may wish to enable this in development, or else updates will be skipped when there's an eslint error.",
"type": "boolean"
},
"failOnError": {
"description": "Loader will cause the module build to fail if there are any eslint errors.",
"type": "boolean"
},
"failOnWarning": {
"description": "Loader will cause the module build to fail if there are any eslint warnings.",
"type": "boolean"
},
"quiet": {
"description": "Loader will process and report errors only and ignore warnings if this option is set to true",
"type": "boolean"
},
"outputReport": {
"description": "Write the output of the errors to a file, for example a checkstyle xml file for use for reporting on Jenkins CI",
"anyOf": [
{
"type": "boolean"
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"filePath": {
"description": "The `filePath` is relative to the webpack config: output.path",
"anyOf": [{ "type": "string" }]
},
"formatter": {
"description": "You can pass in a different formatter for the output file, if none is passed in the default/configured formatter will be used",
"anyOf": [{ "type": "string" }, { "instanceof": "Function" }]
}
}
}
]
}
}
}
31 changes: 31 additions & 0 deletions test/Linter.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Linter from '../src/Linter';

describe('Linter', () => {
let linter;

beforeAll(() => {
const loaderContext = {
resourcePath: 'test',
};

const options = {
eslintPath: 'eslint',
ignore: false,
formatter: jest.fn(),
};

linter = new Linter(loaderContext, options);
});

it('should parse undefined results without error', () => {
expect(linter.parseResults({})).toBeUndefined();
});

it('should parse results correctly', () => {
const res = {
results: [{ filePath: '' }],
};

expect(linter.parseResults(res)).toEqual([{ filePath: 'test' }]);
});
});
56 changes: 0 additions & 56 deletions test/autofix-stop.js

This file was deleted.

36 changes: 36 additions & 0 deletions test/autofix-stop.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { join } from 'path';

import { copySync, removeSync } from 'fs-extra';
import chokidar from 'chokidar';

import pack from './utils/pack';

describe('autofix stop', () => {
const entry = join(__dirname, 'fixtures/nonfixable-clone.js');

let changed = false;
let watcher;

beforeAll(() => {
copySync(join(__dirname, 'fixtures/nonfixable.js'), entry);

watcher = chokidar.watch(entry);
watcher.on('change', () => {
changed = true;
});
});

afterAll(() => {
watcher.close();
removeSync(entry);
});

it('should not change file if there are no fixable errors/warnings', (done) => {
const compiler = pack('nonfixable-clone', { fix: true });

compiler.run(() => {
expect(changed).toBe(false);
done();
});
});
});
47 changes: 0 additions & 47 deletions test/autofix.js

This file was deleted.

27 changes: 27 additions & 0 deletions test/autofix.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { join } from 'path';

import { copySync, removeSync } from 'fs-extra';

import pack from './utils/pack';

describe('autofix stop', () => {
const entry = join(__dirname, 'fixtures/fixable-clone.js');

beforeAll(() => {
copySync(join(__dirname, 'fixtures/fixable.js'), entry);
});

afterAll(() => {
removeSync(entry);
});

it('should not throw error if file ok after auto-fixing', (done) => {
const compiler = pack('fixable-clone', { fix: true });

compiler.run((err, stats) => {
expect(stats.hasWarnings()).toBe(false);
expect(stats.hasErrors()).toBe(false);
done();
});
});
});
268 changes: 0 additions & 268 deletions test/cache.js

This file was deleted.

168 changes: 168 additions & 0 deletions test/cache.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import { join } from 'path';
import fs from 'fs';

import { readdirSync, removeSync } from 'fs-extra';
import webpack from 'webpack';

const defaultCacheDir = join(__dirname, '../node_modules/.cache/eslint-loader');
const cacheDir = join(__dirname, 'output/cache/cachefiles');
const outputDir = join(__dirname, 'output/cache');
const eslintLoader = join(__dirname, '../src/index');
const globalConfig = {
entry: join(__dirname, 'fixtures/cache.js'),
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: eslintLoader,
},
],
},
};

function createTestDirectory(dir) {
const directory = join(dir, 'cache');

removeSync(directory);
fs.mkdirSync(directory, { recursive: true });

return directory;
}

describe('cache', () => {
let directory;
let cache;

beforeEach(() => {
directory = createTestDirectory(outputDir);
cache = createTestDirectory(cacheDir);
removeSync(defaultCacheDir);
});

afterEach(() => {
removeSync(cache);
removeSync(directory);
});

it('should output files to cache directory', (done) => {
const compiler = webpack({
...globalConfig,
output: {
path: directory,
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: `${eslintLoader}?cache=${cache}`,
},
],
},
});
compiler.run(() => {
const files = readdirSync(cache);
expect(files.length).toBeGreaterThan(0);
done();
});
});

it('should output files to standard cache dir if set to true in query', (done) => {
const compiler = webpack({
...globalConfig,
output: {
path: directory,
},
module: {
rules: [
{
test: /\.jsx?/,
exclude: /node_modules/,
use: `${eslintLoader}?cache=true`,
},
],
},
});
compiler.run(() => {
const files = readdirSync(defaultCacheDir).filter((file) =>
/\b[0-9a-f]{5,40}\.json\.gz\b/.test(file)
);
expect(files.length).toBeGreaterThan(0);
done();
});
});

it('should read from cache directory if cached file exists', (done) => {
const compiler = webpack({
...globalConfig,
output: {
path: directory,
},
module: {
rules: [
{
test: /\.jsx?/,
exclude: /node_modules/,
use: `${eslintLoader}?cache=${cache}`,
},
],
},
});
compiler.run(() => {
const files = readdirSync(cache);
expect(files.length).toBe(3);
done();
});
});

it('should generate a new file if the identifier changes', (done) => {
const configs = [
{
...globalConfig,
output: {
path: directory,
},
module: {
rules: [
{
test: /\.jsx?/,
exclude: /node_modules/,
use: `${eslintLoader}?cache=${cache}&cacheIdentifier=a`,
},
],
},
},
{
...globalConfig,
output: {
path: directory,
},
module: {
rules: [
{
test: /\.jsx?/,
exclude: /node_modules/,
use: `${eslintLoader}?cache=${cache}&cacheIdentifier=b`,
},
],
},
},
];

let counter = configs.length;

configs.forEach((config) => {
const compiler = webpack(config);
compiler.run(() => {
counter -= 1;

if (!counter) {
const files = readdirSync(cache);
expect(files.length).toBe(6);
done();
}
});
});
});
});
8 changes: 8 additions & 0 deletions test/cjs.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import EslintLoader from '../src';
import CJSEslintLoader from '../src/cjs';

describe('cjs', () => {
it('should exported plugin', () => {
expect(CJSEslintLoader).toEqual(EslintLoader);
});
});
25 changes: 0 additions & 25 deletions test/error.js

This file was deleted.

12 changes: 12 additions & 0 deletions test/error.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import pack from './utils/pack';

describe('error', () => {
it('should return error if file is bad', (done) => {
const compiler = pack('error');

compiler.run((err, stats) => {
expect(stats.hasErrors()).toBe(true);
done();
});
});
});
39 changes: 0 additions & 39 deletions test/eslint-path.js

This file was deleted.

16 changes: 16 additions & 0 deletions test/eslint-path.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { join } from 'path';

import pack from './utils/pack';

describe('eslint path', () => {
it('should use another instance of eslint via eslintPath config', (done) => {
const eslintPath = join(__dirname, 'mock/eslint');
const compiler = pack('good', { eslintPath });

compiler.run((err, stats) => {
expect(stats.hasErrors()).toBe(true);
expect(stats.compilation.errors[0].message).toContain('Fake error');
done();
});
});
});
29 changes: 0 additions & 29 deletions test/eslintignore.js

This file was deleted.

12 changes: 12 additions & 0 deletions test/eslintignore.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import pack from './utils/pack';

describe('eslintignore', () => {
it('should ignores files present in .eslintignore', (done) => {
const compiler = pack('ignore', { ignore: true });

compiler.run((err, stats) => {
expect(stats.hasWarnings()).toBe(false);
done();
});
});
});
62 changes: 0 additions & 62 deletions test/fail-on-error-async-and-emit.js

This file was deleted.

30 changes: 30 additions & 0 deletions test/fail-on-error.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import pack from './utils/pack';

describe('fail on error', () => {
it('should emits errors', (done) => {
const compiler = pack('error', { failOnError: true });

compiler.run((err, stats) => {
expect(stats.hasErrors()).toBe(true);
done();
});
});

it('should correctly indentifies a success', (done) => {
const compiler = pack('good', { failOnError: true });

compiler.run((err, stats) => {
expect(stats.hasErrors()).toBe(false);
done();
});
});

it('should emits errors when cache enabled', (done) => {
const compiler = pack('error', { failOnError: true, cache: true });

compiler.run((err, stats) => {
expect(stats.hasErrors()).toBe(true);
done();
});
});
});
30 changes: 30 additions & 0 deletions test/fail-on-warning.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import pack from './utils/pack';

describe('fail on warning', () => {
it('should emits errors', (done) => {
const compiler = pack('warn', { failOnWarning: true });

compiler.run((err, stats) => {
expect(stats.hasErrors()).toBe(true);
done();
});
});

it('should correctly indentifies a success', (done) => {
const compiler = pack('good', { failOnWarning: true });

compiler.run((err, stats) => {
expect(stats.hasErrors()).toBe(false);
done();
});
});

it('should emits errors when cache enabled', (done) => {
const compiler = pack('error', { failOnWarning: true, cache: true });

compiler.run((err, stats) => {
expect(stats.hasErrors()).toBe(true);
done();
});
});
});
2 changes: 2 additions & 0 deletions test/fixtures/fixable.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use strict'

function foo() {
return true
}
4 changes: 1 addition & 3 deletions test/fixtures/good-semi.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"use strict"

function test() {
return "value"
return 'value'
}

test()
2 changes: 0 additions & 2 deletions test/fixtures/good.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
"use strict"

function test() {
return "value"
}
2 changes: 1 addition & 1 deletion test/fixtures/ignore.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// this file should be totally ignore since it's present in .eslintignore
var -dasdas;
var -dasdas;
4 changes: 2 additions & 2 deletions test/fixtures/warn.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/* eslint no-unused-vars: 1 */
var foo = this
/* eslint no-unused-vars: warn */
const foo = this
32 changes: 0 additions & 32 deletions test/force-emit-error.js

This file was deleted.

13 changes: 13 additions & 0 deletions test/force-emit-error.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import pack from './utils/pack';

describe('force emit error', () => {
it('should force to emit error', (done) => {
const compiler = pack('warn', { emitError: true });

compiler.run((err, stats) => {
expect(stats.hasWarnings()).toBe(false);
expect(stats.hasErrors()).toBe(true);
done();
});
});
});
32 changes: 0 additions & 32 deletions test/force-emit-warning.js

This file was deleted.

13 changes: 13 additions & 0 deletions test/force-emit-warning.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import pack from './utils/pack';

describe('force emit warning', () => {
it('should force to emit warning', (done) => {
const compiler = pack('error', { emitWarning: true });

compiler.run((err, stats) => {
expect(stats.hasWarnings()).toBe(true);
expect(stats.hasErrors()).toBe(false);
done();
});
});
});
37 changes: 0 additions & 37 deletions test/formatter-custom.js

This file was deleted.

23 changes: 23 additions & 0 deletions test/formatter-custom.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import pack from './utils/pack';

describe('formatter eslint', () => {
it('should use custom formatter as function', (done) => {
const formatter = require('eslint-friendly-formatter');
const compiler = pack('error', { formatter });

compiler.run((err, stats) => {
expect(stats.compilation.errors[0].message).toBeTruthy();
done();
});
});

it('should use custom formatter as string', (done) => {
const formatter = 'eslint-friendly-formatter';
const compiler = pack('error', { formatter });

compiler.run((err, stats) => {
expect(stats.compilation.errors[0].message).toBeTruthy();
done();
});
});
});
29 changes: 0 additions & 29 deletions test/formatter-eslint.js

This file was deleted.

12 changes: 12 additions & 0 deletions test/formatter-eslint.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import pack from './utils/pack';

describe('formatter eslint', () => {
it('should use eslint formatter', (done) => {
const compiler = pack('error');

compiler.run((err, stats) => {
expect(stats.compilation.errors[0].message).toBeTruthy();
done();
});
});
});
59 changes: 0 additions & 59 deletions test/formatter-multiple-entries.js

This file was deleted.

41 changes: 41 additions & 0 deletions test/formatter-multiple-entries.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { basename, join } from 'path';

import { readFileSync } from 'fs-extra';
import { CLIEngine } from 'eslint';
import webpack from 'webpack';

import conf from './utils/conf';

describe('formatter multiple entries', () => {
it('should be configured to write multiple eslint result files', (done) => {
const formatter = CLIEngine.getFormatter('checkstyle');
const outputFilename = 'outputReport-[name].txt';
const config = conf(
[
join(__dirname, 'fixtures/error-multi-two.js'),
join(__dirname, 'fixtures/error-multi-one.js'),
join(__dirname, 'fixtures/error-multi.js'),
],
{
formatter,
outputReport: {
filePath: outputFilename,
formatter,
},
}
);

const compiler = webpack(config);

compiler.run((err, stats) => {
stats.compilation.errors.forEach((e) => {
const name = basename(e.module.resource, '.js');
const filename = join(config.output.path, `outputReport-${name}.txt`);
const contents = readFileSync(filename, 'utf8');
expect(e.error.message).toBe(contents);
});

done();
});
});
});
12 changes: 12 additions & 0 deletions test/formatter-official.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import pack from './utils/pack';

describe('formatter official', () => {
it('should use official formatter', (done) => {
const compiler = pack('error', { formatter: 'table' });

compiler.run((err, stats) => {
expect(stats.compilation.errors[0].message).toBeTruthy();
done();
});
});
});
60 changes: 0 additions & 60 deletions test/formatter-write.js

This file was deleted.

51 changes: 51 additions & 0 deletions test/formatter-write.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { join } from 'path';

import { readFileSync } from 'fs-extra';
import { CLIEngine } from 'eslint';
import webpack from 'webpack';

import conf from './utils/conf';

describe('formatter write', () => {
it('should configured to write eslint results to a file (relative path)', (done) => {
const outputFilename = 'outputReport-relative.txt';
const loaderOptions = {
formatter: CLIEngine.getFormatter('checkstyle'),
outputReport: {
filePath: outputFilename,
},
};

const config = conf('error', loaderOptions);
const compiler = webpack(config);

compiler.run((err, stats) => {
const filePath = join(config.output.path, outputFilename);
const contents = readFileSync(filePath, 'utf8');

expect(stats.compilation.errors[0].error.message).toBe(contents);
done();
});
});

it('should configured to write eslint results to a file (absolute path)', (done) => {
const outputFilename = 'outputReport-absolute.txt';
const outputFilepath = join(__dirname, 'output', outputFilename);
const loaderOptions = {
formatter: CLIEngine.getFormatter('checkstyle'),
outputReport: {
filePath: outputFilepath,
},
};

const config = conf('error', loaderOptions);
const compiler = webpack(config);

compiler.run((err, stats) => {
const contents = readFileSync(outputFilepath, 'utf8');

expect(stats.compilation.errors[0].error.message).toBe(contents);
done();
});
});
});
73 changes: 49 additions & 24 deletions test/mock/eslint/index.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,58 @@
function CLIEngine() {
function CLIEngine() {}

}

CLIEngine.prototype.executeOnText = function() {
CLIEngine.prototype.executeOnText = function executeOnText() {
return {
results: [{
filePath: "",
messages: [{
ruleId: "no-undef",
severity: 2,
message: "Fake error",
line: 1,
column: 11,
nodeType: "Identifier",
source: "var foo = stuff",
}],
errorCount: 2,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0,
source: "",
}],
results: [
{
filePath: '',
messages: [
{
ruleId: 'no-undef',
severity: 2,
message: 'Fake error',
line: 1,
column: 11,
nodeType: 'Identifier',
source: 'var foo = stuff',
},
],
errorCount: 2,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0,
source: '',
},
],
errorCount: 2,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0,
};
};

CLIEngine.prototype.getFormatter = function getFormatter(format) {
const resolvedFormatName = format || 'stylish';

if (typeof resolvedFormatName !== 'string') {
return null;
}
}

const eslintVersion = require('./package.json').version;
const formatterPath =
eslintVersion >= '6.0.0'
? './lib/cli-engine/formatters/stylish'
: './lib/formatters/stylish';

try {
return require(formatterPath);
} catch (ex) {
ex.message = `There was a problem loading formatter: ${formatterPath}\nError: ${ex.message}`;
throw ex;
}
};

CLIEngine.getFormatter = CLIEngine.prototype.getFormatter;

module.exports = {
CLIEngine: CLIEngine,
}
CLIEngine,
};
3 changes: 3 additions & 0 deletions test/mock/eslint/lib/cli-engine/formatters/stylish.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = function formatter(result) {
return JSON.stringify(result);
};
6 changes: 3 additions & 3 deletions test/mock/eslint/lib/formatters/stylish.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module.exports = function(result) {
return JSON.stringify(result)
}
module.exports = function formatter(result) {
return JSON.stringify(result);
};
4 changes: 4 additions & 0 deletions test/mock/eslint/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "eslint",
"version": "5.16.0"
}
52 changes: 0 additions & 52 deletions test/multiple-engines.js

This file was deleted.

Loading