eslint 5.2.0 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/conf/eslint-recommended.js +4 -0
  3. package/lib/cli-engine.js +12 -12
  4. package/lib/code-path-analysis/code-path-analyzer.js +1 -1
  5. package/lib/config/config-initializer.js +7 -7
  6. package/lib/config.js +1 -1
  7. package/lib/ignored-paths.js +125 -37
  8. package/lib/linter.js +1 -1
  9. package/lib/rules/array-bracket-newline.js +1 -1
  10. package/lib/rules/array-bracket-spacing.js +1 -1
  11. package/lib/rules/array-callback-return.js +1 -1
  12. package/lib/rules/array-element-newline.js +1 -1
  13. package/lib/rules/arrow-body-style.js +1 -1
  14. package/lib/rules/arrow-parens.js +1 -1
  15. package/lib/rules/arrow-spacing.js +1 -1
  16. package/lib/rules/block-spacing.js +1 -1
  17. package/lib/rules/brace-style.js +1 -1
  18. package/lib/rules/capitalized-comments.js +1 -1
  19. package/lib/rules/comma-dangle.js +1 -1
  20. package/lib/rules/comma-spacing.js +1 -1
  21. package/lib/rules/comma-style.js +1 -1
  22. package/lib/rules/complexity.js +1 -1
  23. package/lib/rules/computed-property-spacing.js +1 -1
  24. package/lib/rules/consistent-return.js +1 -1
  25. package/lib/rules/curly.js +1 -1
  26. package/lib/rules/dot-location.js +1 -1
  27. package/lib/rules/dot-notation.js +1 -1
  28. package/lib/rules/eqeqeq.js +1 -1
  29. package/lib/rules/func-call-spacing.js +1 -1
  30. package/lib/rules/func-name-matching.js +1 -1
  31. package/lib/rules/func-names.js +1 -1
  32. package/lib/rules/function-paren-newline.js +1 -1
  33. package/lib/rules/getter-return.js +1 -1
  34. package/lib/rules/indent-legacy.js +1 -1
  35. package/lib/rules/indent.js +37 -5
  36. package/lib/rules/jsx-quotes.js +1 -1
  37. package/lib/rules/key-spacing.js +2 -2
  38. package/lib/rules/keyword-spacing.js +1 -1
  39. package/lib/rules/line-comment-position.js +2 -2
  40. package/lib/rules/linebreak-style.js +1 -1
  41. package/lib/rules/lines-around-comment.js +1 -1
  42. package/lib/rules/lines-around-directive.js +1 -1
  43. package/lib/rules/lines-between-class-members.js +1 -1
  44. package/lib/rules/max-len.js +1 -1
  45. package/lib/rules/max-lines-per-function.js +1 -1
  46. package/lib/rules/max-lines.js +1 -1
  47. package/lib/rules/max-params.js +1 -1
  48. package/lib/rules/max-statements-per-line.js +1 -1
  49. package/lib/rules/max-statements.js +1 -1
  50. package/lib/rules/multiline-comment-style.js +1 -1
  51. package/lib/rules/multiline-ternary.js +1 -1
  52. package/lib/rules/new-parens.js +1 -1
  53. package/lib/rules/newline-after-var.js +1 -1
  54. package/lib/rules/newline-per-chained-call.js +1 -1
  55. package/lib/rules/no-alert.js +1 -1
  56. package/lib/rules/no-async-promise-executor.js +33 -0
  57. package/lib/rules/no-catch-shadow.js +1 -1
  58. package/lib/rules/no-class-assign.js +1 -1
  59. package/lib/rules/no-cond-assign.js +1 -1
  60. package/lib/rules/no-confusing-arrow.js +1 -1
  61. package/lib/rules/no-console.js +1 -1
  62. package/lib/rules/no-const-assign.js +1 -1
  63. package/lib/rules/no-dupe-keys.js +1 -1
  64. package/lib/rules/no-else-return.js +1 -1
  65. package/lib/rules/no-empty-function.js +1 -1
  66. package/lib/rules/no-empty.js +1 -1
  67. package/lib/rules/no-eval.js +1 -1
  68. package/lib/rules/no-ex-assign.js +1 -1
  69. package/lib/rules/no-extend-native.js +1 -1
  70. package/lib/rules/no-extra-bind.js +1 -1
  71. package/lib/rules/no-extra-boolean-cast.js +1 -1
  72. package/lib/rules/no-extra-label.js +1 -1
  73. package/lib/rules/no-extra-parens.js +1 -1
  74. package/lib/rules/no-extra-semi.js +1 -1
  75. package/lib/rules/no-floating-decimal.js +1 -1
  76. package/lib/rules/no-func-assign.js +1 -1
  77. package/lib/rules/no-implicit-coercion.js +1 -1
  78. package/lib/rules/no-inline-comments.js +1 -1
  79. package/lib/rules/no-invalid-this.js +1 -1
  80. package/lib/rules/no-irregular-whitespace.js +1 -1
  81. package/lib/rules/no-label-var.js +1 -1
  82. package/lib/rules/no-labels.js +1 -1
  83. package/lib/rules/no-misleading-character-class.js +189 -0
  84. package/lib/rules/no-mixed-operators.js +1 -1
  85. package/lib/rules/no-multi-spaces.js +1 -1
  86. package/lib/rules/no-multi-str.js +1 -1
  87. package/lib/rules/no-regex-spaces.js +1 -1
  88. package/lib/rules/no-restricted-properties.js +1 -1
  89. package/lib/rules/no-return-assign.js +1 -1
  90. package/lib/rules/no-return-await.js +1 -1
  91. package/lib/rules/no-self-assign.js +1 -1
  92. package/lib/rules/no-sequences.js +1 -1
  93. package/lib/rules/no-shadow.js +1 -1
  94. package/lib/rules/no-this-before-super.js +1 -1
  95. package/lib/rules/no-throw-literal.js +1 -1
  96. package/lib/rules/no-trailing-spaces.js +1 -1
  97. package/lib/rules/no-undef-init.js +1 -1
  98. package/lib/rules/no-unexpected-multiline.js +1 -1
  99. package/lib/rules/no-unmodified-loop-condition.js +2 -3
  100. package/lib/rules/no-unneeded-ternary.js +1 -1
  101. package/lib/rules/no-unsafe-negation.js +1 -1
  102. package/lib/rules/no-unused-vars.js +1 -1
  103. package/lib/rules/no-useless-call.js +1 -1
  104. package/lib/rules/no-useless-computed-key.js +1 -1
  105. package/lib/rules/no-useless-concat.js +1 -1
  106. package/lib/rules/no-useless-escape.js +1 -1
  107. package/lib/rules/no-useless-return.js +2 -11
  108. package/lib/rules/no-var.js +1 -1
  109. package/lib/rules/no-warning-comments.js +1 -1
  110. package/lib/rules/no-whitespace-before-property.js +1 -1
  111. package/lib/rules/object-curly-newline.js +1 -1
  112. package/lib/rules/object-curly-spacing.js +1 -1
  113. package/lib/rules/object-shorthand.js +1 -1
  114. package/lib/rules/operator-assignment.js +1 -1
  115. package/lib/rules/operator-linebreak.js +1 -1
  116. package/lib/rules/padding-line-between-statements.js +2 -2
  117. package/lib/rules/prefer-const.js +2 -11
  118. package/lib/rules/prefer-object-spread.js +9 -3
  119. package/lib/rules/prefer-promise-reject-errors.js +1 -1
  120. package/lib/rules/prefer-spread.js +1 -1
  121. package/lib/rules/prefer-template.js +1 -1
  122. package/lib/rules/quotes.js +1 -1
  123. package/lib/rules/radix.js +1 -1
  124. package/lib/rules/require-atomic-updates.js +239 -0
  125. package/lib/rules/require-await.js +1 -1
  126. package/lib/rules/require-unicode-regexp.js +65 -0
  127. package/lib/rules/semi-spacing.js +1 -1
  128. package/lib/rules/semi-style.js +1 -1
  129. package/lib/rules/semi.js +1 -1
  130. package/lib/rules/sort-keys.js +1 -1
  131. package/lib/rules/space-before-blocks.js +1 -1
  132. package/lib/rules/space-before-function-paren.js +1 -1
  133. package/lib/rules/space-in-parens.js +1 -1
  134. package/lib/rules/space-unary-ops.js +1 -1
  135. package/lib/rules/spaced-comment.js +1 -1
  136. package/lib/rules/strict.js +1 -1
  137. package/lib/rules/switch-colon-spacing.js +1 -1
  138. package/lib/rules/symbol-description.js +1 -1
  139. package/lib/rules/template-curly-spacing.js +1 -1
  140. package/lib/rules/wrap-iife.js +1 -1
  141. package/lib/rules/yoda.js +1 -1
  142. package/lib/testers/rule-tester.js +2 -2
  143. package/lib/token-store/index.js +1 -1
  144. package/lib/{ast-utils.js → util/ast-utils.js} +0 -0
  145. package/lib/{file-finder.js → util/file-finder.js} +0 -0
  146. package/lib/util/fix-tracker.js +1 -1
  147. package/lib/util/{glob-util.js → glob-utils.js} +4 -4
  148. package/lib/util/naming.js +2 -2
  149. package/lib/util/node-event-generator.js +3 -3
  150. package/lib/util/{npm-util.js → npm-utils.js} +0 -0
  151. package/lib/util/{path-util.js → path-utils.js} +1 -1
  152. package/lib/util/{source-code-util.js → source-code-utils.js} +3 -3
  153. package/lib/util/source-code.js +1 -1
  154. package/lib/util/unicode/index.js +11 -0
  155. package/lib/util/unicode/is-combining-character.js +13 -0
  156. package/lib/util/unicode/is-emoji-modifier.js +13 -0
  157. package/lib/util/unicode/is-regional-indicator-symbol.js +13 -0
  158. package/lib/util/unicode/is-surrogate-pair.js +14 -0
  159. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,3 +1,37 @@
