eslint 4.2.0 → 4.5.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 (47) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/bin/eslint.js +5 -4
  3. package/conf/category-list.json +2 -2
  4. package/conf/config-schema.js +3 -1
  5. package/conf/eslint-recommended.js +11 -14
  6. package/lib/config/config-file.js +5 -5
  7. package/lib/config/config-initializer.js +123 -14
  8. package/lib/config/config-validator.js +25 -1
  9. package/lib/config/plugins.js +13 -1
  10. package/lib/formatters/junit.js +2 -8
  11. package/lib/formatters/stylish.js +2 -1
  12. package/lib/linter.js +21 -13
  13. package/lib/rule-context.js +53 -41
  14. package/lib/rules/arrow-parens.js +1 -1
  15. package/lib/rules/curly.js +1 -1
  16. package/lib/rules/getter-return.js +34 -9
  17. package/lib/rules/id-blacklist.js +7 -3
  18. package/lib/rules/id-match.js +8 -4
  19. package/lib/rules/indent-legacy.js +2 -2
  20. package/lib/rules/indent.js +451 -380
  21. package/lib/rules/key-spacing.js +2 -2
  22. package/lib/rules/no-cond-assign.js +7 -3
  23. package/lib/rules/no-constant-condition.js +62 -6
  24. package/lib/rules/no-else-return.js +1 -1
  25. package/lib/rules/no-extra-parens.js +3 -1
  26. package/lib/rules/no-inner-declarations.js +8 -4
  27. package/lib/rules/no-multi-spaces.js +53 -115
  28. package/lib/rules/no-regex-spaces.js +2 -2
  29. package/lib/rules/no-restricted-globals.js +50 -9
  30. package/lib/rules/no-restricted-properties.js +19 -11
  31. package/lib/rules/no-tabs.js +8 -4
  32. package/lib/rules/no-underscore-dangle.js +28 -1
  33. package/lib/rules/object-curly-newline.js +18 -0
  34. package/lib/rules/object-curly-spacing.js +1 -1
  35. package/lib/rules/padded-blocks.js +2 -2
  36. package/lib/rules/padding-line-between-statements.js +1 -1
  37. package/lib/rules/prefer-destructuring.js +70 -32
  38. package/lib/rules/prefer-numeric-literals.js +36 -7
  39. package/lib/rules/prefer-reflect.js +8 -4
  40. package/lib/rules/prefer-template.js +2 -2
  41. package/lib/rules/space-infix-ops.js +1 -1
  42. package/lib/rules/spaced-comment.js +2 -2
  43. package/lib/rules/valid-jsdoc.js +15 -7
  44. package/lib/testers/rule-tester.js +13 -21
  45. package/lib/testers/test-parser.js +48 -0
  46. package/lib/util/npm-util.js +9 -8
  47. package/package.json +11 -6
@@ -174,7 +174,7 @@ module.exports = {
174
174
  options.arraysInObjectsException && astUtils.isClosingBracketToken(penultimate) ||
175
175
  options.objectsInObjectsException && astUtils.isClosingBraceToken(penultimate)
176
176
  );
177
- const penultimateType = shouldCheckPenultimate && sourceCode.getNodeByRangeIndex(penultimate.start).type;
177
+ const penultimateType = shouldCheckPenultimate && sourceCode.getNodeByRangeIndex(penultimate.range[0]).type;
178
178
 
179
179
  const closingCurlyBraceMustBeSpaced = (
180
180
  options.arraysInObjectsException && penultimateType === "ArrayExpression" ||
@@ -202,7 +202,7 @@ module.exports = {
202
202
  node,
203
203
  loc: { line: tokenBeforeFirst.loc.start.line, column: tokenBeforeFirst.loc.start.column },
204
204
  fix(fixer) {
205
- return fixer.replaceTextRange([tokenBeforeFirst.end, firstBlockToken.start - firstBlockToken.loc.start.column], "\n");
205
+ return fixer.replaceTextRange([tokenBeforeFirst.range[1], firstBlockToken.range[0] - firstBlockToken.loc.start.column], "\n");
206
206
  },
207
207
  message: NEVER_MESSAGE
208
208
  });
