Bug 1264649 - add reject-some-requires eslint rule; r?pbro draft
authorTom Tromey <tom@tromey.com>
Thu, 21 Jul 2016 08:39:29 -0600
changeset 391945 a454dd2511f7be67e25b70f8070023f7963bd248
parent 391383 ff29f08b72c466b65dea5efa6f82f99add8f17ef
child 391946 119fe22bedddb125c25bcfed0d365fd48ae7dfb6
push id23913
push userbmo:ttromey@mozilla.com
push dateFri, 22 Jul 2016 20:16:35 +0000
reviewerspbro
bugs1264649
milestone50.0a1
Bug 1264649 - add reject-some-requires eslint rule; r?pbro MozReview-Commit-ID: FVxy2c5Wsgg
tools/lint/eslint/eslint-plugin-mozilla/docs/index.rst
tools/lint/eslint/eslint-plugin-mozilla/docs/reject-some-requires.rst
tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-some-requires.js
tools/lint/eslint/eslint-plugin-mozilla/package.json
tools/lint/eslint/manifest.tt
tools/lint/eslint/npm-shrinkwrap.json
tools/lint/mach_commands.py
--- a/tools/lint/eslint/eslint-plugin-mozilla/docs/index.rst
+++ b/tools/lint/eslint/eslint-plugin-mozilla/docs/index.rst
@@ -27,16 +27,19 @@ if so, checks for possible CPOW usage.
 
 ``no-single-arg-cu-import`` rejects calls to "Cu.import" that do not supply a
 second argument (meaning they add the exported properties into global scope).
 
 ``reject-importGlobalProperties`` rejects calls to
 "Cu.importGlobalProperties".  Use of this function is undesirable in
 some parts of the tree.
 
+``reject-some-requires`` rejects some calls to ``require``, according
+to a regexp passed in as an option.
+
 ``this-top-level-scope`` treats top-level assignments like
 ``this.mumble = value`` as declaring a global.
 
 Note: These are string matches so we will miss situations where the parent
 object is assigned to another variable e.g.::
 
    var b = gBrowser;
    b.content // Would not be detected as a CPOW.
@@ -74,10 +77,11 @@ Example configuration::
    balanced-listeners
    components-imports
    import-globals-from
    import-headjs-globals
    mark-test-function-used
    no-aArgs
    no-cpows-in-tests
    reject-importGlobalProperties
+   reject-some-requires
    this-top-level-scope
    var-only-at-top-level
new file mode 100644
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/docs/reject-some-requires.rst
@@ -0,0 +1,12 @@
+.. _reject-some-requires:
+
+====================
+reject-some-requires
+====================
+
+Rule Details
+------------
+
+This takes an option, a regular expression.  Invocations of
+``require`` with a string literal argument are matched against this
+regexp; and if it matches, the ``require`` use is flagged.
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
@@ -21,23 +21,25 @@ module.exports = {
     "import-globals": require("../lib/rules/import-globals"),
     "import-headjs-globals": require("../lib/rules/import-headjs-globals"),
     "import-browserjs-globals": require("../lib/rules/import-browserjs-globals"),
     "mark-test-function-used": require("../lib/rules/mark-test-function-used"),
     "no-aArgs": require("../lib/rules/no-aArgs"),
     "no-cpows-in-tests": require("../lib/rules/no-cpows-in-tests"),
     "no-single-arg-cu-import": require("../lib/rules/no-single-arg-cu-import"),
     "reject-importGlobalProperties": require("../lib/rules/reject-importGlobalProperties"),
+    "reject-some-requires": require("../lib/rules/reject-some-requires"),
     "var-only-at-top-level": require("../lib/rules/var-only-at-top-level")
   },
   rulesConfig: {
     "balanced-listeners": 0,
     "import-globals": 0,
     "import-headjs-globals": 0,
     "import-browserjs-globals": 0,
     "mark-test-function-used": 0,
     "no-aArgs": 0,
     "no-cpows-in-tests": 0,
     "no-single-arg-cu-import": 0,
     "reject-importGlobalProperties": 0,
+    "reject-some-requires": 0,
     "var-only-at-top-level": 0
   }
 };
