rizowski / eslint-watch

ESLint with simple watching capabilities
https://www.npmjs.com/package/eslint-watch
MIT License
193 stars 29 forks source link

Running `esw --changed -w` causes non-JS files to attempt to be linted #160

Closed bobwhitelock closed 5 years ago

bobwhitelock commented 5 years ago

Environment

Basic Description of the problem

Running esw --changed -w causes non-JS files to attempt to be linted.

We noticed this after upgrading from eslint-watch v3 to v5; this command was working as expected (only detecting/linting JS code in a repo when run in a repo containing many languages) in v3 for a long time.

How to reproduce it

  1. Clone this repo; have master branch checked out.
  2. touch foo.py
  3. bin/esw --changed -w
  4. In an editor, add some Python code to foo.py, e.g.:
    def foo():
      pass
  5. The watch process detects this and prints a spurious error:

    
    /home/bob/src/rizowski/eslint-watch/foo.py
    2:5  error  Parsing error: Unexpected token, expected ";"
    
    1 |
    > 2 | def foo():
    |     ^
    3 |     pass
    4 |

✖ 1 problem (1 error, 0 warnings)


### Debug output:

<details>

$ DEBUG='esw:' bin/esw --changed -w esw:eslint-help Loaded +0ms esw:main [ '--changed', '-w' ] +0ms esw:main ESW: v5.1.2 +2ms esw:eslint Executing [ '--help' ] +0ms esw:eslint { stdout: 'eslint [options] file.js [file.js] [dir]\n\nBasic configuration:\n --no-eslintrc Disable use of configuration from .eslintrc.\n -c, --config path::String Use this configuration, overriding .eslintrc. config options if present\n --env [String] Specify environments\n --ext [String] Specify JavaScript file extensions - default: .js\n --global [String] Define global variables\n --parser String Specify the parser to be used\n --parser-options Object Specify parser options\n\nSpecifying rules and plugins:\n --rulesdir [path::String] Use additional rules from this directory\n --plugin [String] Specify plugins\n --rule Object Specify rules\n\nFixing problems:\n --fix Automatically fix problems\n --fix-dry-run Automatically fix problems without saving the changes to the file system\n --fix-type Array Specify the types of fixes to apply (problem, suggestion, layout)\n\nIgnoring files:\n --ignore-path path::String Specify path of ignore file\n --no-ignore Disable use of ignore files and patterns\n --ignore-pattern [String] Pattern of files to ignore (in addition to those in .eslintignore)\n\nUsing stdin:\n --stdin Lint code provided on - default: false\n --stdin-filename String Specify filename to process STDIN as\n\nHandling warnings:\n --quiet Report errors only - default: false\n --max-warnings Int Number of warnings to trigger nonzero exit code - default: -1\n\nOutput:\n -o, --output-file path::String Specify file to write report to\n -f, --format String Use a specific output format - default: stylish\n --color, --no-color Force enabling/disabling of color\n\nInline configuration comments:\n --no-inline-config Prevent comments from changing config or rules\n --report-unused-disable-directives Adds reported errors for unused eslint-disable directives\n\nCaching:\n --cache Only check changed files - default: false\n --cache-file path::String Path to the cache file. Deprecated: use --cache-location - default: .eslintcache\n --cache-location path::String Path to the cache file or directory\n\nMiscellaneous:\n --init Run config initialization wizard - default: false\n --debug Output debugging information\n -h, --help Show help\n -v, --version Output the version number\n --print-config path::String Print the configuration for the given file', esw:eslint stderr: '', esw:eslint code: 0, esw:eslint failed: false, esw:eslint killed: false, esw:eslint signal: null, esw:eslint cmd: 'eslint --help', esw:eslint timedOut: false } +241ms esw:eslint-help Parsing --no-eslintrc +332ms esw:eslint-help Parsing no option --no-eslintrc +0ms esw:eslint-help Alias found: -c +1ms esw:eslint-help Parsing --config +0ms esw:eslint-help Parsing --env +0ms esw:eslint-help Parsing --ext +0ms esw:eslint-help Parsing --global +0ms esw:eslint-help Parsing --parser +0ms esw:eslint-help Parsing --parser-options +0ms esw:eslint-help Parsing --rulesdir +0ms esw:eslint-help Parsing --plugin +0ms esw:eslint-help Parsing --rule +0ms esw:eslint-help Parsing --fix +0ms esw:eslint-help Parsing --fix-dry-run +0ms esw:eslint-help Parsing --fix-type +0ms esw:eslint-help Parsing --ignore-path +0ms esw:eslint-help Parsing --no-ignore +0ms esw:eslint-help Parsing no option --no-ignore +0ms esw:eslint-help Parsing --ignore-pattern +0ms esw:eslint-help Parsing --stdin +1ms esw:eslint-help Parsing --stdin-filename +0ms esw:eslint-help Parsing --quiet +0ms esw:eslint-help Parsing --max-warnings +0ms esw:eslint-help Alias found: -o +0ms esw:eslint-help Parsing --output-file +0ms esw:eslint-help Alias found: -f +0ms esw:eslint-help Parsing --format +0ms esw:eslint-help Parsing --no-inline-config +0ms esw:eslint-help Parsing no option --no-inline-config +0ms esw:eslint-help Parsing --report-unused-disable-directives +0ms esw:eslint-help Parsing --cache +0ms esw:eslint-help Parsing --cache-file +0ms esw:eslint-help Parsing --cache-location +0ms esw:eslint-help Parsing --init +0ms esw:eslint-help Parsing --debug +0ms esw:eslint-help Alias found: -h +0ms esw:eslint-help Parsing --help +0ms esw:eslint-help Alias found: -v +0ms esw:eslint-help Parsing --version +0ms esw:eslint-help Parsing --print-config +0ms esw:options [ { heading: 'ESW Options' }, esw:options { option: 'help', esw:options alias: 'h', esw:options type: 'Boolean', esw:options description: 'Show help' }, esw:options { option: 'watch', esw:options alias: 'w', esw:options type: 'Boolean', esw:options description: 'Enable file watch' }, esw:options { option: 'changed', esw:options type: 'Boolean', esw:options description: 'Enables single file linting while watch is enabled' }, esw:options { option: 'clear', esw:options type: 'Boolean', esw:options description: 'Clear terminal when running lint' }, esw:options { option: 'version', esw:options type: 'Boolean', esw:options alias: 'v', esw:options description: 'Prints Eslint-Watch Version' }, esw:options { option: 'versions', esw:options type: 'Boolean', esw:options description: 'Prints Eslint-Watch and Eslint Versions' }, esw:options { option: 'watch-ignore', esw:options type: 'RegExp', esw:options description: 'Regex string of folders to ignore when watching - default: /.git|node_modules|bower_components/' }, esw:options { option: 'watch-delay', esw:options type: 'Int', esw:options description: 'Delay(ms) for watcher to wait to trigger re-lint', esw:options default: '300' }, esw:options { heading: 'Basic configuration' }, esw:options { default: 'true', esw:options option: 'eslintrc', esw:options type: 'Boolean', esw:options description: 'Disable use of configuration from .eslintrc.' }, esw:options { option: 'config', esw:options type: 'path::String', esw:options description: 'Use this configuration, overriding .eslintrc.* config options if present', esw:options alias: 'c' }, esw:options { option: 'env', esw:options type: '[String]', esw:options description: 'Specify environments' }, esw:options { option: 'ext', esw:options type: '[String]', esw:options description: 'Specify JavaScript file extensions - default: .js' }, esw:options { option: 'global', esw:options type: '[String]', esw:options description: 'Define global variables' }, esw:options { option: 'parser', esw:options type: 'String', esw:options description: 'Specify the parser to be used' }, esw:options { option: 'parser-options', esw:options type: 'Object', esw:options description: 'Specify parser options' }, esw:options { heading: 'Specifying rules and plugins' }, esw:options { option: 'rulesdir', esw:options type: '[path::String]', esw:options description: 'Use additional rules from this directory' }, esw:options { option: 'plugin', esw:options type: '[String]', esw:options description: 'Specify plugins' }, esw:options { option: 'rule', type: 'Object', description: 'Specify rules' }, esw:options { heading: 'Fixing problems' }, esw:options { option: 'fix', esw:options type: 'Boolean', esw:options description: 'Automatically fix problems' }, esw:options { option: 'fix-dry-run', esw:options type: 'Boolean', esw:options description: 'Automatically fix problems without saving the changes to the file system' }, esw:options { option: 'fix-type', esw:options type: 'Array', esw:options description: 'Specify the types of fixes to apply (problem suggestion, layout)' }, esw:options { heading: 'Ignoring files' }, esw:options { option: 'ignore-path', esw:options type: 'path::String', esw:options description: 'Specify path of ignore file' }, esw:options { default: 'true', esw:options option: 'ignore', esw:options type: 'Boolean', esw:options description: 'Disable use of ignore files and patterns' }, esw:options { option: 'ignore-pattern', esw:options type: '[String]', esw:options description: 'Pattern of files to ignore (in addition to those in .eslintignore)' }, esw:options { heading: 'Using stdin' }, esw:options { option: 'stdin', esw:options type: 'Boolean', esw:options description: 'Lint code provided on - default: false' }, esw:options { option: 'stdin-filename', esw:options type: 'String', esw:options description: 'Specify filename to process STDIN as' }, esw:options { heading: 'Handling warnings' }, esw:options { option: 'quiet', esw:options type: 'Boolean', esw:options description: 'Report errors only - default: false' }, esw:options { option: 'max-warnings', esw:options type: 'Int', esw:options description: 'Number of warnings to trigger nonzero exit code - default: -1' }, esw:options { heading: 'Output' }, esw:options { option: 'output-file', esw:options type: 'path::String', esw:options description: 'Specify file to write report to', esw:options alias: 'o' }, esw:options { option: 'format', esw:options type: 'String', esw:options description: 'Use a specific output format - default: stylish', esw:options alias: 'f' }, esw:options { option: 'color', esw:options type: 'Boolean', esw:options alias: 'no-color', esw:options description: 'Force enabling/disabling of color' }, esw:options { heading: 'Inline configuration comments' }, esw:options { default: 'true', esw:options option: 'inline-config', esw:options type: 'Boolean', esw:options description: 'Prevent comments from changing config or rules' }, esw:options { option: 'report-unused-disable-directives', esw:options type: 'Boolean', esw:options description: 'Adds reported errors for unused eslint-disable directives' }, esw:options { heading: 'Caching' }, esw:options { option: 'cache', esw:options type: 'Boolean', esw:options description: 'Only check changed files - default: false' }, esw:options { option: 'cache-file', esw:options type: 'path::String', esw:options description: 'Path to the cache file. Deprecated: use --cache-location - default: .eslintcache' }, esw:options { option: 'cache-location', esw:options type: 'path::String', esw:options description: 'Path to the cache file or directory' }, esw:options { heading: 'Miscellaneous' }, esw:options { option: 'init', esw:options type: 'Boolean', esw:options description: 'Run config initialization wizard - default: false' }, esw:options { option: 'debug', esw:options type: 'Boolean', esw:options description: 'Output debugging information' }, esw:options { option: 'print-config', esw:options type: 'path::String', esw:options description: 'Print the configuration for the given file' } ] +0ms esw:main { changed: true, esw:main watch: true, esw:main watchDelay: 300, esw:main eslintrc: true, esw:main ignore: true, esw:main inlineConfig: true, esw:main _: [ '/home/bob/src/rizowski/eslint-watch' ] } +252ms esw:commands Running 0 esw commands +0ms esw:commands Success: +0ms esw:watch:chokidar Watching [ '/home/bob/src/rizowski/eslint-watch' ] { ignored: undefined } +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/.babelrc added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/.editorconfig added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/.eslintignore added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/.eslintrc added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/.nvmrc added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/.nycrc added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/.prettierrc added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/.travis.yml added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/.yarnclean added. +1ms esw:events:watch /home/bob/src/rizowski/eslint-watch/LICENSE added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/README.md added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/appveyor.yml added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/foo.py added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/package-lock.json added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/yarn.lock added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/package.json added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/bin/esw added. +3ms esw:events:watch /home/bob/src/rizowski/eslint-watch/build/index.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/build/logger.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/scripts/deploy.sh added. +1ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/.eslintrc added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/globals.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/mocha-integration.opts added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/mocha-unit.opts added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/mocha.opts added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/src/index.js added. +1ms esw:events:watch /home/bob/src/rizowski/eslint-watch/src/logger.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/build/cli/options.js added. +7ms esw:events:watch /home/bob/src/rizowski/eslint-watch/build/commands/clear.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/build/commands/index.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/build/commands/version.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/build/commands/versions.js added. +1ms esw:events:watch /home/bob/src/rizowski/eslint-watch/build/eslint/index.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/build/eslint/parser.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/integration/integration-spec.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/mocks/eslint-help.text added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/mocks/index.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/src/cli/options.js added. +1ms esw:events:watch /home/bob/src/rizowski/eslint-watch/src/commands/clear.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/src/commands/index.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/src/commands/version.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/src/commands/versions.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/src/eslint/index.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/src/eslint/parser.js added. +1ms esw:events:watch /home/bob/src/rizowski/eslint-watch/build/events/watch/chokidar.js added. +4ms esw:events:watch /home/bob/src/rizowski/eslint-watch/build/events/watch/index.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/build/events/watch/key-listener.js added. +1ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/integration/test-files/.eslintrc added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/unit/cli/options-spec.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/unit/commands/clear-spec.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/unit/commands/commands-spec.js added. +1ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/unit/commands/version-spec.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/unit/commands/versions-spec.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/unit/eslint/eslint-spec.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/unit/eslint/help-parser-spec.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/unit/events/chokidar-spec.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/unit/events/watch-spec.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/src/events/watch/chokidar.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/src/events/watch/index.js added. +0ms esw:events:watch /home/bob/src/rizowski/eslint-watch/src/events/watch/key-listener.js added. +1ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/integration/test-files/sub1/a.js added. +1ms esw:events:watch /home/bob/src/rizowski/eslint-watch/tests/integration/test-files/sub2/b.js added. +0ms esw:events:watch Ready +0ms esw:eslint Executing [ '--eslintrc', '--ignore', '--inline-config', '/home/bob/src/rizowski/eslint-watch' ] +0ms esw:eslint { stdout: '\n/home/bob/src/rizowski/eslint-watch/src/cli/options.js\n 88:11 warning The use of method push is not allowed as it might be a mutating method fp/no-mutating-methods\n 112:13 warning The use of method push is not allowed as it might be a mutating method fp/no-mutating-methods\n 119:11 warning The use of method push is not allowed as it might be a mutating method fp/no-mutating-methods\n 121:11 warning The use of method push is not allowed as it might be a mutating method fp/no-mutating-methods\n 122:11 warning The use of method push is not allowed as it might be a mutating method fp/no-mutating-methods\n\n/home/bob/src/rizowski/eslint-watch/src/eslint/parser.js\n 24:3 warning Function \'parseNo\' expected no return value consistent-return\n 63:3 warning Function \'parseRegular\' expected no return value consistent-return\n 106:7 warning The use of method push is not allowed as it might be a mutating method fp/no-mutating-methods\n 122:5 warning The use of method push is not allowed as it might be a mutating method fp/no-mutating-methods\n\n/home/bob/src/rizowski/eslint-watch/src/events/watch/chokidar.js\n 12:21 warning The use of method watch is not allowed as it might be a mutating method fp/no-mutating-methods\n\n/home/bob/src/rizowski/eslint-watch/src/index.js\n 35:7 warning Async method \'run\' expected a return value consistent-return\n\n✖ 11 problems (0 errors, 11 warnings)\n', esw:eslint stderr: '', esw:eslint code: 0, esw:eslint failed: false, esw:eslint killed: false, esw:eslint signal: null, esw:eslint cmd: 'eslint --eslintrc --ignore --inline-config /home/bob/src/rizowski/eslint-watch', esw:eslint timedOut: false } +926ms

