Repository: eslint/eslint
Pull request #8503 (2017-04-25 03:17:02)

Add license report and scan status
Followup to @kborchers's email on JSF adopting FOSSA for license scanning. We're currently merging in PRs for scan status into repo READMEs (i.e. webpack/webpack#4768)

Congrats on the passing license scan! In the PR is a green badge and report.

mention-bot: @xizhao, thanks for your PR! By analyzing the history of the files in this pull request, we identified @nzakas, @alberto and @platinumazure to be potential reviewers.
jsf-clabot: [![CLA assistant check](https://cla.js.foundation/pull/badge/not_signed)](https://cla.js.foundation/eslint/eslint?pullRequest=8503) <br/>Thank you for your submission, we really appreciate it. Like many open source projects, we ask that you sign our [Contributor License Agreement](https://cla.js.foundation/eslint/eslint?pullRequest=8503) before we can accept your contribution.<br/>
eslintbot: Thanks for the pull request, @xizhao! I took a look to make sure it's ready for merging and found some changes are needed:


* The commit summary needs to begin with a tag (such as `Fix:` or `Update:`). Please check out our [guide](http://eslint.org/docs/developer-guide/contributing/pull-requests#step-2-make-your-changes) for how to properly format your commit summary and [update](http://eslint.org/docs/developer-guide/contributing/pull-requests#updating-the-commit-message) it on this pull request.


Can you please update the pull request to address these?

(More information can be found in our [pull request guide](http://eslint.org/docs/developer-guide/contributing/pull-requests).)

Patch:
diff --git a/README.md b/README.md
index 4dcec44e1..59f5255cf 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,7 @@
 [![Downloads][downloads-image]][downloads-url]
 [![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=282608)](https://www.bountysource.com/trackers/282608-eslint?utm_source=282608&utm_medium=shield&utm_campaign=TRACKER_BADGE)
 [![Join the chat at https://gitter.im/eslint/eslint](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/eslint/eslint?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Feslint%2Feslint.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Feslint%2Feslint?ref=badge_shield)
 
 # ESLint
 
@@ -172,6 +173,10 @@ ESLint follows [semantic versioning](http://semver.org). However, due to the nat
 
 According to our policy, any minor update may report more errors than the previous release (ex: from a bug fix). As such, we recommend using the tilde (`~`) in `package.json` e.g. `"eslint": "~3.1.0"` to guarantee the results of your builds.
 
+## License
+
+[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Feslint%2Feslint.svg?type=large)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Feslint%2Feslint?ref=badge_large)
+
 ## Frequently Asked Questions
 
 ### How is ESLint different from JSHint?
diff --git a/conf/cli-options.js b/conf/default-cli-options.js
similarity index 92%
rename from conf/cli-options.js
rename to conf/default-cli-options.js
index 291007515..6dfdb5442 100644
--- a/conf/cli-options.js
+++ b/conf/default-cli-options.js
@@ -12,11 +12,9 @@ module.exports = {
     useEslintrc: true,
     envs: [],
     globals: [],
-    rules: {},
     extensions: [".js"],
     ignore: true,
     ignorePath: null,
-    parser: "", // must be empty
     cache: false,
 
     // in order to honor the cacheFile option if specified
diff --git a/conf/default-config-options.js b/conf/default-config-options.js
new file mode 100644
index 000000000..63d28c48b
--- /dev/null
+++ b/conf/default-config-options.js
@@ -0,0 +1,33 @@
+/**
+ * @fileoverview Default config options
+ * @author Teddy Katz
+ */
+
+"use strict";
+
+/**
+ * Freezes an object and all its nested properties
+ * @param {Object} obj The object to deeply freeze
+ * @returns {Object} `obj` after freezing it
+ */
+function deepFreeze(obj) {
+    if (obj === null || typeof obj !== "object") {
+        return obj;
+    }
+
+    Object.keys(obj).map(key => obj[key]).forEach(deepFreeze);
+    return Object.freeze(obj);
+}
+
+module.exports = deepFreeze({
+    env: {},
+    globals: {},
+    rules: {},
+    settings: {},
+    parser: "espree",
+    parserOptions: {
+        ecmaVersion: 5,
+        sourceType: "script",
+        ecmaFeatures: {}
+    }
+});
diff --git a/conf/eslint-recommended.js b/conf/eslint-recommended.js
index 79340ce7d..29cc3de29 100755
--- a/conf/eslint-recommended.js
+++ b/conf/eslint-recommended.js
@@ -10,8 +10,6 @@
 /* eslint-disable sort-keys */
 
 module.exports = {
-    parser: "espree",
-
     rules: {
 
         /* eslint-enable sort-keys */
diff --git a/lib/cli-engine.js b/lib/cli-engine.js
index 6dd85a394..a1378502a 100644
--- a/lib/cli-engine.js
+++ b/lib/cli-engine.js
@@ -19,7 +19,7 @@ const fs = require("fs"),
     path = require("path"),
     rules = require("./rules"),
     eslint = require("./eslint"),
-    defaultOptions = require("../conf/cli-options"),
+    defaultOptions = require("../conf/default-cli-options"),
     IgnoredPaths = require("./ignored-paths"),
     Config = require("./config"),
     Plugins = require("./config/plugins"),
diff --git a/lib/config/config-file.js b/lib/config/config-file.js
index 4965851cf..1cabbbab1 100644
--- a/lib/config/config-file.js
+++ b/lib/config/config-file.js
@@ -23,7 +23,6 @@ const fs = require("fs"),
     stripBom = require("strip-bom"),
     stripComments = require("strip-json-comments"),
     stringify = require("json-stable-stringify"),
-    defaultOptions = require("../../conf/eslint-recommended"),
     requireUncached = require("require-uncached");
 
 const debug = require("debug")("eslint:config-file");
@@ -541,11 +540,6 @@ function load(filePath, applyEnvironments, relativeTo) {
             Plugins.loadAll(config.plugins);
         }
 
-        // remove parser from config if it is the default parser
-        if (config.parser === defaultOptions.parser) {
-            config.parser = null;
-        }
-
         // include full path of parser if present
         if (config.parser) {
             if (isFilePath(config.parser)) {
diff --git a/lib/eslint.js b/lib/eslint.js
index 7671b7ccc..ee5d3d2c1 100755
--- a/lib/eslint.js
+++ b/lib/eslint.js
@@ -14,7 +14,7 @@ const assert = require("assert"),
     eslintScope = require("eslint-scope"),
     levn = require("levn"),
     blankScriptAST = require("../conf/blank-script.json"),
-    DEFAULT_PARSER = require("../conf/eslint-recommended").parser,
+    defaultConfig = require("../conf/default-config-options.js"),
     replacements = require("../conf/replacements.json"),
     CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"),
     ConfigOps = require("./config/config-ops"),
@@ -453,8 +453,8 @@ function prepareConfig(config) {
     config.globals = config.globals || config.global || {};
     delete config.global;
 
-    const copiedRules = {};
-    let parserOptions = {};
+    const copiedRules = Object.assign({}, defaultConfig.rules);
+    let parserOptions = Object.assign({}, defaultConfig.parserOptions);
 
     if (typeof config.rules === "object") {
         Object.keys(config.rules).forEach(k => {
@@ -484,21 +484,18 @@ function prepareConfig(config) {
 
     const preparedConfig = {
         rules: copiedRules,
-        parser: config.parser || DEFAULT_PARSER,
-        globals: ConfigOps.merge({}, config.globals),
-        env: ConfigOps.merge({}, config.env || {}),
-        settings: ConfigOps.merge({}, config.settings || {}),
+        parser: config.parser || defaultConfig.parser,
+        globals: ConfigOps.merge(defaultConfig.globals, config.globals),
+        env: ConfigOps.merge(defaultConfig.env, config.env || {}),
+        settings: ConfigOps.merge(defaultConfig.settings, config.settings || {}),
         parserOptions: ConfigOps.merge(parserOptions, config.parserOptions || {})
     };
     const isModule = preparedConfig.parserOptions.sourceType === "module";
 
     if (isModule) {
-        if (!preparedConfig.parserOptions.ecmaFeatures) {
-            preparedConfig.parserOptions.ecmaFeatures = {};
-        }
 
         // can't have global return inside of modules
-        preparedConfig.parserOptions.ecmaFeatures.globalReturn = false;
+        preparedConfig.parserOptions.ecmaFeatures = Object.assign({}, preparedConfig.parserOptions.ecmaFeatures, { globalReturn: false });
     }
 
     preparedConfig.parserOptions.ecmaVersion = normalizeEcmaVersion(preparedConfig.parserOptions.ecmaVersion, isModule);
@@ -880,8 +877,8 @@ module.exports = (function() {
             currentConfig = config;
             traverser = new Traverser();
 
-            const ecmaFeatures = currentConfig.parserOptions.ecmaFeatures || {};
-            const ecmaVersion = currentConfig.parserOptions.ecmaVersion || 5;
+            const ecmaFeatures = currentConfig.parserOptions.ecmaFeatures;
+            const ecmaVersion = currentConfig.parserOptions.ecmaVersion;
 
             // gather scope data that may be needed by the rules
             scopeManager = eslintScope.analyze(ast, {
@@ -889,7 +886,7 @@ module.exports = (function() {
                 nodejsScope: ecmaFeatures.globalReturn,
                 impliedStrict: ecmaFeatures.impliedStrict,
                 ecmaVersion,
-                sourceType: currentConfig.parserOptions.sourceType || "script",
+                sourceType: currentConfig.parserOptions.sourceType,
                 fallback: Traverser.getKeys
             });
 
@@ -1183,7 +1180,7 @@ module.exports = (function() {
      * @returns {Object} Object mapping rule IDs to their default configurations
      */
     api.defaults = function() {
-        return require("../conf/eslint-recommended");
+        return defaultConfig;
     };
 
     /**
diff --git a/lib/util/source-code-util.js b/lib/util/source-code-util.js
index 892c32d22..a16a0d977 100644
--- a/lib/util/source-code-util.js
+++ b/lib/util/source-code-util.js
@@ -12,7 +12,7 @@
 const CLIEngine = require("../cli-engine"),
     eslint = require("../eslint"),
     globUtil = require("./glob-util"),
-    baseDefaultOptions = require("../../conf/cli-options");
+    baseDefaultOptions = require("../../conf/default-cli-options");
 
 const debug = require("debug")("eslint:source-code-util");
 


Test patch:
diff --git a/tests/fixtures/config-file/js/.eslintrc.parser3.js b/tests/fixtures/config-file/js/.eslintrc.parser3.js
index 66463377b..fd5f04ff1 100644
--- a/tests/fixtures/config-file/js/.eslintrc.parser3.js
+++ b/tests/fixtures/config-file/js/.eslintrc.parser3.js
@@ -1,4 +1,4 @@
-var defaultOptions = require("../../../../conf/eslint-recommended");
+var defaultOptions = require("../../../../conf/default-config-options");
 
 module.exports = {
     parser: defaultOptions.parser,
diff --git a/tests/lib/config/autoconfig.js b/tests/lib/config/autoconfig.js
index 7f354f155..5cd193122 100644
--- a/tests/lib/config/autoconfig.js
+++ b/tests/lib/config/autoconfig.js
@@ -12,7 +12,7 @@
 const assert = require("chai").assert,
     autoconfig = require("../../../lib/config/autoconfig"),
     sourceCodeUtil = require("../../../lib/util/source-code-util"),
-    baseDefaultOptions = require("../../../conf/cli-options");
+    baseDefaultOptions = require("../../../conf/default-cli-options");
 
 const defaultOptions = Object.assign({}, baseDefaultOptions, { cwd: process.cwd() });
 
diff --git a/tests/lib/config/config-file.js b/tests/lib/config/config-file.js
index a8a3bfd79..405133a0f 100644
--- a/tests/lib/config/config-file.js
+++ b/tests/lib/config/config-file.js
@@ -492,11 +492,11 @@ describe("ConfigFile", () => {
             });
         });
 
-        it("should not interpret parser module name or path when parser is set to default parser in a JavaScript file", () => {
+        it("should interpret parser module name or path when parser is set to default parser in a JavaScript file", () => {
             const config = ConfigFile.load(getFixturePath("js/.eslintrc.parser3.js"));
 
             assert.deepEqual(config, {
-                parser: null,
+                parser: require.resolve("espree"),
                 parserOptions: {},
                 env: {},
                 globals: {},