new file mode 100644
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-some-requires.js
@@ -0,0 +1,48 @@
+/**
+ * @fileoverview Reject some uses of require.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+"use strict";
+
+// -----------------------------------------------------------------------------
+// Rule Definition
+// -----------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+  // ---------------------------------------------------------------------------
+  // Public
+  //  --------------------------------------------------------------------------
+
+  if (typeof(context.options[0]) !== "string") {
+    throw new Error("reject-some-requires expects a regexp");
+  }
+  const RX = new RegExp(context.options[0]);
+
+  const checkPath = function(node, path) {
+    if (RX.test(path)) {
+      context.report(node, `require(${path}) is not allowed`);
+    }
+  };
+
+  return {
+    "CallExpression": function(node) {
+      if (node.callee.type == "Identifier" &&
+          node.callee.name == "require" &&
+          node.arguments.length == 1 &&
+          node.arguments[0].type == "Literal") {
+        checkPath(node, node.arguments[0].value);
+      } else if (node.callee.type == "MemberExpression" &&
+                 node.callee.property.type == "Identifier" &&
+                 node.callee.property.name == "lazyRequireGetter" &&
+                 node.arguments.length >= 3 &&
+                 node.arguments[2].type == "Literal") {
+        checkPath(node, node.arguments[2].value);
+      }
+    }
+  };
+};
--- a/tools/lint/eslint/eslint-plugin-mozilla/package.json
+++ b/tools/lint/eslint/eslint-plugin-mozilla/package.json
@@ -1,11 +1,11 @@
 {
   "name": "eslint-plugin-mozilla",
-  "version": "0.1.1",
+  "version": "0.2.0",
   "description": "A collection of rules that help enforce JavaScript coding standard in the Mozilla project.",
   "keywords": [
     "eslint",
     "eslintplugin",
     "eslint-plugin",
     "mozilla",
     "firefox"
   ],
--- a/tools/lint/eslint/manifest.tt
+++ b/tools/lint/eslint/manifest.tt
@@ -1,9 +1,9 @@
 [
 {
-"size": 2348527,
+"size": 2349680,
 "visibility": "public",
-"digest": "2e6c1f35b178e2ee1055c89f020f6b3b88f310a4b63f2fbb2023016c3890f672f86f8e35f716745135740c59fdccd3ad46d48c7995e7d281aa19d74637caa405",
+"digest": "2b02ae6dd4bc735990660f97a831f05e604c28120977e4120cf59619fb02be22cbd42be26ec2bd176f172f4566f3dfb445082e8d9651346662b8fb8fde407b8c",
 "algorithm": "sha512",
 "filename": "eslint.tar.gz"
 }
 ]
--- a/tools/lint/eslint/npm-shrinkwrap.json
+++ b/tools/lint/eslint/npm-shrinkwrap.json
@@ -51,19 +51,19 @@
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz"
     },
     "bluebird": {
       "version": "3.4.1",
       "from": "bluebird@>=3.1.1 <4.0.0",
       "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.1.tgz"
     },
     "brace-expansion": {
-      "version": "1.1.5",
+      "version": "1.1.6",
       "from": "brace-expansion@>=1.0.0 <2.0.0",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz"
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz"
     },
     "caller-path": {
       "version": "0.1.0",
       "from": "caller-path@>=0.1.0 <0.2.0",
       "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz"
     },
     "callsites": {
       "version": "0.2.0",
@@ -215,17 +215,17 @@
       "resolved": "https://registry.npmjs.org/eslint/-/eslint-2.9.0.tgz"
     },
     "eslint-plugin-html": {
       "version": "1.4.0",
       "from": "eslint-plugin-html@1.4.0",
       "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-1.4.0.tgz"
     },
     "eslint-plugin-mozilla": {
-      "version": "0.1.1",
+      "version": "0.2.0",
       "from": "eslint-plugin-mozilla",
       "resolved": "file:eslint-plugin-mozilla",
       "dependencies": {
         "espree": {
           "version": "2.2.5",
           "from": "espree@>=2.2.4 <3.0.0",
           "resolved": "https://registry.npmjs.org/espree/-/espree-2.2.5.tgz"
         }
@@ -274,19 +274,19 @@
       "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.4.tgz"
     },
     "exit-hook": {
       "version": "1.1.1",
       "from": "exit-hook@>=1.0.0 <2.0.0",
       "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz"
     },
     "fast-levenshtein": {
-      "version": "1.1.3",
+      "version": "1.1.4",
       "from": "fast-levenshtein@>=1.1.0 <2.0.0",
-      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.3.tgz"
+      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz"
     },
     "figures": {
       "version": "1.7.0",
       "from": "figures@>=1.3.5 <2.0.0",
       "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz"
     },
     "file-entry-cache": {
       "version": "1.2.4",
@@ -564,19 +564,19 @@
       "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz"
     },
     "restore-cursor": {
       "version": "1.0.1",
       "from": "restore-cursor@>=1.0.1 <2.0.0",
       "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz"
     },
     "rimraf": {
-      "version": "2.5.3",
+      "version": "2.5.4",
       "from": "rimraf@>=2.2.8 <3.0.0",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.3.tgz"
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz"
     },
     "run-async": {
       "version": "0.1.0",
       "from": "run-async@>=0.1.0 <0.2.0",
       "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz"
     },
     "rx-lite": {
       "version": "3.1.2",
--- a/tools/lint/mach_commands.py
+++ b/tools/lint/mach_commands.py
@@ -27,17 +27,17 @@ from mach.decorators import (
 
 
 here = os.path.abspath(os.path.dirname(__file__))
 
 
 ESLINT_PACKAGES = [
     "eslint@2.9.0",
     "eslint-plugin-html@1.4.0",
-    "eslint-plugin-mozilla@0.1.1",
+    "eslint-plugin-mozilla@0.2.0",
     "eslint-plugin-react@4.2.3"
 ]
 
 ESLINT_NOT_FOUND_MESSAGE = '''
 Could not find eslint!  We looked at the --binary option, at the ESLINT
 environment variable, and then at your local node_modules path. Please Install
 eslint and needed plugins with: