{"action":"closed","number":300,"pull_request":{"url":"https://api.github.com/repos/codeclimate/codeclimate/pulls/300","id":56202553,"html_url":"https://github.com/codeclimate/codeclimate/pull/300","diff_url":"https://github.com/codeclimate/codeclimate/pull/300.diff","patch_url":"https://github.com/codeclimate/codeclimate/pull/300.patch","issue_url":"https://api.github.com/repos/codeclimate/codeclimate/issues/300","number":300,"state":"closed","locked":false,"title":"Drastically simplify workspace building","user":{"login":"pbrisbin","id":50812,"avatar_url":"https://avatars.githubusercontent.com/u/50812?v=3","gravatar_id":"","url":"https://api.github.com/users/pbrisbin","html_url":"https://github.com/pbrisbin","followers_url":"https://api.github.com/users/pbrisbin/followers","following_url":"https://api.github.com/users/pbrisbin/following{/other_user}","gists_url":"https://api.github.com/users/pbrisbin/gists{/gist_id}","starred_url":"https://api.github.com/users/pbrisbin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pbrisbin/subscriptions","organizations_url":"https://api.github.com/users/pbrisbin/orgs","repos_url":"https://api.github.com/users/pbrisbin/repos","events_url":"https://api.github.com/users/pbrisbin/events{/privacy}","received_events_url":"https://api.github.com/users/pbrisbin/received_events","type":"User","site_admin":false},"body":"/cc @codeclimate/review\r\n\r\nThis commit removes IncludePathsBuilder and all classes involved in it. In its\r\nplace, we have CC::Workspace (new terminology) with drastically simpler\r\nsemantics. This simpler approach should be faster and more reliable, at the\r\nexpense of less features.\r\n\r\nWe drop support for glob-style patterns. Instead we support a simple list of\r\nfiles or directories to ignore. We stop sending an exclude_paths configuration\r\nkey in /engines.json, only include_paths now. We stop incorporating .gitignore\r\nin workspace-building.\r\n\r\nReasoning:\r\n\r\n- Paths, not patterns.\r\n\r\n  We see little actual value in patterns support. We leave it up to the engine\r\n  to know that it should (for example) only target .py files, therefore we\r\n  don't have to exclude **/*.pyc from the workspace.\r\n\r\n  We've found the vast majority of our users have just been trying to exclude\r\n  directories. They're actually quite frustrated having to shoe-horn it into\r\n  patterns, only to be met with slowness or frequent bugs as we needlessly\r\n  expand and filter these patterns in complicated ways.\r\n\r\n  Old:\r\n\r\n      exclude_paths:\r\n      - .node_modules/**/*\r\n      - app/assets/vendor/**\r\n\r\n  New:\r\n\r\n      exclude_paths:\r\n      - .node_modules\r\n      - app/assets/vendor\r\n\r\n  We minimize disruption to these users by transparently handling a pattern\r\n  such as foo/bar/\\*\\* or foo/bar/\\*\\*/\\*\\* as the directory foo/bar. Other patterns,\r\n  such as foo/\\*.pyc will generate a warning and be ignored.\r\n\r\n- Ignore .gitignore\r\n\r\n  The motivation for this feature is unclear, so I'm testing the waters about\r\n  dropping it as it simplifies things.\r\n\r\n- Stop all the permissions checking\r\n\r\n  If the current directory contents, plus the user's defined excludes causes a\r\n  permissions error in the workspace, it should be treated as an actual error:\r\n  the user must modify the permissions or add the unreadable file to excludes.\r\n\r\nAdditional feature:\r\n\r\n- Per-engine excludes\r\n\r\n  The algorithm supports repeated filtering. That is, we can build a workspace\r\n  filtered from top-level exclude_paths once, then filter that further for each\r\n  engine with per-engine-excludes.\r\n\r\nCaveats:\r\n\r\nThe \"explicit includes\" feature (i.e. codeclimate analyze [FILE, ...]) has an\r\ninteresting interaction with this approach. Specifying files in this way\r\neffectively means we begin building a workspace from these files rather than\r\nthe current directory's contents. This means excludes will still apply on top\r\nof the passed files. This may not be what we want, an alternative would be to\r\npass along those paths as-is as include_paths and do no filtering -- I leave\r\nthe decision open, with no strong opinion of my own.\r\n\r\nBecause the passed files are compared against the exclude list, they must be\r\nsimple and relative (i.e. they cannot be \".\" or \"./\"-prefixed), as they would\r\ncome out in a * glob. This is brittle, but currently necessary. See\r\nPathsValidator for more details.\r\n\r\nAdditionally, the way the exclude list applies on top of the given files can be\r\nsurprising. A user could exclude spec, for example, and pass spec/foo.rb. In\r\nsuch a case, spec/foo.rb will be processed which may be surprising. This is\r\nbecause the current exclusion check assumes we'd never even get to a file\r\nwithin spec if that directory were entirely excluded, so there's no logic to\r\ncatch such a case.\r\n\r\nI'm inclined to either simplify the feature to a simple pass-through or keep\r\nthese caveats and just document the behavior.","created_at":"2016-01-15T18:14:24Z","updated_at":"2016-01-21T20:11:22Z","closed_at":"2016-01-21T20:11:22Z","merged_at":null,"merge_commit_sha":"1a860df06068219b4e2ded88a5d9d7b6804de6e7","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/codeclimate/codeclimate/pulls/300/commits","review_comments_url":"https://api.github.com/repos/codeclimate/codeclimate/pulls/300/comments","review_comment_url":"https://api.github.com/repos/codeclimate/codeclimate/pulls/comments{/number}","comments_url":"https://api.github.com/repos/codeclimate/codeclimate/issues/300/comments","statuses_url":"https://api.github.com/repos/codeclimate/codeclimate/statuses/86e938b39ce0cb08969c5da4fa074d15f4f4c123","head":{"label":"codeclimate:pb-enough-is-enough","ref":"pb-enough-is-enough","sha":"86e938b39ce0cb08969c5da4fa074d15f4f4c123","user":{"login":"codeclimate","id":789641,"avatar_url":"https://avatars.githubusercontent.com/u/789641?v=3","gravatar_id":"","url":"https://api.github.com/users/codeclimate","html_url":"https://github.com/codeclimate","followers_url":"https://api.github.com/users/codeclimate/followers","following_url":"https://api.github.com/users/codeclimate/following{/other_user}","gists_url":"https://api.github.com/users/codeclimate/gists{/gist_id}","starred_url":"https://api.github.com/users/codeclimate/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codeclimate/subscriptions","organizations_url":"https://api.github.com/users/codeclimate/orgs","repos_url":"https://api.github.com/users/codeclimate/repos","events_url":"https://api.github.com/users/codeclimate/events{/privacy}","received_events_url":"https://api.github.com/users/codeclimate/received_events","type":"Organization","site_admin":false},"repo":{"id":37724576,"name":"codeclimate","full_name":"codeclimate/codeclimate","owner":{"login":"codeclimate","id":789641,"avatar_url":"https://avatars.githubusercontent.com/u/789641?v=3","gravatar_id":"","url":"https://api.github.com/users/codeclimate","html_url":"https://github.com/codeclimate","followers_url":"https://api.github.com/users/codeclimate/followers","following_url":"https://api.github.com/users/codeclimate/following{/other_user}","gists_url":"https://api.github.com/users/codeclimate/gists{/gist_id}","starred_url":"https://api.github.com/users/codeclimate/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codeclimate/subscriptions","organizations_url":"https://api.github.com/users/codeclimate/orgs","repos_url":"https://api.github.com/users/codeclimate/repos","events_url":"https://api.github.com/users/codeclimate/events{/privacy}","received_events_url":"https://api.github.com/users/codeclimate/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/codeclimate/codeclimate","description":"Code Climate CLI","fork":false,"url":"https://api.github.com/repos/codeclimate/codeclimate","forks_url":"https://api.github.com/repos/codeclimate/codeclimate/forks","keys_url":"https://api.github.com/repos/codeclimate/codeclimate/keys{/key_id}","collaborators_url":"https://api.github.com/repos/codeclimate/codeclimate/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/codeclimate/codeclimate/teams","hooks_url":"https://api.github.com/repos/codeclimate/codeclimate/hooks","issue_events_url":"https://api.github.com/repos/codeclimate/codeclimate/issues/events{/number}","events_url":"https://api.github.com/repos/codeclimate/codeclimate/events","assignees_url":"https://api.github.com/repos/codeclimate/codeclimate/assignees{/user}","branches_url":"https://api.github.com/repos/codeclimate/codeclimate/branches{/branch}","tags_url":"https://api.github.com/repos/codeclimate/codeclimate/tags","blobs_url":"https://api.github.com/repos/codeclimate/codeclimate/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/codeclimate/codeclimate/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/codeclimate/codeclimate/git/refs{/sha}","trees_url":"https://api.github.com/repos/codeclimate/codeclimate/git/trees{/sha}","statuses_url":"https://api.github.com/repos/codeclimate/codeclimate/statuses/{sha}","languages_url":"https://api.github.com/repos/codeclimate/codeclimate/languages","stargazers_url":"https://api.github.com/repos/codeclimate/codeclimate/stargazers","contributors_url":"https://api.github.com/repos/codeclimate/codeclimate/contributors","subscribers_url":"https://api.github.com/repos/codeclimate/codeclimate/subscribers","subscription_url":"https://api.github.com/repos/codeclimate/codeclimate/subscription","commits_url":"https://api.github.com/repos/codeclimate/codeclimate/commits{/sha}","git_commits_url":"https://api.github.com/repos/codeclimate/codeclimate/git/commits{/sha}","comments_url":"https://api.github.com/repos/codeclimate/codeclimate/comments{/number}","issue_comment_url":"https://api.github.com/repos/codeclimate/codeclimate/issues/comments{/number}","contents_url":"https://api.github.com/repos/codeclimate/codeclimate/contents/{+path}","compare_url":"https://api.github.com/repos/codeclimate/codeclimate/compare/{base}...{head}","merges_url":"https://api.github.com/repos/codeclimate/codeclimate/merges","archive_url":"https://api.github.com/repos/codeclimate/codeclimate/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/codeclimate/codeclimate/downloads","issues_url":"https://api.github.com/repos/codeclimate/codeclimate/issues{/number}","pulls_url":"https://api.github.com/repos/codeclimate/codeclimate/pulls{/number}","milestones_url":"https://api.github.com/repos/codeclimate/codeclimate/milestones{/number}","notifications_url":"https://api.github.com/repos/codeclimate/codeclimate/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/codeclimate/codeclimate/labels{/name}","releases_url":"https://api.github.com/repos/codeclimate/codeclimate/releases{/id}","created_at":"2015-06-19T13:54:41Z","updated_at":"2016-01-21T11:01:48Z","pushed_at":"2016-01-21T20:10:54Z","git_url":"git://github.com/codeclimate/codeclimate.git","ssh_url":"git@github.com:codeclimate/codeclimate.git","clone_url":"https://github.com/codeclimate/codeclimate.git","svn_url":"https://github.com/codeclimate/codeclimate","homepage":"https://codeclimate.com/","size":923,"stargazers_count":627,"watchers_count":627,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":59,"mirror_url":null,"open_issues_count":18,"forks":59,"open_issues":18,"watchers":627,"default_branch":"master"}},"base":{"label":"codeclimate:master","ref":"master","sha":"14d9b9eebb84e9e0a9cabd77b023b48206dcac6d","user":{"login":"codeclimate","id":789641,"avatar_url":"https://avatars.githubusercontent.com/u/789641?v=3","gravatar_id":"","url":"https://api.github.com/users/codeclimate","html_url":"https://github.com/codeclimate","followers_url":"https://api.github.com/users/codeclimate/followers","following_url":"https://api.github.com/users/codeclimate/following{/other_user}","gists_url":"https://api.github.com/users/codeclimate/gists{/gist_id}","starred_url":"https://api.github.com/users/codeclimate/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codeclimate/subscriptions","organizations_url":"https://api.github.com/users/codeclimate/orgs","repos_url":"https://api.github.com/users/codeclimate/repos","events_url":"https://api.github.com/users/codeclimate/events{/privacy}","received_events_url":"https://api.github.com/users/codeclimate/received_events","type":"Organization","site_admin":false},"repo":{"id":37724576,"name":"codeclimate","full_name":"codeclimate/codeclimate","owner":{"login":"codeclimate","id":789641,"avatar_url":"https://avatars.githubusercontent.com/u/789641?v=3","gravatar_id":"","url":"https://api.github.com/users/codeclimate","html_url":"https://github.com/codeclimate","followers_url":"https://api.github.com/users/codeclimate/followers","following_url":"https://api.github.com/users/codeclimate/following{/other_user}","gists_url":"https://api.github.com/users/codeclimate/gists{/gist_id}","starred_url":"https://api.github.com/users/codeclimate/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codeclimate/subscriptions","organizations_url":"https://api.github.com/users/codeclimate/orgs","repos_url":"https://api.github.com/users/codeclimate/repos","events_url":"https://api.github.com/users/codeclimate/events{/privacy}","received_events_url":"https://api.github.com/users/codeclimate/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/codeclimate/codeclimate","description":"Code Climate CLI","fork":false,"url":"https://api.github.com/repos/codeclimate/codeclimate","forks_url":"https://api.github.com/repos/codeclimate/codeclimate/forks","keys_url":"https://api.github.com/repos/codeclimate/codeclimate/keys{/key_id}","collaborators_url":"https://api.github.com/repos/codeclimate/codeclimate/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/codeclimate/codeclimate/teams","hooks_url":"https://api.github.com/repos/codeclimate/codeclimate/hooks","issue_events_url":"https://api.github.com/repos/codeclimate/codeclimate/issues/events{/number}","events_url":"https://api.github.com/repos/codeclimate/codeclimate/events","assignees_url":"https://api.github.com/repos/codeclimate/codeclimate/assignees{/user}","branches_url":"https://api.github.com/repos/codeclimate/codeclimate/branches{/branch}","tags_url":"https://api.github.com/repos/codeclimate/codeclimate/tags","blobs_url":"https://api.github.com/repos/codeclimate/codeclimate/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/codeclimate/codeclimate/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/codeclimate/codeclimate/git/refs{/sha}","trees_url":"https://api.github.com/repos/codeclimate/codeclimate/git/trees{/sha}","statuses_url":"https://api.github.com/repos/codeclimate/codeclimate/statuses/{sha}","languages_url":"https://api.github.com/repos/codeclimate/codeclimate/languages","stargazers_url":"https://api.github.com/repos/codeclimate/codeclimate/stargazers","contributors_url":"https://api.github.com/repos/codeclimate/codeclimate/contributors","subscribers_url":"https://api.github.com/repos/codeclimate/codeclimate/subscribers","subscription_url":"https://api.github.com/repos/codeclimate/codeclimate/subscription","commits_url":"https://api.github.com/repos/codeclimate/codeclimate/commits{/sha}","git_commits_url":"https://api.github.com/repos/codeclimate/codeclimate/git/commits{/sha}","comments_url":"https://api.github.com/repos/codeclimate/codeclimate/comments{/number}","issue_comment_url":"https://api.github.com/repos/codeclimate/codeclimate/issues/comments{/number}","contents_url":"https://api.github.com/repos/codeclimate/codeclimate/contents/{+path}","compare_url":"https://api.github.com/repos/codeclimate/codeclimate/compare/{base}...{head}","merges_url":"https://api.github.com/repos/codeclimate/codeclimate/merges","archive_url":"https://api.github.com/repos/codeclimate/codeclimate/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/codeclimate/codeclimate/downloads","issues_url":"https://api.github.com/repos/codeclimate/codeclimate/issues{/number}","pulls_url":"https://api.github.com/repos/codeclimate/codeclimate/pulls{/number}","milestones_url":"https://api.github.com/repos/codeclimate/codeclimate/milestones{/number}","notifications_url":"https://api.github.com/repos/codeclimate/codeclimate/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/codeclimate/codeclimate/labels{/name}","releases_url":"https://api.github.com/repos/codeclimate/codeclimate/releases{/id}","created_at":"2015-06-19T13:54:41Z","updated_at":"2016-01-21T11:01:48Z","pushed_at":"2016-01-21T20:10:54Z","git_url":"git://github.com/codeclimate/codeclimate.git","ssh_url":"git@github.com:codeclimate/codeclimate.git","clone_url":"https://github.com/codeclimate/codeclimate.git","svn_url":"https://github.com/codeclimate/codeclimate","homepage":"https://codeclimate.com/","size":923,"stargazers_count":627,"watchers_count":627,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":59,"mirror_url":null,"open_issues_count":18,"forks":59,"open_issues":18,"watchers":627,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/codeclimate/codeclimate/pulls/300"},"html":{"href":"https://github.com/codeclimate/codeclimate/pull/300"},"issue":{"href":"https://api.github.com/repos/codeclimate/codeclimate/issues/300"},"comments":{"href":"https://api.github.com/repos/codeclimate/codeclimate/issues/300/comments"},"review_comments":{"href":"https://api.github.com/repos/codeclimate/codeclimate/pulls/300/comments"},"review_comment":{"href":"https://api.github.com/repos/codeclimate/codeclimate/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/codeclimate/codeclimate/pulls/300/commits"},"statuses":{"href":"https://api.github.com/repos/codeclimate/codeclimate/statuses/86e938b39ce0cb08969c5da4fa074d15f4f4c123"}},"merged":false,"mergeable":true,"mergeable_state":"unstable","merged_by":null,"comments":7,"review_comments":12,"commits":12,"additions":535,"deletions":788,"changed_files":23}}