Repository: eslint/eslint (js)

Issue:
extends only supports 7 extends, silently drops rest
<!--
This template is for bug reports. If you are reporting a bug, please continue on. If you are here for another reason, please see below:

1. To propose a new rule: http://eslint.org/docs/developer-guide/contributing/new-rules
2. To request a change: http://eslint.org/docs/developer-guide/contributing/changes
3. If you have any questions, please stop by our chatroom: https://gitter.im/eslint/eslint

Note that leaving sections blank will make it difficult for us to troubleshoot and we may have to close the issue.
-->

**Tell us about your environment**
macOS Sierra

* **ESLint Version:**
3.16.1
* **Node Version:**
6.9.2
* **npm Version:**
yarn@0.21.3

**What parser (default, Babel-ESLint, etc.) are you using?**
default

**Please show your full configuration:**

<!-- Paste your configuration below: -->
```
{
  "root": true,
  "extends": [
    "simenb-base",
    "simenb-node",
    "simenb-jsdoc"
  ]
}
```

**What did you do? Please include the actual source code causing the issue.**
Source code not applicable, but I've created a repo reproducing the error: https://github.com/SimenB/eslint-extends-issue

**What did you expect to happen?**
That all extends, recursively, are resolved.

**What actually happened? Please include the actual, raw output from ESLint.**
"Only" 7 extends are resolved.

This might be by design, but if so, why only 7, and it's not mentioned in the docs http://eslint.org/docs/developer-guide/shareable-configs.

For output from eslint, see https://github.com/SimenB/eslint-extends-issue

Pull request:
Fix: Config merge to correctly account for extends (fixes #8193)
**What is the purpose of this pull request? (put an "X" next to item)**

[ ] Documentation update
[ X ] Bug fix ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/bug-report.md))
[ ] New rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-proposal.md))
[ ] Changes an existing rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-change-proposal.md))
[ ] Add autofixing to a rule
[ ] Add a CLI option
[ ] Add something to the core
[ ] Other, please explain:

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (http://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

**What changes did you make? (Give an overview)**

Config merge never took care of the extends that why it was overriding the array as mentioned in the issue. This has never caught because the rules for all those extended configs got picked up, it just the `extends` array inside `config` never got updated correctly due to merge issues.

**Is there anything you'd like reviewers to focus on?**




Patch:
diff --git a/README.md b/README.md
index cdf5cabd9..7fb4fa343 100644
--- a/README.md
+++ b/README.md
@@ -124,7 +124,7 @@ These folks keep the project moving and are resources for help.
 * Michael Ficarra ([@michaelficarra](https://github.com/michaelficarra))
 * Mark Pedrotti ([@pedrottimark](https://github.com/pedrottimark))
 * Oleg Gaidarenko ([@markelog](https://github.com/markelog))
-* Mike Sherov [@mikesherov](https://github.com/mikesherov))
+* Mike Sherov ([@mikesherov](https://github.com/mikesherov))
 * Henry Zhu ([@hzoo](https://github.com/hzoo))
 * Marat Dulin ([@mdevils](https://github.com/mdevils))
 * Alexej Yaroshevich ([@zxqfox](https://github.com/zxqfox))
diff --git a/docs/developer-guide/contributing/pull-requests.md b/docs/developer-guide/contributing/pull-requests.md
index ff6c864d9..cfb627840 100644
--- a/docs/developer-guide/contributing/pull-requests.md
+++ b/docs/developer-guide/contributing/pull-requests.md
@@ -6,7 +6,7 @@ If you want to contribute to an ESLint repo, please use a GitHub pull request. T
 
 If you'd like to work on a pull request and you've never submitted code before, follow these steps:
 
-1. Sign our [Contributor License Agreement](https://contribute.jquery.org/cla).
+1. Sign our [Contributor License Agreement](https://cla.js.foundation/eslint/eslint).
 1. Set up a [development environment](../development-environment).
 1. If you want to implement a breaking change or a change to the core, ensure there's an issue that describes what you're doing and the issue has been accepted. You can create a new issue or just indicate you're [working on an existing issue](working-on-issues). Bug fixes, documentation changes, and other pull requests do not require an issue.
 
diff --git a/lib/config/config-ops.js b/lib/config/config-ops.js
index 79a2f7f41..e1d9a9013 100644
--- a/lib/config/config-ops.js
+++ b/lib/config/config-ops.js
@@ -175,7 +175,7 @@ module.exports = {
             }
             Object.keys(src).forEach(key => {
                 if (Array.isArray(src[key]) || Array.isArray(target[key])) {
-                    dst[key] = deepmerge(target[key], src[key], key === "plugins", isRule);
+                    dst[key] = deepmerge(target[key], src[key], key === "plugins" || key === "extends", isRule);
                 } else if (typeof src[key] !== "object" || !src[key] || key === "exported" || key === "astGlobals") {
                     dst[key] = src[key];
                 } else {


Test patch:
diff --git a/tests/lib/config/config-ops.js b/tests/lib/config/config-ops.js
index 46ee8c8ea..f0c72c488 100644
--- a/tests/lib/config/config-ops.js
+++ b/tests/lib/config/config-ops.js
@@ -316,6 +316,18 @@ describe("ConfigOps", () => {
             assert.deepEqual(config[1], { rules: { "no-mixed-requires": "error" } });
         });
 
+        it("should combine extends correctly", () => {
+
+            const config = [
+                { extends: ["a", "b", "c", "d", "e"] },
+                { extends: ["f", "g", "h", "i"] }
+            ];
+
+            const result = ConfigOps.merge(config[0], config[1]);
+
+            assert.sameDeepMembers(result.extends, ["a", "b", "c", "d", "e", "f", "g", "h", "i"]);
+        });
+
         it("should combine configs correctly", () => {
 
             const config = [