/home/bob/src/rizowski/eslint-watch/src/cli/options.js 88:11 warning The use of method push is not allowed as it might be a mutating method fp/no-mutating-methods 112:13 warning The use of method push is not allowed as it might be a mutating method fp/no-mutating-methods 119:11 warning The use of method push is not allowed as it might be a mutating method fp/no-mutating-methods 121:11 warning The use of method push is not allowed as it might be a mutating method fp/no-mutating-methods 122:11 warning The use of method push is not allowed as it might be a mutating method fp/no-mutating-methods

/home/bob/src/rizowski/eslint-watch/src/eslint/parser.js 24:3 warning Function 'parseNo' expected no return value consistent-return 63:3 warning Function 'parseRegular' expected no return value consistent-return 106:7 warning The use of method push is not allowed as it might be a mutating method fp/no-mutating-methods 122:5 warning The use of method push is not allowed as it might be a mutating method fp/no-mutating-methods

/home/bob/src/rizowski/eslint-watch/src/events/watch/chokidar.js 12:21 warning The use of method watch is not allowed as it might be a mutating method fp/no-mutating-methods

/home/bob/src/rizowski/eslint-watch/src/index.js 35:7 warning Async method 'run' expected a return value consistent-return

✖ 11 problems (0 errors, 11 warnings)