1
+ v5.3.0 - August 3, 2018
2
+
3
+ * dd6cb19 Docs: Updated no-return-await Rule Documentation (fixes #9695) (#10699) (Marla Foreman)
4
+ * 6009239 Chore: rename utils for consistency (#10727) (薛定谔的猫)
5
+ * 6eb972c New: require-unicode-regexp rule (fixes #9961) (#10698) (Toru Nagashima)
6
+ * 5c5d64d Fix: ignored-paths for Windows path (fixes #10687) (#10691) (Toru Nagashima)
7
+ * 5f6a765 Build: ensure URL fragments remain in documentation links (fixes #10717) (#10720) (Teddy Katz)
8
+ * 863aa78 Docs: add another example for when not to use no-await-in-loop (#10714) (Valeri Karpov)
9
+ * 6e78b7d Docs: remove links to terminated jscs.info domain (#10706) (Piotr Kuczynski)
10
+ * d56c39d Fix: ESLint cache no longer stops autofix (fixes #10679) (#10694) (Kevin Partington)
11
+ * 2cc3240 New: add no-misleading-character-class (fixes #10049) (#10511) (Toru Nagashima)
12
+ * 877f4b8 Fix: The "../.." folder is always ignored (fixes #10675) (#10682) (Sridhar)
13
+ * 5984820 Chore: Move lib/file-finder.js to lib/util/ (refs #10559) (#10695) (Kevin Partington)
14
+ * e37a593 Update: Fix incorrect default value for position (#10670) (Iulian Onofrei)
15
+ * 8084bfc Docs: change when not to use object spread (#10621) (Benny Powers)
16
+ * 7f496e2 Chore: Update require path for ast-utils (#10693) (Kevin Partington)
17
+ * 648a33a Chore: reorganize code structure of utilities (refs #10599) (#10680) (薛定谔的猫)
18
+ * f026fe1 Update: Fix 'function' in padding-line-between-statements (fixes #10487) (#10676) (Kevin Partington)
19
+ * c2bb8bb Docs: Remove superfluous object option sample code (#10652) (Iulian Onofrei)
20
+ * d34a13b Docs: add subheader in configuring/configuring-rules (#10686) (薛定谔的猫)
21
+ * d8aea28 Chore: rm unnecessary plugin in eslint-config-eslint (#10685) (薛定谔的猫)
22
+ * 9e76be7 Update: indent comments w/ nearby code if no blank lines (fixes #9733) (#10640) (Kevin Partington)
23
+ * 9e93d46 New: add no-async-promise-executor rule (fixes #10217) (#10661) (Teddy Katz)
24
+ * 5a2538c New: require-atomic-updates rule (fixes #10405) (#10655) (Teddy Katz)
25
+ * 8b83d2b Fix: always resolve default ignore patterns from CWD (fixes #9227) (#10638) (Teddy Katz)
26
+ * acb6658 Fix: ESLint crash with prefer-object-spread (fixes #10646) (#10649) (薛定谔的猫)
27
+ * 99fb7d3 Docs: fix misleading no-prototype-builtins description (#10666) (薛定谔的猫)
28
+ * 005b849 Docs: fix outdated description of `baseConfig` option (#10657) (Teddy Katz)
29
+ * 15a77c4 Docs: fix broken links (fixes eslint/eslint-jp#6) (#10658) (Toru Nagashima)
30
+ * 87cd344 Docs: Make marking a default option consistent with other rules (#10650) (Iulian Onofrei)
31
+ * 0cb5e3e Chore: Replace some function application with spread operators (#10645) (Kevin Partington)
32
+ * b6daf0e Docs: Remove superfluous section from no-unsafe-negation (#10648) (Iulian Onofrei)
33
+ * e1a3cac Chore: rm deprecated experimentalObjectRestSpread option in tests (#10647) (薛定谔的猫)
34
+
1
35
  v5.2.0 - July 20, 2018
2
36
 
3
37
  * 81283d0 Update: Cache files that failed linting (fixes #9948) (#10571) (Kevin Partington)
@@ -83,6 +83,7 @@ module.exports = {
83
83
  "newline-per-chained-call": "off",
84
84
  "no-alert": "off",
85
85
  "no-array-constructor": "off",
86
+ "no-async-promise-executor": "off",
86
87
  "no-await-in-loop": "off",
87
88
  "no-bitwise": "off",
88
89
  "no-buffer-constructor": "off",
@@ -139,6 +140,7 @@ module.exports = {
139
140
  "no-lonely-if": "off",
140
141
  "no-loop-func": "off",
141
142
  "no-magic-numbers": "off",
143
+ "no-misleading-character-class": "off",
142
144
  "no-mixed-operators": "off",
143
145
  "no-mixed-requires": "off",
144
146
  "no-mixed-spaces-and-tabs": "error",
@@ -240,8 +242,10 @@ module.exports = {
240
242
  "quote-props": "off",
241
243
  quotes: "off",
242
244
  radix: "off",
245
+ "require-atomic-updates": "off",
243
246
  "require-await": "off",
244
247
  "require-jsdoc": "off",
248
+ "require-unicode-regexp": "off",
245
249
  "require-yield": "error",
246
250
  "rest-spread-spacing": "off",
247
251
  semi: "off",
package/lib/cli-engine.js CHANGED
@@ -22,7 +22,7 @@ const fs = require("fs"),
22
22
  IgnoredPaths = require("./ignored-paths"),
23
23
  Config = require("./config"),
24
24
  LintResultCache = require("./util/lint-result-cache"),
25
- globUtil = require("./util/glob-util"),
25
+ globUtils = require("./util/glob-utils"),
26
26
  validator = require("./config/config-validator"),
27
27
  hash = require("./util/hash"),
28
28
  ModuleResolver = require("./util/module-resolver"),
@@ -41,7 +41,7 @@ const resolver = new ModuleResolver();
41
41
  * The options to configure a CLI engine with.
42
42
  * @typedef {Object} CLIEngineOptions
43
43
  * @property {boolean} allowInlineConfig Enable or disable inline configuration comments.
44
- * @property {boolean|Object} baseConfig Base config object. True enables recommend rules and environments.
44
+ * @property {Object} baseConfig Base config object, extended by all configs used with this CLIEngine instance
45
45
  * @property {boolean} cache Enable result caching.
46
46
  * @property {string} cacheLocation The cache file to use instead of .eslintcache.
47
47
  * @property {string} configFile The configuration file to use.
@@ -492,7 +492,7 @@ class CLIEngine {
492
492
  * @returns {string[]} The equivalent glob patterns.
493
493
  */
494
494
  resolveFileGlobPatterns(patterns) {
495
- return globUtil.resolveFileGlobPatterns(patterns.filter(Boolean), this.options);
495
+ return globUtils.resolveFileGlobPatterns(patterns.filter(Boolean), this.options);
496
496
  }
497
497
 
498
498
  /**
@@ -511,25 +511,25 @@ class CLIEngine {
511
511
  }
512
512
 
513
513
  const startTime = Date.now();
514
- const fileList = globUtil.listFilesToProcess(patterns, options);
514
+ const fileList = globUtils.listFilesToProcess(patterns, options);
515
515
  const results = fileList.map(fileInfo => {
516
516
  if (fileInfo.ignored) {
517
517
  return createIgnoreResult(fileInfo.filename, options.cwd);
518
518
  }
519
519
 
520
520
  if (options.cache) {
521
-
522
- /*
523
- * get the descriptor for this file
524
- * with the metadata and the flag that determines if
525
- * the file has changed
526
- */
527
521
  const cachedLintResults = lintResultCache.getCachedLintResults(fileInfo.filename);
528
522
 
529
523
  if (cachedLintResults) {
530
- debug(`Skipping file since it hasn't changed: ${fileInfo.filename}`);
524
+ const resultHadMessages = cachedLintResults.messages && cachedLintResults.messages.length;
525
+
526
+ if (resultHadMessages && options.fix) {
527
+ debug(`Reprocessing cached file to allow autofix: ${fileInfo.filename}`);
528
+ } else {
529
+ debug(`Skipping file since it hasn't changed: ${fileInfo.filename}`);
531
530
 
532
- return cachedLintResults;
531
+ return cachedLintResults;
532
+ }
533
533
  }
534
534
  }
535
535
 
@@ -14,7 +14,7 @@ const assert = require("assert"),
14
14
  CodePathSegment = require("./code-path-segment"),
15
15
  IdGenerator = require("./id-generator"),
16
16
  debug = require("./debug-helpers"),
17
- astUtils = require("../ast-utils");
17
+ astUtils = require("../util/ast-utils");
18
18
 
19
19
  //------------------------------------------------------------------------------
20
20
  // Helpers
@@ -16,9 +16,9 @@ const util = require("util"),
16
16
  autoconfig = require("./autoconfig.js"),
17
17
  ConfigFile = require("./config-file"),
18
18
  ConfigOps = require("./config-ops"),
19
- getSourceCodeOfFiles = require("../util/source-code-util").getSourceCodeOfFiles,
19
+ getSourceCodeOfFiles = require("../util/source-code-utils").getSourceCodeOfFiles,
20
20
  ModuleResolver = require("../util/module-resolver"),
21
- npmUtil = require("../util/npm-util"),
21
+ npmUtils = require("../util/npm-utils"),
22
22
  recConfig = require("../../conf/eslint-recommended"),
23
23
  log = require("../util/logging");
24
24
 
@@ -61,7 +61,7 @@ function writeFile(config, format) {
61
61
  /**
62
62
  * Get the peer dependencies of the given module.
63
63
  * This adds the gotten value to cache at the first time, then reuses it.
64
- * In a process, this function is called twice, but `npmUtil.fetchPeerDependencies` needs to access network which is relatively slow.
64
+ * In a process, this function is called twice, but `npmUtils.fetchPeerDependencies` needs to access network which is relatively slow.
65
65
  * @param {string} moduleName The module name to get.
66
66
  * @returns {Object} The peer dependencies of the given module.
67
67
  * This object is the object of `peerDependencies` field of `package.json`.
@@ -73,7 +73,7 @@ function getPeerDependencies(moduleName) {
73
73
  if (!result) {
74
74
  log.info(`Checking peerDependencies of ${moduleName}`);
75
75
 
76
- result = npmUtil.fetchPeerDependencies(moduleName);
76
+ result = npmUtils.fetchPeerDependencies(moduleName);
77
77
  getPeerDependencies.cache.set(moduleName, result);
78
78
  }
79
79
 
@@ -109,7 +109,7 @@ function getModulesList(config, installESLint) {
109
109
  if (installESLint === false) {
110
110
  delete modules.eslint;
111
111
  } else {
112
- const installStatus = npmUtil.checkDevDeps(["eslint"]);
112
+ const installStatus = npmUtils.checkDevDeps(["eslint"]);
113
113
 
114
114
  // Mark to show messages if it's new installation of eslint.
115
115
  if (installStatus.eslint === false) {
@@ -373,7 +373,7 @@ function hasESLintVersionConflict(answers) {
373
373
  */
374
374
  function installModules(modules) {
375
375
  log.info(`Installing ${modules.join(", ")}`);
376
- npmUtil.installSyncSaveDev(modules);
376
+ npmUtils.installSyncSaveDev(modules);
377
377
  }
378
378
 
379
379
  /* istanbul ignore next: no need to test inquirer */
@@ -438,7 +438,7 @@ function promptUser() {
438
438
  { name: "Google (https://github.com/google/eslint-config-google)", value: "google" }
439
439
  ],
440
440
  when(answers) {
441
- answers.packageJsonExists = npmUtil.checkPackageJson();
441
+ answers.packageJsonExists = npmUtils.checkPackageJson();
442
442
  return answers.source === "guide" && answers.packageJsonExists;
443
443
  }
444
444
  },
package/lib/config.js CHANGED
@@ -15,7 +15,7 @@ const path = require("path"),
15
15
  ConfigFile = require("./config/config-file"),
16
16
  ConfigCache = require("./config/config-cache"),
17
17
  Plugins = require("./config/plugins"),
18
- FileFinder = require("./file-finder"),
18
+ FileFinder = require("./util/file-finder"),
19
19
  isResolvable = require("is-resolvable");
20
20
 
21
21
  const debug = require("debug")("eslint:config");
@@ -12,7 +12,7 @@
12
12
  const fs = require("fs"),
13
13
  path = require("path"),
14
14
  ignore = require("ignore"),
15
- pathUtil = require("./util/path-util");
15
+ pathUtils = require("./util/path-utils");
16
16
 
17
17
  const debug = require("debug")("eslint:ignored-paths");
18
18
 
@@ -79,6 +79,40 @@ function mergeDefaultOptions(options) {
79
79
  return Object.assign({}, DEFAULT_OPTIONS, options);
80
80
  }
81
81
 
82
+ /* eslint-disable valid-jsdoc */
83
+ /**
84
+ * Normalize the path separators in a given string.
85
+ * On Windows environment, this replaces `\` by `/`.
86
+ * Otherwrise, this does nothing.
87
+ * @param {string} str The path string to normalize.
88
+ * @returns {string} The normalized path.
89
+ */
90
+ const normalizePathSeps = path.sep === "/"
91
+ ? (str => str)
92
+ : ((seps, str) => str.replace(seps, "/")).bind(null, new RegExp(`\\${path.sep}`, "g"));
93
+ /* eslint-enable valid-jsdoc */
94
+
95
+ /**
96
+ * Converts a glob pattern to a new glob pattern relative to a different directory
97
+ * @param {string} globPattern The glob pattern, relative the the old base directory
98
+ * @param {string} relativePathToOldBaseDir A relative path from the new base directory to the old one
99
+ * @returns {string} A glob pattern relative to the new base directory
100
+ */
101
+ function relativize(globPattern, relativePathToOldBaseDir) {
102
+ if (relativePathToOldBaseDir === "") {
103
+ return globPattern;
104
+ }
105
+
106
+ const prefix = globPattern.startsWith("!") ? "!" : "";
107
+ const globWithoutPrefix = globPattern.replace(/^!/, "");
108
+
109
+ if (globWithoutPrefix.startsWith("/")) {
110
+ return `${prefix}/${normalizePathSeps(relativePathToOldBaseDir)}${globWithoutPrefix}`;
111
+ }
112
+
113
+ return globPattern;
114
+ }
115
+
82
116
  //------------------------------------------------------------------------------
83
117
  // Public Interface
84
118
  //------------------------------------------------------------------------------
@@ -96,41 +130,36 @@ class IgnoredPaths {
96
130
 
97
131
  this.cache = {};
98
132
 
99
- /**
100
- * add pattern to node-ignore instance
101
- * @param {Object} ig, instance of node-ignore
102
- * @param {string} pattern, pattern do add to ig
103
- * @returns {array} raw ignore rules
104
- */
105
- function addPattern(ig, pattern) {
106
- return ig.addPattern(pattern);
107
- }
108
-
109
133
  this.defaultPatterns = [].concat(DEFAULT_IGNORE_DIRS, options.patterns || []);
110
- this.baseDir = options.cwd;
134
+
135
+ this.ignoreFileDir = options.ignore !== false && options.ignorePath
136
+ ? path.dirname(path.resolve(options.cwd, options.ignorePath))
137
+ : options.cwd;
138
+ this.options = options;
139
+ this._baseDir = null;
111
140
 
112
141
  this.ig = {
113
142
  custom: ignore(),
114
143
  default: ignore()
115
144
  };
116
145
 
117
- /*
118
- * Add a way to keep track of ignored files. This was present in node-ignore
119
- * 2.x, but dropped for now as of 3.0.10.
120
- */
121
- this.ig.custom.ignoreFiles = [];
122
- this.ig.default.ignoreFiles = [];
123
-
146
+ this.defaultPatterns.forEach(pattern => this.addPatternRelativeToCwd(this.ig.default, pattern));
124
147
  if (options.dotfiles !== true) {
125
148
 
126
149
  /*
127
150
  * ignore files beginning with a dot, but not files in a parent or
128
151
  * ancestor directory (which in relative format will begin with `../`).
129
152
  */
130
- addPattern(this.ig.default, [".*", "!../"]);
153
+ this.addPatternRelativeToCwd(this.ig.default, ".*");
154
+ this.addPatternRelativeToCwd(this.ig.default, "!../");
131
155
  }
132
156
 
133
- addPattern(this.ig.default, this.defaultPatterns);
157
+ /*
158
+ * Add a way to keep track of ignored files. This was present in node-ignore
159
+ * 2.x, but dropped for now as of 3.0.10.
160
+ */
161
+ this.ig.custom.ignoreFiles = [];
162
+ this.ig.default.ignoreFiles = [];
134
163
 
135
164
  if (options.ignore !== false) {
136
165
  let ignorePath;
@@ -154,13 +183,11 @@ class IgnoredPaths {
154
183
  debug(`Loaded ignore file ${ignorePath}`);
155
184
  } catch (e) {
156
185
  debug("Could not find ignore file in cwd");
157
- this.options = options;
158
186
  }
159
187
  }
160
188
 
161
189
  if (ignorePath) {
162
190
  debug(`Adding ${ignorePath}`);
163
- this.baseDir = path.dirname(path.resolve(options.cwd, ignorePath));
164
191
  this.addIgnoreFile(this.ig.custom, ignorePath);
165
192
  this.addIgnoreFile(this.ig.default, ignorePath);
166
193
  } else {
@@ -187,8 +214,8 @@ class IgnoredPaths {
187
214
  if (packageJSONOptions.eslintIgnore) {
188
215
  if (Array.isArray(packageJSONOptions.eslintIgnore)) {
189
216
  packageJSONOptions.eslintIgnore.forEach(pattern => {
190
- addPattern(this.ig.custom, pattern);
191
- addPattern(this.ig.default, pattern);
217
+ this.addPatternRelativeToIgnoreFile(this.ig.custom, pattern);
218
+ this.addPatternRelativeToIgnoreFile(this.ig.default, pattern);
192
219
  });
193
220
  } else {
194
221
  throw new TypeError("Package.json eslintIgnore property requires an array of paths");
@@ -202,12 +229,68 @@ class IgnoredPaths {
202
229
  }
203
230
 
204
231
  if (options.ignorePattern) {
205
- addPattern(this.ig.custom, options.ignorePattern);
206
- addPattern(this.ig.default, options.ignorePattern);
232
+ this.addPatternRelativeToCwd(this.ig.custom, options.ignorePattern);
233
+ this.addPatternRelativeToCwd(this.ig.default, options.ignorePattern);
207
234
  }
208
235
  }
236
+ }
209
237
 
210
- this.options = options;
238
+ /*
239
+ * If `ignoreFileDir` is a subdirectory of `cwd`, all paths will be normalized to be relative to `cwd`.
240
+ * Otherwise, all paths will be normalized to be relative to `ignoreFileDir`.
241
+ * This ensures that the final normalized ignore rule will not contain `..`, which is forbidden in
242
+ * ignore rules.
243
+ */
244
+
245
+ addPatternRelativeToCwd(ig, pattern) {
246
+ const baseDir = this.getBaseDir();
247
+ const cookedPattern = baseDir === this.options.cwd
248
+ ? pattern
249
+ : relativize(pattern, path.relative(baseDir, this.options.cwd));
250
+
251
+ ig.addPattern(cookedPattern);
252
+ debug("addPatternRelativeToCwd:\n original = %j\n cooked = %j", pattern, cookedPattern);
253
+ }
254
+
255
+ addPatternRelativeToIgnoreFile(ig, pattern) {
256
+ const baseDir = this.getBaseDir();
257
+ const cookedPattern = baseDir === this.ignoreFileDir
258
+ ? pattern
259
+ : relativize(pattern, path.relative(baseDir, this.ignoreFileDir));
260
+
261
+ ig.addPattern(cookedPattern);
262
+ debug("addPatternRelativeToIgnoreFile:\n original = %j\n cooked = %j", pattern, cookedPattern);
263
+ }
264
+
265
+ // Detect the common ancestor
266
+ getBaseDir() {
267
+ if (!this._baseDir) {
268
+ const a = path.resolve(this.options.cwd);
269
+ const b = path.resolve(this.ignoreFileDir);
270
+ let lastSepPos = 0;
271
+
272
+ // Set the shorter one (it's the common ancestor if one includes the other).
273
+ this._baseDir = a.length < b.length ? a : b;
274
+
275
+ // Set the common ancestor.
276
+ for (let i = 0; i < a.length && i < b.length; ++i) {
277
+ if (a[i] !== b[i]) {
278
+ this._baseDir = a.slice(0, lastSepPos);
279
+ break;
280
+ }
281
+ if (a[i] === path.sep) {
282
+ lastSepPos = i;
283
+ }
284
+ }
285
+
286
+ // If it's only Windows drive letter, it needs \
287
+ if (/^[A-Z]:$/.test(this._baseDir)) {
288
+ this._baseDir += "\\";
289
+ }
290
+
291
+ debug("baseDir = %j", this._baseDir);
292
+ }
293
+ return this._baseDir;
211
294
  }
212
295
 
213
296
  /**
@@ -217,7 +300,7 @@ class IgnoredPaths {
217
300
  */
218
301
  readIgnoreFile(filePath) {
219
302
  if (typeof this.cache[filePath] === "undefined") {
220
- this.cache[filePath] = fs.readFileSync(filePath, "utf8");
303
+ this.cache[filePath] = fs.readFileSync(filePath, "utf8").split(/\r?\n/g).filter(Boolean);
221
304
  }
222
305
  return this.cache[filePath];
223
306
  }
@@ -226,11 +309,13 @@ class IgnoredPaths {
226
309
  * add ignore file to node-ignore instance
227
310
  * @param {Object} ig, instance of node-ignore
228
311
  * @param {string} filePath, file to add to ig
229
- * @returns {array} raw ignore rules
312
+ * @returns {void}
230
313
  */
231
314
  addIgnoreFile(ig, filePath) {
232
315
  ig.ignoreFiles.push(filePath);
233
- return ig.add(this.readIgnoreFile(filePath));
316
+ this
317
+ .readIgnoreFile(filePath)
318
+ .forEach(ignoreRule => this.addPatternRelativeToIgnoreFile(ig, ignoreRule));
234
319
  }
235
320
 
236
321
  /**
@@ -243,7 +328,7 @@ class IgnoredPaths {
243
328
 
244
329
  let result = false;
245
330
  const absolutePath = path.resolve(this.options.cwd, filepath);
246
- const relativePath = pathUtil.getRelativePath(absolutePath, this.baseDir);
331
+ const relativePath = pathUtils.getRelativePath(absolutePath, this.getBaseDir());
247
332
 
248
333
  if (typeof category === "undefined") {
249
334
  result = (this.ig.default.filter([relativePath]).length === 0) ||
@@ -251,6 +336,9 @@ class IgnoredPaths {
251
336
  } else {
252
337
  result = (this.ig[category].filter([relativePath]).length === 0);
253
338
  }
339
+ debug("contains:");
340
+ debug(" target = %j", filepath);
341
+ debug(" result = %j", result);
254
342
 
255
343
  return result;
256
344
 
@@ -261,13 +349,15 @@ class IgnoredPaths {
261
349
  * @returns {function()} method to check whether a folder should be ignored by glob.
262
350
  */
263
351
  getIgnoredFoldersGlobChecker() {
352
+ const baseDir = this.getBaseDir();
353
+ const ig = ignore();
264
354
 
265
- const ig = ignore().add(DEFAULT_IGNORE_DIRS);
355
+ DEFAULT_IGNORE_DIRS.forEach(ignoreDir => this.addPatternRelativeToCwd(ig, ignoreDir));
266
356
 
267
357
  if (this.options.dotfiles !== true) {
268
358
 
269
359
  // Ignore hidden folders. (This cannot be ".*", or else it's not possible to unignore hidden files)
270
- ig.add([".*/*", "!../"]);
360
+ ig.add([".*/*", "!../*"]);
271
361
  }
272
362
 
273
363
  if (this.options.ignore) {
@@ -276,10 +366,8 @@ class IgnoredPaths {
276
366
 
277
367
  const filter = ig.createFilter();
278
368
 
279
- const base = this.baseDir;
280
-
281
369
  return function(absolutePath) {
282
- const relative = pathUtil.getRelativePath(absolutePath, base);
370
+ const relative = pathUtils.getRelativePath(absolutePath, baseDir);
283
371
 
284
372
  if (!relative) {
285
373
  return false;
package/lib/linter.js CHANGED
@@ -25,7 +25,7 @@ const eslintScope = require("eslint-scope"),
25
25
  createReportTranslator = require("./report-translator"),
26
26
  Rules = require("./rules"),
27
27
  timing = require("./util/timing"),
28
- astUtils = require("./ast-utils"),
28
+ astUtils = require("./util/ast-utils"),
29
29
  pkg = require("../package.json"),
30
30
  SourceCodeFixer = require("./util/source-code-fixer");
31
31
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const astUtils = require("../ast-utils");
8
+ const astUtils = require("../util/ast-utils");
9
9
 
10
10
  //------------------------------------------------------------------------------
11
11
  // Rule Definition
@@ -4,7 +4,7 @@
4
4
  */
5
5
  "use strict";
6
6
 
7
- const astUtils = require("../ast-utils");
7
+ const astUtils = require("../util/ast-utils");
8
8
 
9
9
  //------------------------------------------------------------------------------
10
10
  // Rule Definition
@@ -11,7 +11,7 @@
11
11
 
12
12
  const lodash = require("lodash");
13
13
 
14
- const astUtils = require("../ast-utils");
14
+ const astUtils = require("../util/ast-utils");
15
15
 
16
16
  //------------------------------------------------------------------------------
17
17
  // Helpers
@@ -5,7 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const astUtils = require("../ast-utils");
8
+ const astUtils = require("../util/ast-utils");
9
9
 
10
10
  //------------------------------------------------------------------------------
11
11
  // Rule Definition
@@ -8,7 +8,7 @@
8
8
  // Requirements
9
9
  //------------------------------------------------------------------------------
10
10
 
11
- const astUtils = require("../ast-utils");
11
+ const astUtils = require("../util/ast-utils");
12
12
 
13
13
  //------------------------------------------------------------------------------
14
14
  // Rule Definition
@@ -8,7 +8,7 @@
8
8
  // Requirements
9
9
  //------------------------------------------------------------------------------
10
10
 
11
- const astUtils = require("../ast-utils");
11
+ const astUtils = require("../util/ast-utils");
12
12
 
13
13
  //------------------------------------------------------------------------------
14
14
  // Rule Definition
@@ -8,7 +8,7 @@
8
8
  // Requirements
9
9
  //------------------------------------------------------------------------------
10
10
 
11
- const astUtils = require("../ast-utils");
11
+ const astUtils = require("../util/ast-utils");
12
12
 
13
13
  //------------------------------------------------------------------------------
14
14
  // Rule Definition
@@ -5,7 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const util = require("../ast-utils");
8
+ const util = require("../util/ast-utils");
9
9
 
10
10
  //------------------------------------------------------------------------------
11
11
  // Rule Definition
@@ -5,7 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const astUtils = require("../ast-utils");
8
+ const astUtils = require("../util/ast-utils");
9
9
 
10
10
  //------------------------------------------------------------------------------
11
11
  // Rule Definition
@@ -9,7 +9,7 @@
9
9
  //------------------------------------------------------------------------------
10
10
 
11
11
  const LETTER_PATTERN = require("../util/patterns/letters");
12
- const astUtils = require("../ast-utils");
12
+ const astUtils = require("../util/ast-utils");
13
13
 
14
14
  //------------------------------------------------------------------------------
15
15
  // Helpers
@@ -10,7 +10,7 @@
10
10
  //------------------------------------------------------------------------------
11
11
 
12
12
  const lodash = require("lodash");
13
- const astUtils = require("../ast-utils");
13
+ const astUtils = require("../util/ast-utils");
14
14
 
15
15
  //------------------------------------------------------------------------------
16
16
  // Helpers
@@ -4,7 +4,7 @@
4
4
  */
5
5
  "use strict";
6
6
 
7
- const astUtils = require("../ast-utils");
7
+ const astUtils = require("../util/ast-utils");
8
8
 
9
9
  //------------------------------------------------------------------------------
10
10
  // Rule Definition
@@ -5,7 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const astUtils = require("../ast-utils");
8
+ const astUtils = require("../util/ast-utils");
9
9
 
10
10
  //------------------------------------------------------------------------------
11
11
  // Rule Definition
@@ -12,7 +12,7 @@
12
12
 
13
13
  const lodash = require("lodash");
14
14
 
15
- const astUtils = require("../ast-utils");
15
+ const astUtils = require("../util/ast-utils");
16
16
 
17
17
  //------------------------------------------------------------------------------
18
18
  // Rule Definition
@@ -4,7 +4,7 @@
4
4
  */
5
5
  "use strict";
6
6
 
7
- const astUtils = require("../ast-utils");
7
+ const astUtils = require("../util/ast-utils");
8
8
 
9
9
  //------------------------------------------------------------------------------
10
10
  // Rule Definition
@@ -10,7 +10,7 @@
10
10
 
11
11
  const lodash = require("lodash");
12
12
 
13
- const astUtils = require("../ast-utils");
13
+ const astUtils = require("../util/ast-utils");
14
14
 
15
15
  //------------------------------------------------------------------------------
16
16
  // Helpers
@@ -8,7 +8,7 @@
8
8
  // Requirements
9
9
  //------------------------------------------------------------------------------
10
10
 
11
- const astUtils = require("../ast-utils");
11
+ const astUtils = require("../util/ast-utils");
12
12
 
13
13
  //------------------------------------------------------------------------------
14
14
  // Rule Definition