{"action":"created","comment":{"url":"https://api.github.com/repos/gradle/gradle/pulls/comments/174002052","pull_request_review_id":103277969,"id":174002052,"diff_hunk":"@@ -0,0 +1,415 @@\n+/*\n+ * Copyright 2018 the original author or authors.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ *      http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+package org.gradle.integtests.resolve.capabilities\n+\n+import org.gradle.integtests.fixtures.GradleMetadataResolveRunner\n+import org.gradle.integtests.fixtures.RequiredFeature\n+import org.gradle.integtests.fixtures.RequiredFeatures\n+import org.gradle.integtests.resolve.AbstractModuleDependencyResolveTest\n+import spock.lang.Unroll\n+\n+class CapabilitiesUseCasesIntegrationTest extends AbstractModuleDependencyResolveTest {\n+    def setup() {\n+        buildFile << \"\"\"\n+            configurations { conf }\n+        \"\"\"\n+        executer.withStackTraceChecksDisabled()\n+    }\n+\n+    /**\n+     * This use case corresponds to an external library which has 2 variants published at\n+     * different coordinates, and using both at the same time is illegal. The libraries\n+     * were not published using Gradle, so the consumer needs a way to express that and\n+     * enforce the use of only one of them at the same time.\n+     */\n+    def \"can choose between cglib and cglib-nodep by declaring capabilities\"() {\n+        given:\n+        repository {\n+            'cglib:cglib:3.2.5'()\n+            'cglib:cglib-nodep:3.2.5'()\n+        }\n+\n+        buildFile << \"\"\"\n+            dependencies {\n+               conf \"cglib:cglib-nodep:3.2.5\"\n+               conf \"cglib:cglib:3.2.5\"\n+            \n+               components {\n+                  withModule('cglib:cglib') {\n+                     allVariants {\n+                         withCapabilities {\n+                             addCapability('cglib', 'cglib', '3.2.5')\n+                         }\n+                     }\n+                  }\n+                  withModule('cglib:cglib-nodep') {\n+                     allVariants {\n+                         withCapabilities {\n+                             addCapability('cglib', 'cglib', '3.2.5')\n+                         }\n+                     }\n+                  }\n+               }\n+            }\n+            \n+            configurations.all {\n+                resolutionStrategy {\n+                    dependencySubstitution {\n+                        substitute(module('cglib:cglib-nodep'))\n+                            .because('capability cglib is provided by cglib:cglib and cglib:cglib-nodep')\n+                            .with(module('cglib:cglib:3.2.5'))\n+                    }\n+                }\n+            }\n+        \"\"\"\n+\n+        when:\n+        repositoryInteractions {\n+            'cglib:cglib:3.2.5' {\n+                expectResolve()\n+            }\n+        }\n+        run ':checkDeps'\n+\n+        then:\n+        resolve.expectGraph {\n+            root(\":\", \":test:\") {\n+                module('cglib:cglib:3.2.5').byReason('capability cglib is provided by cglib:cglib and cglib:cglib-nodep')\n+                edge('cglib:cglib-nodep:3.2.5', 'cglib:cglib:3.2.5').byReason('capability cglib is provided by cglib:cglib and cglib:cglib-nodep')\n+            }\n+        }\n+\n+    }\n+\n+    /**\n+     * This use case corresponds to the case where a library maintainer publishes a library\n+     * either as individual modules, or using a fatjar. It's illegal to have both the fat jar and\n+     * individual modules on the classpath, so we need a way to declare that we prefer to use\n+     * the fat jar.\n+     *\n+     * This is from the consumer point of view, fixing the fact the library doesn't declare capabilities.\n+     */\n+    def \"can select groovy-all over individual groovy-whatever\"() {\n+        given:\n+        repository {\n+            'org.apache:groovy:1.0'()\n+            'org.apache:groovy-json:1.0'()\n+            'org.apache:groovy-xml:1.0'()\n+            'org.apache:groovy-all:1.0'()\n+\n+            'org:a:1.0' {\n+                dependsOn 'org.apache:groovy:1.0'\n+                dependsOn 'org.apache:groovy-json:1.0'\n+            }\n+            'org:b:1.0' {\n+                dependsOn 'org.apache:groovy-all:1.0'\n+            }\n+        }\n+\n+        buildFile << \"\"\"\n+            dependencies {\n+               conf \"org:a:1.0\"\n+               conf \"org:b:1.0\"\n+            \n+               components {\n+                  withModule('org.apache:groovy') {\n+                     allVariants {\n+                        withCapabilities {\n+                            addCapability('org.apache', 'groovy', '1.0')\n+                        }\n+                     }\n+                  }\n+                  withModule('org.apache:groovy-json') {\n+                     allVariants {\n+                        withCapabilities {\n+                            addCapability('org.apache', 'groovy-json', '1.0')\n+                        }\n+                     }\n+                  }\n+                  withModule('org.apache:groovy-all') {\n+                     allVariants {\n+                        withCapabilities {\n+                            addCapability('org.apache', 'groovy', '1.0')\n+                            addCapability('org.apache', 'groovy-json', '1.0')\n+                        }\n+                     }\n+                  }\n+               }               \n+\n+               // solution\n+               configurations.all {\n+                   resolutionStrategy {\n+                       dependencySubstitution {\n+                           substitute module('org.apache:groovy') with module('org.apache:groovy-all:1.0')\n+                           substitute module('org.apache:groovy-json') with module('org.apache:groovy-all:1.0')\n+                       }\n+                   }\n+               }\n+            }\n+        \"\"\"\n+\n+        when:\n+        repositoryInteractions {\n+            'org:a:1.0' {\n+                expectResolve()\n+            }\n+            'org:b:1.0' {\n+                expectResolve()\n+            }\n+            'org.apache:groovy-all:1.0' {\n+                expectResolve()\n+            }\n+        }\n+\n+        then:\n+        run ':checkDeps'\n+        resolve.expectGraph {\n+            root(\":\", \":test:\") {\n+                module('org:a:1.0') {\n+                    edge('org.apache:groovy:1.0', 'org.apache:groovy-all:1.0')\n+                    edge('org.apache:groovy-json:1.0', 'org.apache:groovy-all:1.0')\n+                }\n+                module('org:b:1.0') {\n+                    edge('org.apache:groovy-all:1.0', 'org.apache:groovy-all:1.0')\n+                }\n+            }\n+        }\n+\n+    }\n+\n+    /**\n+     * This use case corresponds to the case where a library maintainer publishes a library\n+     * either as individual modules, or using a fatjar. It's illegal to have both the fat jar and\n+     * individual modules on the classpath, so we need a way to declare that we prefer to use\n+     * the individual jars instead.\n+     *\n+     * It's worth mentioning that the _consumer_ must, in this case, make sure that all the features\n+     * actually used in the fatjar version are replaced with their appropriate module.\n+     *\n+     * This is from the consumer point of view, fixing the fact the library doesn't declare capabilities.\n+     */\n+    def \"can select individual groovy-whatever over individual groovy-all\"() {\n+        given:\n+        repository {\n+            'org.apache:groovy:1.0'()\n+            'org.apache:groovy-json:1.0'()\n+            'org.apache:groovy-xml:1.0'()\n+            'org.apache:groovy-all:1.0'()\n+\n+            'org:a:1.0' {\n+                dependsOn 'org.apache:groovy:1.0'\n+                dependsOn 'org.apache:groovy-json:1.0'\n+            }\n+            'org:b:1.0' {\n+                dependsOn 'org.apache:groovy-all:1.0'\n+            }\n+        }\n+\n+        buildFile << \"\"\"\n+            dependencies {\n+               conf \"org:a:1.0\"\n+               conf \"org:b:1.0\"\n+            \n+               components {\n+                  withModule('org.apache:groovy') {\n+                     allVariants {\n+                        withCapabilities {\n+                            addCapability('org.apache', 'groovy', '1.0')\n+                        }\n+                     }\n+                  }\n+                  withModule('org.apache:groovy-json') {\n+                     allVariants {\n+                        withCapabilities {\n+                            addCapability('org.apache', 'groovy-json', '1.0')\n+                        }\n+                     }\n+                  }\n+                  withModule('org.apache:groovy-all') {\n+                     allVariants {\n+                        withCapabilities {\n+                            addCapability('org.apache', 'groovy', '1.0')\n+                            addCapability('org.apache', 'groovy-json', '1.0')\n+                        }\n+                     }\n+                  }\n+                  \n+                  // solution\n+                  configurations.all {\n+                      resolutionStrategy {\n+                          dependencySubstitution {\n+                              substitute module('org.apache:groovy-all') with module('org.apache:groovy-json:1.0')\n+                          }\n+                      }\n+                  }\n+               } \n+            }\n+        \"\"\"\n+\n+        when:\n+        repositoryInteractions {\n+            'org:a:1.0' {\n+                expectResolve()\n+            }\n+            'org:b:1.0' {\n+                expectResolve()\n+            }\n+            'org.apache:groovy:1.0' {\n+                expectResolve()\n+            }\n+            'org.apache:groovy-json:1.0' {\n+                expectResolve()\n+            }\n+        }\n+\n+        then:\n+        run ':checkDeps'\n+        resolve.expectGraph {\n+            root(\":\", \":test:\") {\n+                module('org:a:1.0') {\n+                    edge('org.apache:groovy:1.0', 'org.apache:groovy:1.0')\n+                    edge('org.apache:groovy-json:1.0', 'org.apache:groovy-json:1.0')\n+                }\n+                module('org:b:1.0') {\n+                    // this is not quite right, as we should replace with 2 edges\n+                    // one option to do it is to construct \"adhoc\" modules, and select an adhoc target in \"prefer\"\n+                    // where this adhoc target would have dependencies on groovy-json and groovy\n+                    edge('org.apache:groovy-all:1.0', 'org.apache:groovy-json:1.0')\n+                }\n+            }\n+        }\n+    }\n+\n+    /**\n+     * This test highlights the case where published module declares a relocation. This is the drop-in replacement\n+     * for \"replacedBy\" rules when a module has been relocated, and that the publisher uses Gradle. There's the\n+     * ability to declare, in a newer version of the module, that it actually provides the same capability as an\n+     * older version published at different coordinates.\n+     *\n+     * This test also makes sure that the order in which dependencies are seen in the graph do not matter.\n+     */\n+    @RequiredFeatures(\n+        @RequiredFeature(feature = GradleMetadataResolveRunner.GRADLE_METADATA, value = \"true\")\n+    )\n+    @Unroll\n+    def \"published module can declare relocation (first in graph = #first, second in graph = #second)\"() {\n+        given:\n+        repository {\n+            'asm:asm:3.0' {\n+                variant('runtime') {\n+                    capability('asm', 'asm', '3.0')\n+                }\n+            }\n+            'org.ow2.asm:asm:4.0' {\n+                variant('runtime') {\n+                    capability('asm', 'asm', '4.0') // upgrades the asm capability\n+                    capability('org.ow2.asm', 'asm', '4.0') // self capability","path":"subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/capabilities/CapabilitiesUseCasesIntegrationTest.groovy","position":320,"original_position":320,"commit_id":"7e48dbd1d4d3ea5f4152ab3f5a053f8a9bc64fd4","original_commit_id":"7e48dbd1d4d3ea5f4152ab3f5a053f8a9bc64fd4","user":{"login":"bigdaz","id":179734,"avatar_url":"https://avatars3.githubusercontent.com/u/179734?v=4","gravatar_id":"","url":"https://api.github.com/users/bigdaz","html_url":"https://github.com/bigdaz","followers_url":"https://api.github.com/users/bigdaz/followers","following_url":"https://api.github.com/users/bigdaz/following{/other_user}","gists_url":"https://api.github.com/users/bigdaz/gists{/gist_id}","starred_url":"https://api.github.com/users/bigdaz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bigdaz/subscriptions","organizations_url":"https://api.github.com/users/bigdaz/orgs","repos_url":"https://api.github.com/users/bigdaz/repos","events_url":"https://api.github.com/users/bigdaz/events{/privacy}","received_events_url":"https://api.github.com/users/bigdaz/received_events","type":"User","site_admin":false},"body":"What is the 'self capability' required for?","created_at":"2018-03-13T02:35:30Z","updated_at":"2018-03-13T02:55:05Z","html_url":"https://github.com/gradle/gradle/pull/4639#discussion_r174002052","pull_request_url":"https://api.github.com/repos/gradle/gradle/pulls/4639","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/gradle/gradle/pulls/comments/174002052"},"html":{"href":"https://github.com/gradle/gradle/pull/4639#discussion_r174002052"},"pull_request":{"href":"https://api.github.com/repos/gradle/gradle/pulls/4639"}}},"pull_request":{"url":"https://api.github.com/repos/gradle/gradle/pulls/4639","id":173781614,"html_url":"https://github.com/gradle/gradle/pull/4639","diff_url":"https://github.com/gradle/gradle/pull/4639.diff","patch_url":"https://github.com/gradle/gradle/pull/4639.patch","issue_url":"https://api.github.com/repos/gradle/gradle/issues/4639","number":4639,"state":"open","locked":false,"title":"Introduce the concept of capabilities","user":{"login":"melix","id":316357,"avatar_url":"https://avatars2.githubusercontent.com/u/316357?v=4","gravatar_id":"","url":"https://api.github.com/users/melix","html_url":"https://github.com/melix","followers_url":"https://api.github.com/users/melix/followers","following_url":"https://api.github.com/users/melix/following{/other_user}","gists_url":"https://api.github.com/users/melix/gists{/gist_id}","starred_url":"https://api.github.com/users/melix/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/melix/subscriptions","organizations_url":"https://api.github.com/users/melix/orgs","repos_url":"https://api.github.com/users/melix/repos","events_url":"https://api.github.com/users/melix/events{/privacy}","received_events_url":"https://api.github.com/users/melix/received_events","type":"User","site_admin":false},"body":"Capabilities are a new first-class concept in Gradle, living along variants. They can be used to model\r\ncomponents which \"provide the same capability\". For example, two different implementations of the same\r\nAPI can provide the same capability, but it's illegal to have both on the dependency graph: the user\r\nmust choose between one of the two.\r\n\r\nThis commit introduces the ability to declare capabilities at the variant level, for now only using\r\ncomponent metadata rules. Capabilities participate in conflict resolution: as soon as we find that two\r\nmodules in the graph provide the same capability, we fail. There's currently no way to prefer one over\r\nthe other (this is going to be implemented in a subsequent commit). This means that if such a conflict\r\noccurs, the user must select the right module appropriately using component selection rules or module\r\nmetadata rules.\r\n","created_at":"2018-03-08T16:21:55Z","updated_at":"2018-03-13T02:55:05Z","closed_at":null,"merged_at":null,"merge_commit_sha":"284b5f026a3da10ef71702aa3d568270007ec633","assignee":{"login":"melix","id":316357,"avatar_url":"https://avatars2.githubusercontent.com/u/316357?v=4","gravatar_id":"","url":"https://api.github.com/users/melix","html_url":"https://github.com/melix","followers_url":"https://api.github.com/users/melix/followers","following_url":"https://api.github.com/users/melix/following{/other_user}","gists_url":"https://api.github.com/users/melix/gists{/gist_id}","starred_url":"https://api.github.com/users/melix/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/melix/subscriptions","organizations_url":"https://api.github.com/users/melix/orgs","repos_url":"https://api.github.com/users/melix/repos","events_url":"https://api.github.com/users/melix/events{/privacy}","received_events_url":"https://api.github.com/users/melix/received_events","type":"User","site_admin":false},"assignees":[{"login":"melix","id":316357,"avatar_url":"https://avatars2.githubusercontent.com/u/316357?v=4","gravatar_id":"","url":"https://api.github.com/users/melix","html_url":"https://github.com/melix","followers_url":"https://api.github.com/users/melix/followers","following_url":"https://api.github.com/users/melix/following{/other_user}","gists_url":"https://api.github.com/users/melix/gists{/gist_id}","starred_url":"https://api.github.com/users/melix/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/melix/subscriptions","organizations_url":"https://api.github.com/users/melix/orgs","repos_url":"https://api.github.com/users/melix/repos","events_url":"https://api.github.com/users/melix/events{/privacy}","received_events_url":"https://api.github.com/users/melix/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":289469033,"url":"https://api.github.com/repos/gradle/gradle/labels/from:member","name":"from:member","color":"0052cc","default":false},{"id":281294573,"url":"https://api.github.com/repos/gradle/gradle/labels/in:dependency-management","name":"in:dependency-management","color":"d4c5f9","default":false}],"milestone":{"url":"https://api.github.com/repos/gradle/gradle/milestones/60","html_url":"https://github.com/gradle/gradle/milestone/60","labels_url":"https://api.github.com/repos/gradle/gradle/milestones/60/labels","id":3014896,"number":60,"title":"4.7 RC1","description":"","creator":{"login":"jjohannes","id":1963746,"avatar_url":"https://avatars0.githubusercontent.com/u/1963746?v=4","gravatar_id":"","url":"https://api.github.com/users/jjohannes","html_url":"https://github.com/jjohannes","followers_url":"https://api.github.com/users/jjohannes/followers","following_url":"https://api.github.com/users/jjohannes/following{/other_user}","gists_url":"https://api.github.com/users/jjohannes/gists{/gist_id}","starred_url":"https://api.github.com/users/jjohannes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jjohannes/subscriptions","organizations_url":"https://api.github.com/users/jjohannes/orgs","repos_url":"https://api.github.com/users/jjohannes/repos","events_url":"https://api.github.com/users/jjohannes/events{/privacy}","received_events_url":"https://api.github.com/users/jjohannes/received_events","type":"User","site_admin":false},"open_issues":34,"closed_issues":74,"state":"open","created_at":"2018-01-05T10:44:13Z","updated_at":"2018-03-12T23:15:38Z","due_on":"2018-03-29T07:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/gradle/gradle/pulls/4639/commits","review_comments_url":"https://api.github.com/repos/gradle/gradle/pulls/4639/comments","review_comment_url":"https://api.github.com/repos/gradle/gradle/pulls/comments{/number}","comments_url":"https://api.github.com/repos/gradle/gradle/issues/4639/comments","statuses_url":"https://api.github.com/repos/gradle/gradle/statuses/7e48dbd1d4d3ea5f4152ab3f5a053f8a9bc64fd4","head":{"label":"gradle:cc/dependency-management/capabilities-take-3","ref":"cc/dependency-management/capabilities-take-3","sha":"7e48dbd1d4d3ea5f4152ab3f5a053f8a9bc64fd4","user":{"login":"gradle","id":124156,"avatar_url":"https://avatars2.githubusercontent.com/u/124156?v=4","gravatar_id":"","url":"https://api.github.com/users/gradle","html_url":"https://github.com/gradle","followers_url":"https://api.github.com/users/gradle/followers","following_url":"https://api.github.com/users/gradle/following{/other_user}","gists_url":"https://api.github.com/users/gradle/gists{/gist_id}","starred_url":"https://api.github.com/users/gradle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gradle/subscriptions","organizations_url":"https://api.github.com/users/gradle/orgs","repos_url":"https://api.github.com/users/gradle/repos","events_url":"https://api.github.com/users/gradle/events{/privacy}","received_events_url":"https://api.github.com/users/gradle/received_events","type":"Organization","site_admin":false},"repo":{"id":302322,"name":"gradle","full_name":"gradle/gradle","owner":{"login":"gradle","id":124156,"avatar_url":"https://avatars2.githubusercontent.com/u/124156?v=4","gravatar_id":"","url":"https://api.github.com/users/gradle","html_url":"https://github.com/gradle","followers_url":"https://api.github.com/users/gradle/followers","following_url":"https://api.github.com/users/gradle/following{/other_user}","gists_url":"https://api.github.com/users/gradle/gists{/gist_id}","starred_url":"https://api.github.com/users/gradle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gradle/subscriptions","organizations_url":"https://api.github.com/users/gradle/orgs","repos_url":"https://api.github.com/users/gradle/repos","events_url":"https://api.github.com/users/gradle/events{/privacy}","received_events_url":"https://api.github.com/users/gradle/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/gradle/gradle","description":"Adaptable, fast automation for all","fork":false,"url":"https://api.github.com/repos/gradle/gradle","forks_url":"https://api.github.com/repos/gradle/gradle/forks","keys_url":"https://api.github.com/repos/gradle/gradle/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gradle/gradle/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gradle/gradle/teams","hooks_url":"https://api.github.com/repos/gradle/gradle/hooks","issue_events_url":"https://api.github.com/repos/gradle/gradle/issues/events{/number}","events_url":"https://api.github.com/repos/gradle/gradle/events","assignees_url":"https://api.github.com/repos/gradle/gradle/assignees{/user}","branches_url":"https://api.github.com/repos/gradle/gradle/branches{/branch}","tags_url":"https://api.github.com/repos/gradle/gradle/tags","blobs_url":"https://api.github.com/repos/gradle/gradle/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gradle/gradle/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gradle/gradle/git/refs{/sha}","trees_url":"https://api.github.com/repos/gradle/gradle/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gradle/gradle/statuses/{sha}","languages_url":"https://api.github.com/repos/gradle/gradle/languages","stargazers_url":"https://api.github.com/repos/gradle/gradle/stargazers","contributors_url":"https://api.github.com/repos/gradle/gradle/contributors","subscribers_url":"https://api.github.com/repos/gradle/gradle/subscribers","subscription_url":"https://api.github.com/repos/gradle/gradle/subscription","commits_url":"https://api.github.com/repos/gradle/gradle/commits{/sha}","git_commits_url":"https://api.github.com/repos/gradle/gradle/git/commits{/sha}","comments_url":"https://api.github.com/repos/gradle/gradle/comments{/number}","issue_comment_url":"https://api.github.com/repos/gradle/gradle/issues/comments{/number}","contents_url":"https://api.github.com/repos/gradle/gradle/contents/{+path}","compare_url":"https://api.github.com/repos/gradle/gradle/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gradle/gradle/merges","archive_url":"https://api.github.com/repos/gradle/gradle/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gradle/gradle/downloads","issues_url":"https://api.github.com/repos/gradle/gradle/issues{/number}","pulls_url":"https://api.github.com/repos/gradle/gradle/pulls{/number}","milestones_url":"https://api.github.com/repos/gradle/gradle/milestones{/number}","notifications_url":"https://api.github.com/repos/gradle/gradle/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gradle/gradle/labels{/name}","releases_url":"https://api.github.com/repos/gradle/gradle/releases{/id}","deployments_url":"https://api.github.com/repos/gradle/gradle/deployments","created_at":"2009-09-09T18:27:19Z","updated_at":"2018-03-13T01:23:23Z","pushed_at":"2018-03-13T02:17:28Z","git_url":"git://github.com/gradle/gradle.git","ssh_url":"git@github.com:gradle/gradle.git","clone_url":"https://github.com/gradle/gradle.git","svn_url":"https://github.com/gradle/gradle","homepage":"https://gradle.org","size":203883,"stargazers_count":6425,"watchers_count":6425,"language":"Java","has_issues":true,"has_projects":false,"has_downloads":false,"has_wiki":true,"has_pages":false,"forks_count":2102,"mirror_url":null,"archived":false,"open_issues_count":974,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":2102,"open_issues":974,"watchers":6425,"default_branch":"master"}},"base":{"label":"gradle:master","ref":"master","sha":"c9ace6ff80e8bab942b9cf8405f417176669b1a4","user":{"login":"gradle","id":124156,"avatar_url":"https://avatars2.githubusercontent.com/u/124156?v=4","gravatar_id":"","url":"https://api.github.com/users/gradle","html_url":"https://github.com/gradle","followers_url":"https://api.github.com/users/gradle/followers","following_url":"https://api.github.com/users/gradle/following{/other_user}","gists_url":"https://api.github.com/users/gradle/gists{/gist_id}","starred_url":"https://api.github.com/users/gradle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gradle/subscriptions","organizations_url":"https://api.github.com/users/gradle/orgs","repos_url":"https://api.github.com/users/gradle/repos","events_url":"https://api.github.com/users/gradle/events{/privacy}","received_events_url":"https://api.github.com/users/gradle/received_events","type":"Organization","site_admin":false},"repo":{"id":302322,"name":"gradle","full_name":"gradle/gradle","owner":{"login":"gradle","id":124156,"avatar_url":"https://avatars2.githubusercontent.com/u/124156?v=4","gravatar_id":"","url":"https://api.github.com/users/gradle","html_url":"https://github.com/gradle","followers_url":"https://api.github.com/users/gradle/followers","following_url":"https://api.github.com/users/gradle/following{/other_user}","gists_url":"https://api.github.com/users/gradle/gists{/gist_id}","starred_url":"https://api.github.com/users/gradle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gradle/subscriptions","organizations_url":"https://api.github.com/users/gradle/orgs","repos_url":"https://api.github.com/users/gradle/repos","events_url":"https://api.github.com/users/gradle/events{/privacy}","received_events_url":"https://api.github.com/users/gradle/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/gradle/gradle","description":"Adaptable, fast automation for all","fork":false,"url":"https://api.github.com/repos/gradle/gradle","forks_url":"https://api.github.com/repos/gradle/gradle/forks","keys_url":"https://api.github.com/repos/gradle/gradle/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gradle/gradle/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gradle/gradle/teams","hooks_url":"https://api.github.com/repos/gradle/gradle/hooks","issue_events_url":"https://api.github.com/repos/gradle/gradle/issues/events{/number}","events_url":"https://api.github.com/repos/gradle/gradle/events","assignees_url":"https://api.github.com/repos/gradle/gradle/assignees{/user}","branches_url":"https://api.github.com/repos/gradle/gradle/branches{/branch}","tags_url":"https://api.github.com/repos/gradle/gradle/tags","blobs_url":"https://api.github.com/repos/gradle/gradle/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gradle/gradle/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gradle/gradle/git/refs{/sha}","trees_url":"https://api.github.com/repos/gradle/gradle/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gradle/gradle/statuses/{sha}","languages_url":"https://api.github.com/repos/gradle/gradle/languages","stargazers_url":"https://api.github.com/repos/gradle/gradle/stargazers","contributors_url":"https://api.github.com/repos/gradle/gradle/contributors","subscribers_url":"https://api.github.com/repos/gradle/gradle/subscribers","subscription_url":"https://api.github.com/repos/gradle/gradle/subscription","commits_url":"https://api.github.com/repos/gradle/gradle/commits{/sha}","git_commits_url":"https://api.github.com/repos/gradle/gradle/git/commits{/sha}","comments_url":"https://api.github.com/repos/gradle/gradle/comments{/number}","issue_comment_url":"https://api.github.com/repos/gradle/gradle/issues/comments{/number}","contents_url":"https://api.github.com/repos/gradle/gradle/contents/{+path}","compare_url":"https://api.github.com/repos/gradle/gradle/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gradle/gradle/merges","archive_url":"https://api.github.com/repos/gradle/gradle/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gradle/gradle/downloads","issues_url":"https://api.github.com/repos/gradle/gradle/issues{/number}","pulls_url":"https://api.github.com/repos/gradle/gradle/pulls{/number}","milestones_url":"https://api.github.com/repos/gradle/gradle/milestones{/number}","notifications_url":"https://api.github.com/repos/gradle/gradle/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gradle/gradle/labels{/name}","releases_url":"https://api.github.com/repos/gradle/gradle/releases{/id}","deployments_url":"https://api.github.com/repos/gradle/gradle/deployments","created_at":"2009-09-09T18:27:19Z","updated_at":"2018-03-13T01:23:23Z","pushed_at":"2018-03-13T02:17:28Z","git_url":"git://github.com/gradle/gradle.git","ssh_url":"git@github.com:gradle/gradle.git","clone_url":"https://github.com/gradle/gradle.git","svn_url":"https://github.com/gradle/gradle","homepage":"https://gradle.org","size":203883,"stargazers_count":6425,"watchers_count":6425,"language":"Java","has_issues":true,"has_projects":false,"has_downloads":false,"has_wiki":true,"has_pages":false,"forks_count":2102,"mirror_url":null,"archived":false,"open_issues_count":974,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":2102,"open_issues":974,"watchers":6425,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/gradle/gradle/pulls/4639"},"html":{"href":"https://github.com/gradle/gradle/pull/4639"},"issue":{"href":"https://api.github.com/repos/gradle/gradle/issues/4639"},"comments":{"href":"https://api.github.com/repos/gradle/gradle/issues/4639/comments"},"review_comments":{"href":"https://api.github.com/repos/gradle/gradle/pulls/4639/comments"},"review_comment":{"href":"https://api.github.com/repos/gradle/gradle/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/gradle/gradle/pulls/4639/commits"},"statuses":{"href":"https://api.github.com/repos/gradle/gradle/statuses/7e48dbd1d4d3ea5f4152ab3f5a053f8a9bc64fd4"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"bigdaz"}}