esw:events:watch Detected change: /home/bob/src/rizowski/eslint-watch/foo.py +7s esw:eslint Executing [ '--eslintrc', '--ignore', '--inline-config', '/home/bob/src/rizowski/eslint-watch/foo.py' ] +0ms esw:eslint Error: Command failed: eslint --eslintrc --ignore --inline-config /home/bob/src/rizowski/eslint-watch/foo.py esw:eslint esw:eslint esw:eslint /home/bob/src/rizowski/eslint-watch/foo.py esw:eslint 2:5 error Parsing error: Unexpected token, expected ";" esw:eslint esw:eslint 1 | esw:eslint > 2 | def foo(): esw:eslint | ^ esw:eslint 3 | pass esw:eslint 4 | esw:eslint esw:eslint ✖ 1 problem (1 error, 0 warnings) esw:eslint esw:eslint esw:eslint at makeError (/home/bob/src/rizowski/eslint-watch/node_modules/execa/index.js:174:9) esw:eslint at Promise.all.then.arr (/home/bob/src/rizowski/eslint-watch/node_modules/execa/index.js:278:16) esw:eslint at esw:eslint at process._tickCallback (internal/process/next_tick.js:189:7) +514ms /home/bob/src/rizowski/eslint-watch/foo.py 2:5 error Parsing error: Unexpected token, expected ";"

1 |

2 | def foo(): | ^ 3 | pass 4 |

✖ 1 problem (1 error, 0 warnings)



</details>
rizowski commented 5 years ago

Looks like I did forget a piece when moving to 5.

https://github.com/rizowski/eslint-watch/blob/3a789d2bb9e5ebe0047577902eb24e977782386f/src/watcher.js#L143-L147

bobwhitelock commented 5 years ago

Ah right, thanks for the quick response!

rizowski commented 5 years ago

This has been released with esw@6.0.0

bobwhitelock commented 5 years ago

Amazing, thanks!