@@ -215,7 +215,7 @@ module.exports = {
215
215
  loc: { line: tokenAfterLast.loc.end.line, column: tokenAfterLast.loc.end.column - 1 },
216
216
  message: NEVER_MESSAGE,
217
217
  fix(fixer) {
218
- return fixer.replaceTextRange([lastBlockToken.end, tokenAfterLast.start - tokenAfterLast.loc.start.column], "\n");
218
+ return fixer.replaceTextRange([lastBlockToken.range[1], tokenAfterLast.range[0] - tokenAfterLast.loc.start.column], "\n");
219
219
  }
220
220
  });
221
221
  }
@@ -93,7 +93,7 @@ function isBlockLikeStatement(sourceCode, node) {
93
93
 
94
94
  // Checks the last token is a closing brace of blocks.
95
95
  const lastToken = sourceCode.getLastToken(node, astUtils.isNotSemicolonToken);
96
- const belongingNode = astUtils.isClosingBraceToken(lastToken)
96
+ const belongingNode = lastToken && astUtils.isClosingBraceToken(lastToken)
97
97
  ? sourceCode.getNodeByRangeIndex(lastToken.range[0])
98
98
  : null;
99
99
 
@@ -15,19 +15,55 @@ module.exports = {
15
15
  category: "ECMAScript 6",
16
16
  recommended: false
17
17
  },
18
-
19
18
  schema: [
20
19
  {
21
- type: "object",
22
- properties: {
23
- array: {
24
- type: "boolean"
20
+
21
+ // old support {array: Boolean, object: Boolean}
22
+ // new support {VariableDeclarator: {}, AssignmentExpression: {}}
23
+ oneOf: [
24
+ {
25
+ type: "object",
26
+ properties: {
27
+ VariableDeclarator: {
28
+ type: "object",
29
+ properties: {
30
+ array: {
31
+ type: "boolean"
32
+ },
33
+ object: {
34
+ type: "boolean"
35
+ }
36
+ },
37
+ additionalProperties: false
38
+ },
39
+ AssignmentExpression: {
40
+ type: "object",
41
+ properties: {
42
+ array: {
43
+ type: "boolean"
44
+ },
45
+ object: {
46
+ type: "boolean"
47
+ }
48
+ },
49
+ additionalProperties: false
50
+ }
51
+ },
52
+ additionalProperties: false
25
53
  },
26
- object: {
27
- type: "boolean"
54
+ {
55
+ type: "object",
56
+ properties: {
57
+ array: {
58
+ type: "boolean"
59
+ },
60
+ object: {
61
+ type: "boolean"
62
+ }
63
+ },
64
+ additionalProperties: false
28
65
  }
29
- },
30
- additionalProperties: false
66
+ ]
31
67
  },
32
68
  {
33
69
  type: "object",
@@ -42,26 +78,17 @@ module.exports = {
42
78
  },
43
79
  create(context) {
44
80
 
45
- let checkArrays = true;
46
- let checkObjects = true;
47
- let enforceForRenamedProperties = false;
48
81
  const enabledTypes = context.options[0];
49
- const additionalOptions = context.options[1];
82
+ const enforceForRenamedProperties = context.options[1] && context.options[1].enforceForRenamedProperties;
83
+ let normalizedOptions = {
84
+ VariableDeclarator: { array: true, object: true },
85
+ AssignmentExpression: { array: true, object: true }
86
+ };
50
87
 
51
88
  if (enabledTypes) {
52
- if (typeof enabledTypes.array !== "undefined") {
53
- checkArrays = enabledTypes.array;
54
- }
55
-
56
- if (typeof enabledTypes.object !== "undefined") {
57
- checkObjects = enabledTypes.object;
58
- }
59
- }
60
-
61
- if (additionalOptions) {
62
- if (typeof additionalOptions.enforceForRenamedProperties !== "undefined") {
63
- enforceForRenamedProperties = additionalOptions.enforceForRenamedProperties;
64
- }
89
+ normalizedOptions = typeof enabledTypes.array !== "undefined" || typeof enabledTypes.object !== "undefined"
90
+ ? { VariableDeclarator: enabledTypes, AssignmentExpression: enabledTypes }
91
+ : enabledTypes;
65
92
  }
66
93
 
67
94
  //--------------------------------------------------------------------------
@@ -69,7 +96,18 @@ module.exports = {
69
96
  //--------------------------------------------------------------------------
70
97
 
71
98
  /**
72
- * Determines if the given node node is accessing an array index
99
+ * @param {string} nodeType "AssignmentExpression" or "VariableDeclarator"
100
+ * @param {string} destructuringType "array" or "object"
101
+ * @returns {boolean} `true` if the destructuring type should be checked for the given node
102
+ */
103
+ function shouldCheck(nodeType, destructuringType) {
104
+ return normalizedOptions &&
105
+ normalizedOptions[nodeType] &&
106
+ normalizedOptions[nodeType][destructuringType];
107
+ }
108
+
109
+ /**
110
+ * Determines if the given node is accessing an array index
73
111
  *
74
112
  * This is used to differentiate array index access from object property
75
113
  * access.
@@ -110,22 +148,22 @@ module.exports = {
110
148
  }
111
149
 
112
150
  if (isArrayIndexAccess(rightNode)) {
113
- if (checkArrays) {
151
+ if (shouldCheck(reportNode.type, "array")) {
114
152
  report(reportNode, "array");
115
153
  }
116
154
  return;
117
155
  }
118
156
 
119
- if (checkObjects && enforceForRenamedProperties) {
157
+ if (shouldCheck(reportNode.type, "object") && enforceForRenamedProperties) {
120
158
  report(reportNode, "object");
121
159
  return;
122
160
  }
123
161
 
124
- if (checkObjects) {
162
+ if (shouldCheck(reportNode.type, "object")) {
125
163
  const property = rightNode.property;
126
164
 
127
- if ((property.type === "Literal" && leftNode.name === property.value) ||
128
- (property.type === "Identifier" && leftNode.name === property.name)) {
165
+ if ((property.type === "Literal" && leftNode.name === property.value) || (property.type === "Identifier" &&
166
+ leftNode.name === property.name)) {
129
167
  report(reportNode, "object");
130
168
  }
131
169
  }
@@ -5,6 +5,33 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ //------------------------------------------------------------------------------
9
+ // Helpers
10
+ //------------------------------------------------------------------------------
11
+
12
+ /**
13
+ * Checks to see if a CallExpression's callee node is `parseInt` or
14
+ * `Number.parseInt`.
15
+ * @param {ASTNode} calleeNode The callee node to evaluate.
16
+ * @returns {boolean} True if the callee is `parseInt` or `Number.parseInt`,
17
+ * false otherwise.
18
+ */
19
+ function isParseInt(calleeNode) {
20
+ switch (calleeNode.type) {
21
+ case "Identifier":
22
+ return calleeNode.name === "parseInt";
23
+ case "MemberExpression":
24
+ return calleeNode.object.type === "Identifier" &&
25
+ calleeNode.object.name === "Number" &&
26
+ calleeNode.property.type === "Identifier" &&
27
+ calleeNode.property.name === "parseInt";
28
+
29
+ // no default
30
+ }
31
+
32
+ return false;
33
+ }
34
+
8
35
  //------------------------------------------------------------------------------
9
36
  // Rule Definition
10
37
  //------------------------------------------------------------------------------
@@ -12,7 +39,7 @@
12
39
  module.exports = {
13
40
  meta: {
14
41
  docs: {
15
- description: "disallow `parseInt()` in favor of binary, octal, and hexadecimal literals",
42
+ description: "disallow `parseInt()` and `Number.parseInt()` in favor of binary, octal, and hexadecimal literals",
16
43
  category: "ECMAScript 6",
17
44
  recommended: false
18
45
  },
@@ -23,6 +50,8 @@ module.exports = {
23
50
  },
24
51
 
25
52
  create(context) {
53
+ const sourceCode = context.getSourceCode();
54
+
26
55
  const radixMap = {
27
56
  2: "binary",
28
57
  8: "octal",
@@ -35,9 +64,9 @@ module.exports = {
35
64
  16: "0x"
36
65
  };
37
66
 
38
- //--------------------------------------------------------------------------
67
+ //----------------------------------------------------------------------
39
68
  // Public
40
- //--------------------------------------------------------------------------
69
+ //----------------------------------------------------------------------
41
70
 
42
71
  return {
43
72
 
@@ -51,16 +80,16 @@ module.exports = {
51
80
  // only error if the radix is 2, 8, or 16
52
81
  const radixName = radixMap[node.arguments[1].value];
53
82
 
54
- if (node.callee.type === "Identifier" &&
55
- node.callee.name === "parseInt" &&
83
+ if (isParseInt(node.callee) &&
56
84
  radixName &&
57
85
  node.arguments[0].type === "Literal"
58
86
  ) {
59
87
  context.report({
60
88
  node,
61
- message: "Use {{radixName}} literals instead of parseInt().",
89
+ message: "Use {{radixName}} literals instead of {{functionName}}().",
62
90
  data: {
63
- radixName
91
+ radixName,
92
+ functionName: sourceCode.getText(node.callee)
64
93
  },
65
94
  fix(fixer) {
66
95
  const newPrefix = prefixMap[node.arguments[1].value];
@@ -83,10 +83,14 @@ module.exports = {
83
83
  * @returns {void}
84
84
  */
85
85
  function report(node, existing, substitute) {
86
- context.report({ node, message: "Avoid using {{existing}}, instead use {{substitute}}.", data: {
87
- existing,
88
- substitute
89
- } });
86
+ context.report({
87
+ node,
88
+ message: "Avoid using {{existing}}, instead use {{substitute}}.",
89
+ data: {
90
+ existing,
91
+ substitute
92
+ }
93
+ });
90
94
  }
91
95
 
92
96
  return {
@@ -74,7 +74,7 @@ function startsWithTemplateCurly(node) {
74
74
  return startsWithTemplateCurly(node.left);
75
75
  }
76
76
  if (node.type === "TemplateLiteral") {
77
- return node.expressions.length && node.quasis.length && node.quasis[0].start === node.quasis[0].end;
77
+ return node.expressions.length && node.quasis.length && node.quasis[0].range[0] === node.quasis[0].range[1];
78
78
  }
79
79
  return node.type !== "Literal" || typeof node.value !== "string";
80
80
  }
@@ -89,7 +89,7 @@ function endsWithTemplateCurly(node) {
89
89
  return startsWithTemplateCurly(node.right);
90
90
  }
91
91
  if (node.type === "TemplateLiteral") {
92
- return node.expressions.length && node.quasis.length && node.quasis[node.quasis.length - 1].start === node.quasis[node.quasis.length - 1].end;
92
+ return node.expressions.length && node.quasis.length && node.quasis[node.quasis.length - 1].range[0] === node.quasis[node.quasis.length - 1].range[1];
93
93
  }
94
94
  return node.type !== "Literal" || typeof node.value !== "string";
95
95
  }
@@ -112,7 +112,7 @@ module.exports = {
112
112
  const nonSpacedNode = getFirstNonSpacedToken(leftNode, rightNode);
113
113
 
114
114
  if (nonSpacedNode) {
115
- if (!(int32Hint && sourceCode.getText(node).substr(-2) === "|0")) {
115
+ if (!(int32Hint && sourceCode.getText(node).endsWith("|0"))) {
116
116
  report(node, nonSpacedNode);
117
117
  }
118
118
  }
@@ -303,9 +303,9 @@ module.exports = {
303
303
  node,
304
304
  fix(fixer) {
305
305
  if (requireSpace) {
306
- return fixer.insertTextAfterRange([node.start, node.end - 2], " ");
306
+ return fixer.insertTextAfterRange([node.range[0], node.range[1] - 2], " ");
307
307
  }
308
- const end = node.end - 2,
308
+ const end = node.range[1] - 2,
309
309
  start = end - match[0].length;
310
310
 
311
311
  return fixer.replaceTextRange([start, end], "");
@@ -362,14 +362,22 @@ module.exports = {
362
362
  // TODO(nzakas): Figure out logical things to do with destructured, default, rest params
363
363
  if (param.type === "Identifier") {
364
364
  if (jsdocParams[i] && (name !== jsdocParams[i])) {
365
- context.report({ node: jsdocNode, message: "Expected JSDoc for '{{name}}' but found '{{jsdocName}}'.", data: {
366
- name,
367
- jsdocName: jsdocParams[i]
368
- } });
365
+ context.report({
366
+ node: jsdocNode,
367
+ message: "Expected JSDoc for '{{name}}' but found '{{jsdocName}}'.",
368
+ data: {
369
+ name,
370
+ jsdocName: jsdocParams[i]
371
+ }
372
+ });
369
373
  } else if (!params[name] && !isOverride) {
370
- context.report({ node: jsdocNode, message: "Missing JSDoc for parameter '{{name}}'.", data: {
371
- name
372
- } });
374
+ context.report({
375
+ node: jsdocNode,
376
+ message: "Missing JSDoc for parameter '{{name}}'.",
377
+ data: {
378
+ name
379
+ }
380
+ });
373
381
  }
374
382
  }
375
383
  });
@@ -9,7 +9,7 @@
9
9
  /*
10
10
  * This is a wrapper around mocha to allow for DRY unittests for eslint
11
11
  * Format:
12
- * RuleTester.add("{ruleName}", {
12
+ * RuleTester.run("{ruleName}", {
13
13
  * valid: [
14
14
  * "{code}",
15
15
  * { code: "{code}", options: {options}, globals: {globals}, parser: "{parser}", settings: {settings} }
@@ -250,7 +250,6 @@ class RuleTester {
250
250
  const testerConfig = this.testerConfig,
251
251
  requiredScenarios = ["valid", "invalid"],
252
252
  scenarioErrors = [],
253
- result = {},
254
253
  linter = this.linter;
255
254
 
256
255
  if (lodash.isNil(test) || typeof test !== "object") {
@@ -269,16 +268,13 @@ class RuleTester {
269
268
  ].concat(scenarioErrors).join("\n"));
270
269
  }
271
270
 
272
- /* eslint-disable no-shadow */
273
-
274
271
  /**
275
272
  * Run the rule for the given item
276
- * @param {string} ruleName name of the rule
277
273
  * @param {string|Object} item Item to run the rule against
278
274
  * @returns {Object} Eslint run result
279
275
  * @private
280
276
  */
281
- function runRuleForItem(ruleName, item) {
277
+ function runRuleForItem(item) {
282
278
  let config = lodash.cloneDeep(testerConfig),
283
279
  code, filename, beforeAST, afterAST;
284
280
 
@@ -350,27 +346,27 @@ class RuleTester {
350
346
 
351
347
  try {
352
348
  linter.rules.get = function(ruleId) {
353
- const rule = originalGet.call(linter.rules, ruleId);
349
+ const originalRule = originalGet.call(linter.rules, ruleId);
354
350
 
355
- if (typeof rule === "function") {
351
+ if (typeof originalRule === "function") {
356
352
  return function(context) {
357
353
  Object.freeze(context);
358
354
  freezeDeeply(context.options);
359
355
  freezeDeeply(context.settings);
360
356
  freezeDeeply(context.parserOptions);
361
357
 
362
- return rule(context);
358
+ return originalRule(context);
363
359
  };
364
360
  }
365
361
  return {
366
- meta: rule.meta,
362
+ meta: originalRule.meta,
367
363
  create(context) {
368
364
  Object.freeze(context);
369
365
  freezeDeeply(context.options);
370
366
  freezeDeeply(context.settings);
371
367
  freezeDeeply(context.parserOptions);
372
368
 
373
- return rule.create(context);
369
+ return originalRule.create(context);
374
370
  }
375
371
  };
376
372
 
@@ -404,13 +400,12 @@ class RuleTester {
404
400
  /**
405
401
  * Check if the template is valid or not
406
402
  * all valid cases go through this
407
- * @param {string} ruleName name of the rule
408
403
  * @param {string|Object} item Item to run the rule against
409
404
  * @returns {void}
410
405
  * @private
411
406
  */
412
- function testValidTemplate(ruleName, item) {
413
- const result = runRuleForItem(ruleName, item);
407
+ function testValidTemplate(item) {
408
+ const result = runRuleForItem(item);
414
409
  const messages = result.messages;
415
410
 
416
411
  assert.equal(messages.length, 0, util.format("Should have no errors but had %d: %s",
@@ -444,16 +439,15 @@ class RuleTester {
444
439
  /**
445
440
  * Check if the template is invalid or not
446
441
  * all invalid cases go through this.
447
- * @param {string} ruleName name of the rule
448
442
  * @param {string|Object} item Item to run the rule against
449
443
  * @returns {void}
450
444
  * @private
451
445
  */
452
- function testInvalidTemplate(ruleName, item) {
446
+ function testInvalidTemplate(item) {
453
447
  assert.ok(item.errors || item.errors === 0,
454
448
  `Did not specify errors for an invalid test of ${ruleName}`);
455
449
 
456
- const result = runRuleForItem(ruleName, item);
450
+ const result = runRuleForItem(item);
457
451
  const messages = result.messages;
458
452
 
459
453
 
@@ -543,7 +537,7 @@ class RuleTester {
543
537
  test.valid.forEach(valid => {
544
538
  RuleTester.it(typeof valid === "object" ? valid.code : valid, () => {
545
539
  linter.defineRules(this.rules);
546
- testValidTemplate(ruleName, valid);
540
+ testValidTemplate(valid);
547
541
  });
548
542
  });
549
543
  });
@@ -552,13 +546,11 @@ class RuleTester {
552
546
  test.invalid.forEach(invalid => {
553
547
  RuleTester.it(invalid.code, () => {
554
548
  linter.defineRules(this.rules);
555
- testInvalidTemplate(ruleName, invalid);
549
+ testInvalidTemplate(invalid);
556
550
  });
557
551
  });
558
552
  });
559
553
  });
560
-
561
- return result.suite;
562
554
  }
563
555
  }
564
556
 
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @author Toru Nagashima <https://github.com/mysticatea>
3
+ */
4
+ "use strict";
5
+
6
+ const espree = require("espree");
7
+ const Traverser = require("../util/traverser");
8
+
9
+ /**
10
+ * Define `start`/`end` properties as throwing error.
11
+ * @param {ASTNode} node The node to define.
12
+ * @returns {void}
13
+ */
14
+ function defineStartEndAsError(node) {
15
+ Object.defineProperty(node, "start", {
16
+ get() {
17
+ throw new Error("Use node.range[0] instead of node.start");
18
+ },
19
+ configurable: true,
20
+ enumerable: false
21
+ });
22
+ Object.defineProperty(node, "end", {
23
+ get() {
24
+ throw new Error("Use node.range[1] instead of node.end");
25
+ },
26
+ configurable: true,
27
+ enumerable: false
28
+ });
29
+ }
30
+
31
+ /**
32
+ * Define `start`/`end` properties of all nodes of the given AST as throwing error.
33
+ * @param {ASTNode} ast The root node to errorize `start`/`end` properties.
34
+ * @returns {void}
35
+ */
36
+ function defineStartEndAsErrorInTree(ast) {
37
+ new Traverser().traverse(ast, { enter: defineStartEndAsError });
38
+ ast.tokens.forEach(defineStartEndAsError);
39
+ ast.comments.forEach(defineStartEndAsError);
40
+ }
41
+
42
+ module.exports.parse = (code, options) => {
43
+ const ret = espree.parse(code, options);
44
+
45
+ defineStartEndAsErrorInTree(ret.ast || ret);
46
+
47
+ return ret;
48
+ };
@@ -10,7 +10,7 @@
10
10
  //------------------------------------------------------------------------------
11
11
 
12
12
  const fs = require("fs"),
13
- childProcess = require("child_process"),
13
+ spawn = require("cross-spawn"),
14
14
  path = require("path"),
15
15
  log = require("../logging");
16
16
 
@@ -50,22 +50,23 @@ function findPackageJson(startDir) {
50
50
  * @returns {void}
51
51
  */
52
52
  function installSyncSaveDev(packages) {
53
- if (Array.isArray(packages)) {
54
- packages = packages.join(" ");
53
+ if (!Array.isArray(packages)) {
54
+ packages = [packages];
55
55
  }
56
- childProcess.execSync(`npm i --save-dev ${packages}`, { stdio: "inherit", encoding: "utf8" });
56
+ spawn.sync("npm", ["i", "--save-dev"].concat(packages), { stdio: "inherit" });
57
57
  }
58
58
 
59
59
  /**
60
60
  * Fetch `peerDependencies` of the given package by `npm show` command.
61
61
  * @param {string} packageName The package name to fetch peerDependencies.
62
- * @returns {string[]} Gotten peerDependencies.
62
+ * @returns {Object} Gotten peerDependencies.
63
63
  */
64
64
  function fetchPeerDependencies(packageName) {
65
- const fetchedText = childProcess.execSync(
66
- `npm show --json ${packageName} peerDependencies`,
65
+ const fetchedText = spawn.sync(
66
+ "npm",
67
+ ["show", "--json", packageName, "peerDependencies"],
67
68
  { encoding: "utf8" }
68
- ).trim();
69
+ ).stdout.trim();
69
70
 
70
71
  return JSON.parse(fetchedText || "{}");
71
72
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "4.2.0",
3
+ "version": "4.5.0",
4
4
  "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
5
5
  "description": "An AST-based pattern checker for JavaScript.",
6
6
  "bin": {
@@ -10,6 +10,7 @@
10
10
  "scripts": {
11
11
  "test": "node Makefile.js test",
12
12
  "lint": "node Makefile.js lint",
13
+ "fuzz": "node Makefile.js fuzz",
13
14
  "release": "node Makefile.js release",
14
15
  "ci-release": "node Makefile.js ciRelease",
15
16
  "alpharelease": "node Makefile.js prerelease -- alpha",
@@ -36,23 +37,25 @@
36
37
  "dependencies": {
37
38
  "ajv": "^5.2.0",
38
39
  "babel-code-frame": "^6.22.0",
39
- "chalk": "^1.1.3",
40
+ "chalk": "^2.1.0",
40
41
  "concat-stream": "^1.6.0",
42
+ "cross-spawn": "^5.1.0",
41
43
  "debug": "^2.6.8",
42
44
  "doctrine": "^2.0.0",
43
45
  "eslint-scope": "^3.7.1",
44
- "espree": "^3.4.3",
46
+ "espree": "^3.5.0",
45
47
  "esquery": "^1.0.0",
46
48
  "estraverse": "^4.2.0",
47
49
  "esutils": "^2.0.2",
48
50
  "file-entry-cache": "^2.0.0",
51
+ "functional-red-black-tree": "^1.0.1",
49
52
  "glob": "^7.1.2",
50
53
  "globals": "^9.17.0",
51
54
  "ignore": "^3.3.3",
52
55
  "imurmurhash": "^0.1.4",
53
56
  "inquirer": "^3.0.6",
54
57
  "is-resolvable": "^1.0.0",
55
- "js-yaml": "^3.8.4",
58
+ "js-yaml": "^3.9.1",
56
59
  "json-stable-stringify": "^1.0.1",
57
60
  "levn": "^0.3.0",
58
61
  "lodash": "^4.17.4",
@@ -64,6 +67,8 @@
64
67
  "pluralize": "^4.0.0",
65
68
  "progress": "^2.0.0",
66
69
  "require-uncached": "^1.0.3",
70
+ "semver": "^5.3.0",
71
+ "strip-ansi": "^4.0.0",
67
72
  "strip-json-comments": "~2.0.1",
68
73
  "table": "^4.0.1",
69
74
  "text-table": "~0.2.0"
@@ -80,9 +85,10 @@
80
85
  "coveralls": "^2.13.1",
81
86
  "dateformat": "^2.0.0",
82
87
  "ejs": "^2.5.6",
83
- "eslint-plugin-eslint-plugin": "^0.7.4",
88
+ "eslint-plugin-eslint-plugin": "^0.8.0",
84
89
  "eslint-plugin-node": "^5.1.0",
85
90
  "eslint-release": "^0.10.1",
91
+ "eslump": "1.6.0",
86
92
  "esprima": "^3.1.3",
87
93
  "esprima-fb": "^15001.1001.0-dev-harmony-fb",
88
94
  "istanbul": "^0.4.5",
@@ -100,7 +106,6 @@
100
106
  "npm-license": "^0.3.3",
101
107
  "phantomjs-prebuilt": "^2.1.14",
102
108
  "proxyquire": "^1.8.0",
103
- "semver": "^5.3.0",
104
109
  "shelljs": "^0.7.7",
105
110
  "shelljs-nodecli": "~0.1.1",
106
111
  "sinon": "^2.3.2",