{"action":"created","comment":{"url":"https://api.github.com/repos/eslint/eslint/pulls/comments/80088456","id":80088456,"diff_hunk":"@@ -48,6 +48,12 @@\n             \".eslintrc\": \"{\\n    \\\"env\\\": {\\n        \\\"commonjs\\\": true\\n    }\\n}\\n\"\n         }\n     },\n+    \"overrides\": {","path":"tests/fixtures/config-hierarchy/file-structure.json","position":4,"original_position":4,"commit_id":"23e2b85da3b5f0951b83f16ee11341b1f52661b1","original_commit_id":"23e2b85da3b5f0951b83f16ee11341b1f52661b1","user":{"login":"nzakas","id":38546,"avatar_url":"https://avatars.githubusercontent.com/u/38546?v=3","gravatar_id":"","url":"https://api.github.com/users/nzakas","html_url":"https://github.com/nzakas","followers_url":"https://api.github.com/users/nzakas/followers","following_url":"https://api.github.com/users/nzakas/following{/other_user}","gists_url":"https://api.github.com/users/nzakas/gists{/gist_id}","starred_url":"https://api.github.com/users/nzakas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nzakas/subscriptions","organizations_url":"https://api.github.com/users/nzakas/orgs","repos_url":"https://api.github.com/users/nzakas/repos","events_url":"https://api.github.com/users/nzakas/events{/privacy}","received_events_url":"https://api.github.com/users/nzakas/received_events","type":"User","site_admin":false},"body":"Just double-checking: are you sure this won't interfere with already-existing tests?","created_at":"2016-09-22T17:06:25Z","updated_at":"2016-09-22T17:11:32Z","html_url":"https://github.com/eslint/eslint/pull/7177#discussion_r80088456","pull_request_url":"https://api.github.com/repos/eslint/eslint/pulls/7177","_links":{"self":{"href":"https://api.github.com/repos/eslint/eslint/pulls/comments/80088456"},"html":{"href":"https://github.com/eslint/eslint/pull/7177#discussion_r80088456"},"pull_request":{"href":"https://api.github.com/repos/eslint/eslint/pulls/7177"}}},"pull_request":{"url":"https://api.github.com/repos/eslint/eslint/pulls/7177","id":85660786,"html_url":"https://github.com/eslint/eslint/pull/7177","diff_url":"https://github.com/eslint/eslint/pull/7177.diff","patch_url":"https://github.com/eslint/eslint/pull/7177.patch","issue_url":"https://api.github.com/repos/eslint/eslint/issues/7177","number":7177,"state":"open","locked":false,"title":"New: Add `overrides` and `files` configuration options (refs #3611)","user":{"login":"CrabDude","id":204037,"avatar_url":"https://avatars.githubusercontent.com/u/204037?v=3","gravatar_id":"","url":"https://api.github.com/users/CrabDude","html_url":"https://github.com/CrabDude","followers_url":"https://api.github.com/users/CrabDude/followers","following_url":"https://api.github.com/users/CrabDude/following{/other_user}","gists_url":"https://api.github.com/users/CrabDude/gists{/gist_id}","starred_url":"https://api.github.com/users/CrabDude/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CrabDude/subscriptions","organizations_url":"https://api.github.com/users/CrabDude/orgs","repos_url":"https://api.github.com/users/CrabDude/repos","events_url":"https://api.github.com/users/CrabDude/events{/privacy}","received_events_url":"https://api.github.com/users/CrabDude/received_events","type":"User","site_admin":false},"body":"**What is the purpose of this pull request? (put an \"X\" next to item)**\r\n\r\n[X] Documentation update\r\n[X] Other, please explain:\r\n\r\nThe ability to override config values based on glob pattern matching relative to the config path.\r\n\r\nhttps://github.com/eslint/eslint/issues/3611\r\n\r\n**Please check each item to ensure your pull request is ready:**\r\n\r\n- [X] I've read the [pull request guide](http://eslint.org/docs/developer-guide/contributing/pull-requests)\r\n- [X] I've included tests for my change\r\n- [X] I've updated documentation for my change (if appropriate)\r\n\r\n**What changes did you make? (Give an overview)**\r\n\r\n1. Added the ability to add configurations targeting specific files based on glob patterns:\r\n\r\n```js\r\n{\r\n    rules: {\r\n        semi: \"error\"\r\n    },\r\n    overrides: [\r\n        {\r\n            files: [\"foo/*.js\"],\r\n            extends: \"eslint:recommended\",\r\n            rules: {\r\n                semi: \"warn\"\r\n            }\r\n        }\r\n\r\n    ]\r\n}\r\n\r\n```\r\n\r\n*This mostly follows @nzakas' [micro-proposal](https://github.com/eslint/eslint/issues/3611#issuecomment-247457717), but with [grunt-style aggregating glob pattern arrays](http://gruntjs.com/configuring-tasks#globbing-patterns).*\r\n\r\n2\\. Importantly, this means files within the same directory no longer necessarily share the same config. Consequently, configs can no longer be cached per directory. To avoid performance degradation due to lack of directory config caching, a new caching strategy was implemented, which necessitated a refactoring of `lib/config.js`.\r\n\r\nSpecifically, a vector based caching was implemented, where a vector is an array of absolute config file paths within a hierarchy that apply to a given file, including separate entries for `\"overrides\"` sub-configs. This hierarchy can then be used to generate a hash for caching, or to merge the config hierarchy and then cached and returned from `Config.prototype.getConfig(filePath)`.\r\n\r\n**Example**\r\nGiven the following config hierarchy:\r\n```js\r\nproject-root\r\n├── app\r\n│   ├── lib\r\n│   │   ├── foo.js\r\n│   │   ├── fooSpec.js\r\n│   │   ├── bazSpec.js\r\n│   ├── components\r\n│   │   ├── bar.js\r\n│   │   ├── barSpec.js\r\n│   ├── .eslintrc\r\n├── server\r\n│   ├── server.js\r\n│   ├── serverSpec.js\r\n├── .eslintrc\r\n```\r\n\r\nWith corresponding configs:\r\n\r\n```js\r\n// project-root/.eslintrc\r\n{\r\n  rules: { \"no-unused-expression\": 2, semi: 0 },\r\n  overrides: [{\r\n    files: \"**/*Spec.js\",\r\n    rules: { \"no-unused-expression\": 0 }\r\n  }]\r\n} \r\n```\r\n\r\n```js\r\n// project-root/app/.eslintrc\r\n{\r\n  env: { node: true },\r\n  rules: { no-console: 1 },\r\n  overrides: [\r\n    {\r\n      files: \"lib/*Spec.js\",\r\n      rules: { \"no-console\": 0 }\r\n    },\r\n    {\r\n      files: \"components/*Spec.js\",\r\n      env: { browser: true }\r\n    },\r\n    {\r\n      files: \"**/*Spec.js\",\r\n      env: { \"mocha\": true }\r\n    }\r\n  ]\r\n} \r\n```\r\n\r\nFor `project-root/app/lib/fooSpec.js`, where `/project-root/` is the absolute path to `project-root`, the corresponding config vector and caching hash (included for illustration, but not important) would be:\r\n\r\n```js\r\n// Config vector\r\n[\r\n  '/project-root/.eslintrc',\r\n  '/project-root/.eslintrc:0',\r\n  '/project-root/app/.eslintrc',\r\n  '/project-root/app/.eslintrc:0',\r\n  // Note the absence of sub-config 1 here\r\n  '/project-root/app/.eslintrc:2'\r\n]\r\n\r\n// Config vector hash\r\n'/project-root/.eslintrc,/project-root/.eslintrc:0,/project-root/app/.eslintrc,/project-root/app/.eslintrc:0,/project-root/app/.eslintrc:2'\r\n```\r\n\r\nAnd the resulting corresponding config value (cached at `config.mergedCache[hash]`):\r\n```js\r\n{\r\n  env: {\r\n    node: true,\r\n    mocha: true\r\n  }\r\n  rules: {\r\n    \"no-unused-expression\": 0,\r\n    \"no-console\": 0,\r\n    semi: 0\r\n  }\r\n}\r\n\r\n// Where the cache includes the properly expanded \"env\" values\r\n```\r\n\r\nAnd `getConfig('project-root/app/lib/bazSpec.js')` would load from cache. \r\n\r\n**Details**\r\nTo maximize the performance benefits of refactoring the config loader caching layer, several other layers of caching (on the config instance) were implemented including config file contents caching, iterative config caching (a merged sub-vector cache), config hierarchy caching by vector and directory-based local config file hierarchy caching.\r\n\r\nAs a result, from the previous example, all of the files within `project-root` would load from various degrees of partial cache.\r\n\r\n**Results**\r\nThe net performance gain from these caching improvements is **a consistent 15% performance increase** when run against the Pinterest web codebase regardless of whether an override config is utilized.\r\n\r\n**Is there anything you'd like reviewers to focus on?**\r\n\r\nEdge cases.\r\n\r\n\r\n@lo1tuma\r\n\r\n*EDIT: Added an expanded example.*","created_at":"2016-09-17T02:12:08Z","updated_at":"2016-09-22T17:11:32Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9b4491573f9dca46f886b12fe5a5b0c38bb68405","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/eslint/eslint/pulls/7177/commits","review_comments_url":"https://api.github.com/repos/eslint/eslint/pulls/7177/comments","review_comment_url":"https://api.github.com/repos/eslint/eslint/pulls/comments{/number}","comments_url":"https://api.github.com/repos/eslint/eslint/issues/7177/comments","statuses_url":"https://api.github.com/repos/eslint/eslint/statuses/23e2b85da3b5f0951b83f16ee11341b1f52661b1","head":{"label":"CrabDude:overrides","ref":"overrides","sha":"23e2b85da3b5f0951b83f16ee11341b1f52661b1","user":{"login":"CrabDude","id":204037,"avatar_url":"https://avatars.githubusercontent.com/u/204037?v=3","gravatar_id":"","url":"https://api.github.com/users/CrabDude","html_url":"https://github.com/CrabDude","followers_url":"https://api.github.com/users/CrabDude/followers","following_url":"https://api.github.com/users/CrabDude/following{/other_user}","gists_url":"https://api.github.com/users/CrabDude/gists{/gist_id}","starred_url":"https://api.github.com/users/CrabDude/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CrabDude/subscriptions","organizations_url":"https://api.github.com/users/CrabDude/orgs","repos_url":"https://api.github.com/users/CrabDude/repos","events_url":"https://api.github.com/users/CrabDude/events{/privacy}","received_events_url":"https://api.github.com/users/CrabDude/received_events","type":"User","site_admin":false},"repo":{"id":68339821,"name":"eslint","full_name":"CrabDude/eslint","owner":{"login":"CrabDude","id":204037,"avatar_url":"https://avatars.githubusercontent.com/u/204037?v=3","gravatar_id":"","url":"https://api.github.com/users/CrabDude","html_url":"https://github.com/CrabDude","followers_url":"https://api.github.com/users/CrabDude/followers","following_url":"https://api.github.com/users/CrabDude/following{/other_user}","gists_url":"https://api.github.com/users/CrabDude/gists{/gist_id}","starred_url":"https://api.github.com/users/CrabDude/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CrabDude/subscriptions","organizations_url":"https://api.github.com/users/CrabDude/orgs","repos_url":"https://api.github.com/users/CrabDude/repos","events_url":"https://api.github.com/users/CrabDude/events{/privacy}","received_events_url":"https://api.github.com/users/CrabDude/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/CrabDude/eslint","description":"A fully pluggable tool for identifying and reporting on patterns in JavaScript.","fork":true,"url":"https://api.github.com/repos/CrabDude/eslint","forks_url":"https://api.github.com/repos/CrabDude/eslint/forks","keys_url":"https://api.github.com/repos/CrabDude/eslint/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CrabDude/eslint/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CrabDude/eslint/teams","hooks_url":"https://api.github.com/repos/CrabDude/eslint/hooks","issue_events_url":"https://api.github.com/repos/CrabDude/eslint/issues/events{/number}","events_url":"https://api.github.com/repos/CrabDude/eslint/events","assignees_url":"https://api.github.com/repos/CrabDude/eslint/assignees{/user}","branches_url":"https://api.github.com/repos/CrabDude/eslint/branches{/branch}","tags_url":"https://api.github.com/repos/CrabDude/eslint/tags","blobs_url":"https://api.github.com/repos/CrabDude/eslint/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CrabDude/eslint/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CrabDude/eslint/git/refs{/sha}","trees_url":"https://api.github.com/repos/CrabDude/eslint/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CrabDude/eslint/statuses/{sha}","languages_url":"https://api.github.com/repos/CrabDude/eslint/languages","stargazers_url":"https://api.github.com/repos/CrabDude/eslint/stargazers","contributors_url":"https://api.github.com/repos/CrabDude/eslint/contributors","subscribers_url":"https://api.github.com/repos/CrabDude/eslint/subscribers","subscription_url":"https://api.github.com/repos/CrabDude/eslint/subscription","commits_url":"https://api.github.com/repos/CrabDude/eslint/commits{/sha}","git_commits_url":"https://api.github.com/repos/CrabDude/eslint/git/commits{/sha}","comments_url":"https://api.github.com/repos/CrabDude/eslint/comments{/number}","issue_comment_url":"https://api.github.com/repos/CrabDude/eslint/issues/comments{/number}","contents_url":"https://api.github.com/repos/CrabDude/eslint/contents/{+path}","compare_url":"https://api.github.com/repos/CrabDude/eslint/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CrabDude/eslint/merges","archive_url":"https://api.github.com/repos/CrabDude/eslint/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CrabDude/eslint/downloads","issues_url":"https://api.github.com/repos/CrabDude/eslint/issues{/number}","pulls_url":"https://api.github.com/repos/CrabDude/eslint/pulls{/number}","milestones_url":"https://api.github.com/repos/CrabDude/eslint/milestones{/number}","notifications_url":"https://api.github.com/repos/CrabDude/eslint/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CrabDude/eslint/labels{/name}","releases_url":"https://api.github.com/repos/CrabDude/eslint/releases{/id}","deployments_url":"https://api.github.com/repos/CrabDude/eslint/deployments","created_at":"2016-09-15T23:38:36Z","updated_at":"2016-09-15T23:38:42Z","pushed_at":"2016-09-17T02:09:15Z","git_url":"git://github.com/CrabDude/eslint.git","ssh_url":"git@github.com:CrabDude/eslint.git","clone_url":"https://github.com/CrabDude/eslint.git","svn_url":"https://github.com/CrabDude/eslint","homepage":"http://eslint.org","size":12706,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"eslint:master","ref":"master","sha":"e0163841067cf3f9e84e83b8a8d914306f3618ee","user":{"login":"eslint","id":6019716,"avatar_url":"https://avatars.githubusercontent.com/u/6019716?v=3","gravatar_id":"","url":"https://api.github.com/users/eslint","html_url":"https://github.com/eslint","followers_url":"https://api.github.com/users/eslint/followers","following_url":"https://api.github.com/users/eslint/following{/other_user}","gists_url":"https://api.github.com/users/eslint/gists{/gist_id}","starred_url":"https://api.github.com/users/eslint/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eslint/subscriptions","organizations_url":"https://api.github.com/users/eslint/orgs","repos_url":"https://api.github.com/users/eslint/repos","events_url":"https://api.github.com/users/eslint/events{/privacy}","received_events_url":"https://api.github.com/users/eslint/received_events","type":"Organization","site_admin":false},"repo":{"id":11061773,"name":"eslint","full_name":"eslint/eslint","owner":{"login":"eslint","id":6019716,"avatar_url":"https://avatars.githubusercontent.com/u/6019716?v=3","gravatar_id":"","url":"https://api.github.com/users/eslint","html_url":"https://github.com/eslint","followers_url":"https://api.github.com/users/eslint/followers","following_url":"https://api.github.com/users/eslint/following{/other_user}","gists_url":"https://api.github.com/users/eslint/gists{/gist_id}","starred_url":"https://api.github.com/users/eslint/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eslint/subscriptions","organizations_url":"https://api.github.com/users/eslint/orgs","repos_url":"https://api.github.com/users/eslint/repos","events_url":"https://api.github.com/users/eslint/events{/privacy}","received_events_url":"https://api.github.com/users/eslint/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/eslint/eslint","description":"A fully pluggable tool for identifying and reporting on patterns in JavaScript.","fork":false,"url":"https://api.github.com/repos/eslint/eslint","forks_url":"https://api.github.com/repos/eslint/eslint/forks","keys_url":"https://api.github.com/repos/eslint/eslint/keys{/key_id}","collaborators_url":"https://api.github.com/repos/eslint/eslint/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/eslint/eslint/teams","hooks_url":"https://api.github.com/repos/eslint/eslint/hooks","issue_events_url":"https://api.github.com/repos/eslint/eslint/issues/events{/number}","events_url":"https://api.github.com/repos/eslint/eslint/events","assignees_url":"https://api.github.com/repos/eslint/eslint/assignees{/user}","branches_url":"https://api.github.com/repos/eslint/eslint/branches{/branch}","tags_url":"https://api.github.com/repos/eslint/eslint/tags","blobs_url":"https://api.github.com/repos/eslint/eslint/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/eslint/eslint/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/eslint/eslint/git/refs{/sha}","trees_url":"https://api.github.com/repos/eslint/eslint/git/trees{/sha}","statuses_url":"https://api.github.com/repos/eslint/eslint/statuses/{sha}","languages_url":"https://api.github.com/repos/eslint/eslint/languages","stargazers_url":"https://api.github.com/repos/eslint/eslint/stargazers","contributors_url":"https://api.github.com/repos/eslint/eslint/contributors","subscribers_url":"https://api.github.com/repos/eslint/eslint/subscribers","subscription_url":"https://api.github.com/repos/eslint/eslint/subscription","commits_url":"https://api.github.com/repos/eslint/eslint/commits{/sha}","git_commits_url":"https://api.github.com/repos/eslint/eslint/git/commits{/sha}","comments_url":"https://api.github.com/repos/eslint/eslint/comments{/number}","issue_comment_url":"https://api.github.com/repos/eslint/eslint/issues/comments{/number}","contents_url":"https://api.github.com/repos/eslint/eslint/contents/{+path}","compare_url":"https://api.github.com/repos/eslint/eslint/compare/{base}...{head}","merges_url":"https://api.github.com/repos/eslint/eslint/merges","archive_url":"https://api.github.com/repos/eslint/eslint/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/eslint/eslint/downloads","issues_url":"https://api.github.com/repos/eslint/eslint/issues{/number}","pulls_url":"https://api.github.com/repos/eslint/eslint/pulls{/number}","milestones_url":"https://api.github.com/repos/eslint/eslint/milestones{/number}","notifications_url":"https://api.github.com/repos/eslint/eslint/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/eslint/eslint/labels{/name}","releases_url":"https://api.github.com/repos/eslint/eslint/releases{/id}","deployments_url":"https://api.github.com/repos/eslint/eslint/deployments","created_at":"2013-06-29T23:59:48Z","updated_at":"2016-09-22T16:33:58Z","pushed_at":"2016-09-22T16:07:49Z","git_url":"git://github.com/eslint/eslint.git","ssh_url":"git@github.com:eslint/eslint.git","clone_url":"https://github.com/eslint/eslint.git","svn_url":"https://github.com/eslint/eslint","homepage":"http://eslint.org","size":18923,"stargazers_count":5919,"watchers_count":5919,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1155,"mirror_url":null,"open_issues_count":221,"forks":1155,"open_issues":221,"watchers":5919,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/eslint/eslint/pulls/7177"},"html":{"href":"https://github.com/eslint/eslint/pull/7177"},"issue":{"href":"https://api.github.com/repos/eslint/eslint/issues/7177"},"comments":{"href":"https://api.github.com/repos/eslint/eslint/issues/7177/comments"},"review_comments":{"href":"https://api.github.com/repos/eslint/eslint/pulls/7177/comments"},"review_comment":{"href":"https://api.github.com/repos/eslint/eslint/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/eslint/eslint/pulls/7177/commits"},"statuses":{"href":"https://api.github.com/repos/eslint/eslint/statuses/23e2b85da3b5f0951b83f16ee11341b1f52661b1"}}}}
{"actor":{"display_login":"nzakas"}}