d6a86f
From 34b37637bd469621bb3eadfdf5fb856a806722df Mon Sep 17 00:00:00 2001
d6a86f
From: Michael Simacek <msimacek@redhat.com>
d6a86f
Date: Mon, 2 Oct 2017 12:01:09 +0300
d6a86f
Subject: [PATCH] Port to Gradle 4.2
d6a86f
d6a86f
---
d6a86f
 libs/gradle-core-api/pom.xml                       |  32 ++++++
d6a86f
 libs/gradle-logging/pom.xml                        |  32 ++++++
d6a86f
 libs/gradle-model-core/pom.xml                     |  32 ++++++
d6a86f
 libs/pom.xml                                       |   3 +
d6a86f
 xmvn-connector-gradle/pom.xml                      |  15 +++
d6a86f
 .../xmvn/connector/gradle/GradleResolver.java      | 119 ++++++++++++++-------
d6a86f
 .../xmvn/connector/gradle/XMvnGradlePlugin.java    |  16 +--
d6a86f
 .../xmvn/connector/gradle/XMvnInstallTask.java     |  22 +++-
d6a86f
 xmvn-parent/pom.xml                                |  17 ++-
d6a86f
 9 files changed, 235 insertions(+), 53 deletions(-)
d6a86f
 create mode 100644 libs/gradle-core-api/pom.xml
d6a86f
 create mode 100644 libs/gradle-logging/pom.xml
d6a86f
 create mode 100644 libs/gradle-model-core/pom.xml
d6a86f
d6a86f
diff --git a/libs/gradle-core-api/pom.xml b/libs/gradle-core-api/pom.xml
d6a86f
new file mode 100644
d6a86f
index 00000000..7b3d68d5
d6a86f
--- /dev/null
d6a86f
+++ b/libs/gradle-core-api/pom.xml
d6a86f
@@ -0,0 +1,32 @@
d6a86f
+
d6a86f
+
d6a86f
+ ! Copyright (c) 2016-2017 Red Hat, Inc.
d6a86f
+ !
d6a86f
+ ! Licensed under the Apache License, Version 2.0 (the "License");
d6a86f
+ ! you may not use this file except in compliance with the License.
d6a86f
+ ! You may obtain a copy of the License at
d6a86f
+ !
d6a86f
+ !     http://www.apache.org/licenses/LICENSE-2.0
d6a86f
+ !
d6a86f
+ ! Unless required by applicable law or agreed to in writing, software
d6a86f
+ ! distributed under the License is distributed on an "AS IS" BASIS,
d6a86f
+ ! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
d6a86f
+ ! See the License for the specific language governing permissions and
d6a86f
+ ! limitations under the License.
d6a86f
+ `-->
d6a86f
+
d6a86f
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
d6a86f
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
d6a86f
+                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
d6a86f
+  <modelVersion>4.0.0</modelVersion>
d6a86f
+  <parent>
d6a86f
+    <groupId>org.fedoraproject.xmvn</groupId>
d6a86f
+    <artifactId>libs</artifactId>
d6a86f
+    <version>3.0.0</version>
d6a86f
+    <relativePath>..</relativePath>
d6a86f
+  </parent>
d6a86f
+  <groupId>org.gradle</groupId>
d6a86f
+  <artifactId>gradle-core-api</artifactId>
d6a86f
+  <version>${gradleVersion}</version>
d6a86f
+  <name>Gradle core API module</name>
d6a86f
+</project>
d6a86f
diff --git a/libs/gradle-logging/pom.xml b/libs/gradle-logging/pom.xml
d6a86f
new file mode 100644
d6a86f
index 00000000..d2dec7c1
d6a86f
--- /dev/null
d6a86f
+++ b/libs/gradle-logging/pom.xml
d6a86f
@@ -0,0 +1,32 @@
d6a86f
+
d6a86f
+
d6a86f
+ ! Copyright (c) 2016-2017 Red Hat, Inc.
d6a86f
+ !
d6a86f
+ ! Licensed under the Apache License, Version 2.0 (the "License");
d6a86f
+ ! you may not use this file except in compliance with the License.
d6a86f
+ ! You may obtain a copy of the License at
d6a86f
+ !
d6a86f
+ !     http://www.apache.org/licenses/LICENSE-2.0
d6a86f
+ !
d6a86f
+ ! Unless required by applicable law or agreed to in writing, software
d6a86f
+ ! distributed under the License is distributed on an "AS IS" BASIS,
d6a86f
+ ! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
d6a86f
+ ! See the License for the specific language governing permissions and
d6a86f
+ ! limitations under the License.
d6a86f
+ `-->
d6a86f
+
d6a86f
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
d6a86f
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
d6a86f
+                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
d6a86f
+  <modelVersion>4.0.0</modelVersion>
d6a86f
+  <parent>
d6a86f
+    <groupId>org.fedoraproject.xmvn</groupId>
d6a86f
+    <artifactId>libs</artifactId>
d6a86f
+    <version>3.0.0</version>
d6a86f
+    <relativePath>..</relativePath>
d6a86f
+  </parent>
d6a86f
+  <groupId>org.gradle</groupId>
d6a86f
+  <artifactId>gradle-logging</artifactId>
d6a86f
+  <version>${gradleVersion}</version>
d6a86f
+  <name>Gradle logging module</name>
d6a86f
+</project>
d6a86f
diff --git a/libs/gradle-model-core/pom.xml b/libs/gradle-model-core/pom.xml
d6a86f
new file mode 100644
d6a86f
index 00000000..f841b960
d6a86f
--- /dev/null
d6a86f
+++ b/libs/gradle-model-core/pom.xml
d6a86f
@@ -0,0 +1,32 @@
d6a86f
+
d6a86f
+
d6a86f
+ ! Copyright (c) 2016-2017 Red Hat, Inc.
d6a86f
+ !
d6a86f
+ ! Licensed under the Apache License, Version 2.0 (the "License");
d6a86f
+ ! you may not use this file except in compliance with the License.
d6a86f
+ ! You may obtain a copy of the License at
d6a86f
+ !
d6a86f
+ !     http://www.apache.org/licenses/LICENSE-2.0
d6a86f
+ !
d6a86f
+ ! Unless required by applicable law or agreed to in writing, software
d6a86f
+ ! distributed under the License is distributed on an "AS IS" BASIS,
d6a86f
+ ! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
d6a86f
+ ! See the License for the specific language governing permissions and
d6a86f
+ ! limitations under the License.
d6a86f
+ `-->
d6a86f
+
d6a86f
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
d6a86f
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
d6a86f
+                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
d6a86f
+  <modelVersion>4.0.0</modelVersion>
d6a86f
+  <parent>
d6a86f
+    <groupId>org.fedoraproject.xmvn</groupId>
d6a86f
+    <artifactId>libs</artifactId>
d6a86f
+    <version>3.0.0</version>
d6a86f
+    <relativePath>..</relativePath>
d6a86f
+  </parent>
d6a86f
+  <groupId>org.gradle</groupId>
d6a86f
+  <artifactId>gradle-model-core</artifactId>
d6a86f
+  <version>${gradleVersion}</version>
d6a86f
+  <name>Gradle model-core module</name>
d6a86f
+</project>
d6a86f
diff --git a/libs/pom.xml b/libs/pom.xml
d6a86f
index 2b31c5d0..fc29e359 100644
d6a86f
--- a/libs/pom.xml
d6a86f
+++ b/libs/pom.xml
d6a86f
@@ -37,8 +37,11 @@
d6a86f
     <module>gradle-base-services</module>
d6a86f
     <module>gradle-base-services-groovy</module>
d6a86f
     <module>gradle-core</module>
d6a86f
+    <module>gradle-core-api</module>
d6a86f
+    <module>gradle-model-core</module>
d6a86f
     <module>gradle-dependency-management</module>
d6a86f
     <module>gradle-resources</module>
d6a86f
+    <module>gradle-logging</module>
d6a86f
   </modules>
d6a86f
   <dependencies>
d6a86f
     <dependency>
d6a86f
diff --git a/xmvn-connector-gradle/pom.xml b/xmvn-connector-gradle/pom.xml
d6a86f
index b433e5dd..f18a285e 100644
d6a86f
--- a/xmvn-connector-gradle/pom.xml
d6a86f
+++ b/xmvn-connector-gradle/pom.xml
d6a86f
@@ -54,11 +54,21 @@
d6a86f
     </dependency>
d6a86f
     <dependency>
d6a86f
       <groupId>org.gradle</groupId>
d6a86f
+      <artifactId>gradle-core-api</artifactId>
d6a86f
+      <scope>provided</scope>
d6a86f
+    </dependency>
d6a86f
+    <dependency>
d6a86f
+      <groupId>org.gradle</groupId>
d6a86f
       <artifactId>gradle-core</artifactId>
d6a86f
       <scope>provided</scope>
d6a86f
     </dependency>
d6a86f
     <dependency>
d6a86f
       <groupId>org.gradle</groupId>
d6a86f
+      <artifactId>gradle-model-core</artifactId>
d6a86f
+      <scope>provided</scope>
d6a86f
+    </dependency>
d6a86f
+    <dependency>
d6a86f
+      <groupId>org.gradle</groupId>
d6a86f
       <artifactId>gradle-dependency-management</artifactId>
d6a86f
       <scope>provided</scope>
d6a86f
     </dependency>
d6a86f
@@ -68,6 +78,11 @@
d6a86f
       <scope>provided</scope>
d6a86f
     </dependency>
d6a86f
     <dependency>
d6a86f
+      <groupId>org.gradle</groupId>
d6a86f
+      <artifactId>gradle-logging</artifactId>
d6a86f
+      <scope>provided</scope>
d6a86f
+    </dependency>
d6a86f
+    <dependency>
d6a86f
       <groupId>org.apache.ivy</groupId>
d6a86f
       <artifactId>ivy</artifactId>
d6a86f
       <scope>provided</scope>
d6a86f
diff --git a/xmvn-connector-gradle/src/main/java/org/fedoraproject/xmvn/connector/gradle/GradleResolver.java b/xmvn-connector-gradle/src/main/java/org/fedoraproject/xmvn/connector/gradle/GradleResolver.java
d6a86f
index a81c5bc0..6305aa86 100644
d6a86f
--- a/xmvn-connector-gradle/src/main/java/org/fedoraproject/xmvn/connector/gradle/GradleResolver.java
d6a86f
+++ b/xmvn-connector-gradle/src/main/java/org/fedoraproject/xmvn/connector/gradle/GradleResolver.java
d6a86f
@@ -18,41 +18,47 @@ package org.fedoraproject.xmvn.connector.gradle;
d6a86f
 import java.nio.file.Path;
d6a86f
 import java.util.Collections;
d6a86f
 import java.util.LinkedHashSet;
d6a86f
+import java.util.Map;
d6a86f
 import java.util.Set;
d6a86f
 
d6a86f
+import org.gradle.api.artifacts.ComponentMetadataSupplier;
d6a86f
 import org.gradle.api.artifacts.ModuleVersionIdentifier;
d6a86f
+import org.gradle.api.artifacts.component.ComponentArtifactIdentifier;
d6a86f
 import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
d6a86f
+import org.gradle.api.internal.artifacts.ImmutableModuleIdentifierFactory;
d6a86f
 import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ConfiguredModuleComponentRepository;
d6a86f
 import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ModuleComponentRepositoryAccess;
d6a86f
 import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.parser.DescriptorParseContext;
d6a86f
-import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.parser.GradlePomModuleDescriptorParser;
d6a86f
 import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.parser.MetaDataParser;
d6a86f
-import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.DefaultVersionComparator;
d6a86f
-import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.DefaultVersionSelectorScheme;
d6a86f
+import org.gradle.api.internal.artifacts.ivyservice.resolveengine.artifact.ResolvableArtifact;
d6a86f
 import org.gradle.api.internal.artifacts.repositories.AbstractArtifactRepository;
d6a86f
 import org.gradle.api.internal.artifacts.repositories.ResolutionAwareRepository;
d6a86f
+import org.gradle.api.internal.artifacts.repositories.resolver.MetadataFetchingCost;
d6a86f
 import org.gradle.api.internal.component.ArtifactType;
d6a86f
-import org.gradle.internal.component.external.model.DefaultMavenModuleResolveMetaData;
d6a86f
-import org.gradle.internal.component.external.model.DefaultModuleComponentArtifactMetaData;
d6a86f
-import org.gradle.internal.component.external.model.ModuleComponentResolveMetaData;
d6a86f
-import org.gradle.internal.component.external.model.MutableModuleComponentResolveMetaData;
d6a86f
-import org.gradle.internal.component.model.ComponentArtifactMetaData;
d6a86f
+import org.gradle.internal.component.external.model.DefaultModuleComponentArtifactMetadata;
d6a86f
+import org.gradle.internal.component.external.model.DefaultMutableMavenModuleResolveMetadata;
d6a86f
+import org.gradle.internal.component.external.model.FixedComponentArtifacts;
d6a86f
+import org.gradle.internal.component.external.model.ModuleComponentArtifactMetadata;
d6a86f
+import org.gradle.internal.component.external.model.ModuleComponentResolveMetadata;
d6a86f
+import org.gradle.internal.component.external.model.MutableMavenModuleResolveMetadata;
d6a86f
+import org.gradle.internal.component.external.model.MutableModuleComponentResolveMetadata;
d6a86f
+import org.gradle.internal.component.model.ComponentArtifactMetadata;
d6a86f
 import org.gradle.internal.component.model.ComponentOverrideMetadata;
d6a86f
-import org.gradle.internal.component.model.ComponentResolveMetaData;
d6a86f
-import org.gradle.internal.component.model.ComponentUsage;
d6a86f
+import org.gradle.internal.component.model.ComponentResolveMetadata;
d6a86f
 import org.gradle.internal.component.model.DefaultIvyArtifactName;
d6a86f
-import org.gradle.internal.component.model.DependencyMetaData;
d6a86f
+import org.gradle.internal.component.model.DependencyMetadata;
d6a86f
 import org.gradle.internal.component.model.IvyArtifactName;
d6a86f
 import org.gradle.internal.component.model.ModuleSource;
d6a86f
 import org.gradle.internal.resolve.ArtifactResolveException;
d6a86f
 import org.gradle.internal.resolve.ModuleVersionResolveException;
d6a86f
 import org.gradle.internal.resolve.result.BuildableArtifactResolveResult;
d6a86f
 import org.gradle.internal.resolve.result.BuildableArtifactSetResolveResult;
d6a86f
+import org.gradle.internal.resolve.result.BuildableComponentArtifactsResolveResult;
d6a86f
 import org.gradle.internal.resolve.result.BuildableModuleComponentMetaDataResolveResult;
d6a86f
 import org.gradle.internal.resolve.result.BuildableModuleVersionListingResolveResult;
d6a86f
-import org.gradle.internal.resource.local.DefaultLocallyAvailableExternalResource;
d6a86f
-import org.gradle.internal.resource.local.DefaultLocallyAvailableResource;
d6a86f
+import org.gradle.internal.resource.local.FileResourceRepository;
d6a86f
 import org.gradle.internal.resource.local.LocallyAvailableExternalResource;
d6a86f
+import org.gradle.internal.resource.metadata.DefaultExternalResourceMetaData;
d6a86f
 import org.slf4j.Logger;
d6a86f
 import org.slf4j.LoggerFactory;
d6a86f
 
d6a86f
@@ -72,6 +78,21 @@ public class GradleResolver
d6a86f
     implements ResolutionAwareRepository, ConfiguredModuleComponentRepository, ModuleComponentRepositoryAccess,
d6a86f
     DescriptorParseContext
d6a86f
 {
d6a86f
+    public GradleResolver( MetaDataParser<MutableMavenModuleResolveMetadata> pomParser,
d6a86f
+                           ImmutableModuleIdentifierFactory moduleIdentifierFactory,
d6a86f
+                           FileResourceRepository fileRepository )
d6a86f
+    {
d6a86f
+        this.pomParser = pomParser;
d6a86f
+        this.moduleIdentifierFactory = moduleIdentifierFactory;
d6a86f
+        this.fileRepository = fileRepository;
d6a86f
+    }
d6a86f
+
d6a86f
+    private MetaDataParser<MutableMavenModuleResolveMetadata> pomParser;
d6a86f
+
d6a86f
+    private ImmutableModuleIdentifierFactory moduleIdentifierFactory;
d6a86f
+
d6a86f
+    private FileResourceRepository fileRepository;
d6a86f
+
d6a86f
     private final Logger logger = LoggerFactory.getLogger( GradleResolver.class );
d6a86f
 
d6a86f
     static class LazyLocatorProvider
d6a86f
@@ -135,17 +156,17 @@ public class GradleResolver
d6a86f
     }
d6a86f
 
d6a86f
     @Override
d6a86f
-    public void listModuleVersions( DependencyMetaData arg0, BuildableModuleVersionListingResolveResult arg1 )
d6a86f
+    public void listModuleVersions( DependencyMetadata arg0, BuildableModuleVersionListingResolveResult arg1 )
d6a86f
     {
d6a86f
         logger.debug( "listModuleVersions() called, but it is NOT IMPLEMENTED" );
d6a86f
     }
d6a86f
 
d6a86f
     @Override
d6a86f
-    public void resolveArtifact( ComponentArtifactMetaData artifact, ModuleSource module,
d6a86f
+    public void resolveArtifact( ComponentArtifactMetadata artifact, ModuleSource module,
d6a86f
                                  BuildableArtifactResolveResult result )
d6a86f
     {
d6a86f
         ModuleVersionIdentifier moduleId =
d6a86f
-            ( (DefaultModuleComponentArtifactMetaData) artifact ).toArtifactIdentifier().getModuleVersionIdentifier();
d6a86f
+            ( (DefaultModuleComponentArtifactMetadata) artifact ).toArtifactIdentifier().getModuleVersionIdentifier();
d6a86f
         String groupId = moduleId.getGroup();
d6a86f
         String artifactId = artifact.getName().getName();
d6a86f
         String extension = artifact.getName().getExtension();
d6a86f
@@ -180,11 +201,9 @@ public class GradleResolver
d6a86f
         {
d6a86f
             logger.debug( "Found Maven POM: {}", pomPath );
d6a86f
 
d6a86f
-            MetaDataParser<DefaultMavenModuleResolveMetaData> parser =
d6a86f
-                new GradlePomModuleDescriptorParser( new DefaultVersionSelectorScheme( new DefaultVersionComparator() ) );
d6a86f
-            MutableModuleComponentResolveMetaData metaData = parser.parseMetaData( this, pomPath.toFile() );
d6a86f
+            MutableModuleComponentResolveMetadata metaData = pomParser.parseMetaData( this, pomPath.toFile() );
d6a86f
 
d6a86f
-            result.resolved( metaData );
d6a86f
+            result.resolved( metaData.asImmutable() );
d6a86f
             return;
d6a86f
         }
d6a86f
         else
d6a86f
@@ -204,9 +223,11 @@ public class GradleResolver
d6a86f
                 if ( path != null )
d6a86f
                 {
d6a86f
                     logger.debug( "Artifact {} found, returning minimal model", artifact3 );
d6a86f
-                    MutableModuleComponentResolveMetaData metaData =
d6a86f
-                        new DefaultMavenModuleResolveMetaData( id, request.getArtifacts() );
d6a86f
-                    result.resolved( metaData );
d6a86f
+                    ModuleVersionIdentifier mvi =
d6a86f
+                        moduleIdentifierFactory.moduleWithVersion( id.getGroup(), id.getModule(), id.getVersion() );
d6a86f
+                    MutableModuleComponentResolveMetadata metaData =
d6a86f
+                        new DefaultMutableMavenModuleResolveMetadata( mvi, id, request.getArtifacts() );
d6a86f
+                    result.resolved( metaData.asImmutable() );
d6a86f
                     return;
d6a86f
                 }
d6a86f
             }
d6a86f
@@ -224,24 +245,15 @@ public class GradleResolver
d6a86f
 
d6a86f
         if ( artifactSet.isEmpty() )
d6a86f
         {
d6a86f
-            artifactSet.add( new DefaultIvyArtifactName( id.getModule(), "jar", "jar",
d6a86f
-                                                         Collections.<String, String>emptyMap() ) );
d6a86f
+            artifactSet.add( new DefaultIvyArtifactName( id.getModule(), "jar", "jar", null ) );
d6a86f
         }
d6a86f
 
d6a86f
         return artifactSet;
d6a86f
     }
d6a86f
 
d6a86f
     @Override
d6a86f
-    public void resolveModuleArtifacts( ComponentResolveMetaData component, ComponentUsage usage,
d6a86f
-                                        BuildableArtifactSetResolveResult result )
d6a86f
-    {
d6a86f
-        result.resolved( Collections.singleton( ( (ModuleComponentResolveMetaData) component ).artifact( "jar", "jar",
d6a86f
-                                                                                                         null ) ) );
d6a86f
-    }
d6a86f
-
d6a86f
-    @Override
d6a86f
-    public void resolveModuleArtifacts( ComponentResolveMetaData component, ArtifactType type,
d6a86f
-                                        BuildableArtifactSetResolveResult result )
d6a86f
+    public void resolveArtifactsWithType( ComponentResolveMetadata component, ArtifactType type,
d6a86f
+                                          BuildableArtifactSetResolveResult result )
d6a86f
     {
d6a86f
         if ( type != ArtifactType.MAVEN_POM )
d6a86f
         {
d6a86f
@@ -250,15 +262,22 @@ public class GradleResolver
d6a86f
             return;
d6a86f
         }
d6a86f
 
d6a86f
-        ModuleComponentResolveMetaData metaData = (ModuleComponentResolveMetaData) component;
d6a86f
-        ModuleComponentIdentifier id = metaData.getComponentId();
d6a86f
+        ModuleComponentIdentifier id = (ModuleComponentIdentifier) component.getComponentId();
d6a86f
         DefaultIvyArtifactName name = new DefaultIvyArtifactName( id.getModule(), "pom", "pom" );
d6a86f
-        DefaultModuleComponentArtifactMetaData resolvedMetaData =
d6a86f
-            new DefaultModuleComponentArtifactMetaData( id, name );
d6a86f
+        DefaultModuleComponentArtifactMetadata resolvedMetaData =
d6a86f
+            new DefaultModuleComponentArtifactMetadata( id, name );
d6a86f
         result.resolved( Collections.singleton( resolvedMetaData ) );
d6a86f
     }
d6a86f
 
d6a86f
     @Override
d6a86f
+    public void resolveArtifacts( ComponentResolveMetadata component, BuildableComponentArtifactsResolveResult result )
d6a86f
+    {
d6a86f
+        ModuleComponentArtifactMetadata artifact =
d6a86f
+            ( (ModuleComponentResolveMetadata) component ).artifact( "jar", "jar", null );
d6a86f
+        result.resolved( new FixedComponentArtifacts( Collections.singleton( artifact ) ) );
d6a86f
+    }
d6a86f
+
d6a86f
+    @Override
d6a86f
     public LocallyAvailableExternalResource getMetaDataArtifact( ModuleComponentIdentifier id, ArtifactType type )
d6a86f
     {
d6a86f
         Path pomPath = resolve( new DefaultArtifact( id.getGroup(), id.getModule(), "pom", id.getVersion() ) );
d6a86f
@@ -266,7 +285,25 @@ public class GradleResolver
d6a86f
         if ( pomPath == null )
d6a86f
             return null;
d6a86f
 
d6a86f
-        return new DefaultLocallyAvailableExternalResource( pomPath.toUri(),
d6a86f
-                                                            new DefaultLocallyAvailableResource( pomPath.toFile() ) );
d6a86f
+        DefaultExternalResourceMetaData metadata = new DefaultExternalResourceMetaData( pomPath.toUri(), 0, 0 );
d6a86f
+        return fileRepository.resource( pomPath.toFile(), pomPath.toUri(), metadata );
d6a86f
+    }
d6a86f
+
d6a86f
+    @Override
d6a86f
+    public ComponentMetadataSupplier createMetadataSupplier()
d6a86f
+    {
d6a86f
+        return null;
d6a86f
+    }
d6a86f
+
d6a86f
+    @Override
d6a86f
+    public Map<ComponentArtifactIdentifier, ResolvableArtifact> getArtifactCache()
d6a86f
+    {
d6a86f
+        return Collections.emptyMap();
d6a86f
+    }
d6a86f
+
d6a86f
+    @Override
d6a86f
+    public MetadataFetchingCost estimateMetadataFetchingCost( ModuleComponentIdentifier arg0 )
d6a86f
+    {
d6a86f
+        return MetadataFetchingCost.CHEAP;
d6a86f
     }
d6a86f
 }
d6a86f
diff --git a/xmvn-connector-gradle/src/main/java/org/fedoraproject/xmvn/connector/gradle/XMvnGradlePlugin.java b/xmvn-connector-gradle/src/main/java/org/fedoraproject/xmvn/connector/gradle/XMvnGradlePlugin.java
d6a86f
index 2646f098..c3250e3c 100644
d6a86f
--- a/xmvn-connector-gradle/src/main/java/org/fedoraproject/xmvn/connector/gradle/XMvnGradlePlugin.java
d6a86f
+++ b/xmvn-connector-gradle/src/main/java/org/fedoraproject/xmvn/connector/gradle/XMvnGradlePlugin.java
d6a86f
@@ -15,9 +15,11 @@
d6a86f
  */
d6a86f
 package org.fedoraproject.xmvn.connector.gradle;
d6a86f
 
d6a86f
+import groovy.lang.Closure;
d6a86f
+import groovy.lang.GroovyShell;
d6a86f
 import org.gradle.api.Plugin;
d6a86f
 import org.gradle.api.Task;
d6a86f
-import org.gradle.api.artifacts.repositories.ArtifactRepository;
d6a86f
+import org.gradle.api.artifacts.dsl.RepositoryHandler;
d6a86f
 import org.gradle.api.invocation.Gradle;
d6a86f
 
d6a86f
 /**
d6a86f
@@ -26,15 +28,17 @@ import org.gradle.api.invocation.Gradle;
d6a86f
 public class XMvnGradlePlugin
d6a86f
     implements Plugin<Gradle>
d6a86f
 {
d6a86f
+    private void configureRepositories( RepositoryHandler repositories )
d6a86f
+    {
d6a86f
+        repositories.configure( (Closure) new GroovyShell().evaluate( "{ it -> xmvn() }" ) );
d6a86f
+    }
d6a86f
+
d6a86f
     @Override
d6a86f
     public void apply( Gradle gradle )
d6a86f
     {
d6a86f
-        ArtifactRepository repo = new GradleResolver();
d6a86f
-        repo.setName( "xmvn" );
d6a86f
-
d6a86f
         gradle.allprojects( project -> {
d6a86f
-            project.getRepositories().addFirst( repo );
d6a86f
-            project.getBuildscript().getRepositories().addFirst( repo );
d6a86f
+            configureRepositories( project.getRepositories() );
d6a86f
+            configureRepositories( project.getBuildscript().getRepositories() );
d6a86f
 
d6a86f
             Task upload = project.getTasks().create( "xmvnInstall", XMvnInstallTask.class );
d6a86f
             upload.setDescription( "Installs all artifacts through XMvn" );
d6a86f
diff --git a/xmvn-connector-gradle/src/main/java/org/fedoraproject/xmvn/connector/gradle/XMvnInstallTask.java b/xmvn-connector-gradle/src/main/java/org/fedoraproject/xmvn/connector/gradle/XMvnInstallTask.java
d6a86f
index 196f4a5b..07905f1f 100644
d6a86f
--- a/xmvn-connector-gradle/src/main/java/org/fedoraproject/xmvn/connector/gradle/XMvnInstallTask.java
d6a86f
+++ b/xmvn-connector-gradle/src/main/java/org/fedoraproject/xmvn/connector/gradle/XMvnInstallTask.java
d6a86f
@@ -17,6 +17,7 @@ package org.fedoraproject.xmvn.connector.gradle;
d6a86f
 
d6a86f
 import java.nio.file.Files;
d6a86f
 import java.util.Collections;
d6a86f
+import java.util.HashSet;
d6a86f
 import java.util.List;
d6a86f
 import java.util.Set;
d6a86f
 import java.util.stream.Collectors;
d6a86f
@@ -32,7 +33,7 @@ import org.gradle.api.artifacts.PublishArtifact;
d6a86f
 import org.gradle.api.artifacts.PublishException;
d6a86f
 import org.gradle.api.component.SoftwareComponent;
d6a86f
 import org.gradle.api.internal.component.SoftwareComponentInternal;
d6a86f
-import org.gradle.api.internal.component.Usage;
d6a86f
+import org.gradle.api.internal.component.UsageContext;
d6a86f
 import org.gradle.api.tasks.TaskAction;
d6a86f
 
d6a86f
 import org.fedoraproject.xmvn.artifact.Artifact;
d6a86f
@@ -83,7 +84,7 @@ class XMvnInstallTask
d6a86f
             Project dependencyProject = projectDependency.getDependencyProject();
d6a86f
             Stream<SoftwareComponent> components = dependencyProject.getComponents().stream();
d6a86f
             Stream<SoftwareComponentInternal> internalComponents = components.map( c -> (SoftwareComponentInternal) c );
d6a86f
-            Stream<Usage> usages = internalComponents.flatMap( ic -> ic.getUsages().stream() );
d6a86f
+            Stream<UsageContext> usages = internalComponents.flatMap( ic -> ic.getUsages().stream() );
d6a86f
             Stream<PublishArtifact> publishArtifacts = usages.flatMap( usage -> usage.getArtifacts().stream() );
d6a86f
             Stream<Artifact> artifacts = publishArtifacts.map( pa -> getPublishArtifact( dependencyProject, pa ) );
d6a86f
             return artifacts.collect( Collectors.toList() );
d6a86f
@@ -144,7 +145,13 @@ class XMvnInstallTask
d6a86f
             }
d6a86f
         }
d6a86f
 
d6a86f
-        DeploymentResult result = getDeployer().deploy( request );
d6a86f
+        DeploymentResult result;
d6a86f
+
d6a86f
+        // prevent parallel access to installation plan
d6a86f
+        synchronized ( XMvnInstallTask.class )
d6a86f
+        {
d6a86f
+            result = getDeployer().deploy( request );
d6a86f
+        }
d6a86f
 
d6a86f
         if ( result.getException() != null )
d6a86f
         {
d6a86f
@@ -155,17 +162,22 @@ class XMvnInstallTask
d6a86f
     @TaskAction
d6a86f
     protected void deployProject()
d6a86f
     {
d6a86f
+        Set<PublishArtifact> seenArtifacts = new HashSet<>();
d6a86f
+
d6a86f
         for ( SoftwareComponent component : getProject().getComponents() )
d6a86f
         {
d6a86f
             SoftwareComponentInternal internalComponent = (SoftwareComponentInternal) component;
d6a86f
 
d6a86f
-            for ( Usage usage : internalComponent.getUsages() )
d6a86f
+            for ( UsageContext usage : internalComponent.getUsages() )
d6a86f
             {
d6a86f
                 Set<ModuleDependency> dependencies = usage.getDependencies();
d6a86f
 
d6a86f
                 for ( PublishArtifact artifact : usage.getArtifacts() )
d6a86f
                 {
d6a86f
-                    deploy( artifact, dependencies );
d6a86f
+                    if ( seenArtifacts.add( artifact ) )
d6a86f
+                    {
d6a86f
+                        deploy( artifact, dependencies );
d6a86f
+                    }
d6a86f
                 }
d6a86f
             }
d6a86f
         }
d6a86f
diff --git a/xmvn-parent/pom.xml b/xmvn-parent/pom.xml
d6a86f
index 661cc24d..7e7a6d94 100644
d6a86f
--- a/xmvn-parent/pom.xml
d6a86f
+++ b/xmvn-parent/pom.xml
d6a86f
@@ -84,7 +84,7 @@
d6a86f
     <atinjectVersion>1</atinjectVersion>
d6a86f
     <ivyVersion>2.4.0</ivyVersion>
d6a86f
     <jcommanderVersion>1.64</jcommanderVersion>
d6a86f
-    <gradleVersion>2.13-rc-1</gradleVersion>
d6a86f
+    <gradleVersion>4.2.1</gradleVersion>
d6a86f
     <groovyVersion>2.4.10</groovyVersion>
d6a86f
     <mavenInvokerVersion>2.2</mavenInvokerVersion>
d6a86f
     <mavenResolverVersion>1.0.3</mavenResolverVersion>
d6a86f
@@ -278,11 +278,21 @@
d6a86f
       </dependency>
d6a86f
       <dependency>
d6a86f
         <groupId>org.gradle</groupId>
d6a86f
+        <artifactId>gradle-core-api</artifactId>
d6a86f
+        <version>${gradleVersion}</version>
d6a86f
+      </dependency>
d6a86f
+      <dependency>
d6a86f
+        <groupId>org.gradle</groupId>
d6a86f
         <artifactId>gradle-core</artifactId>
d6a86f
         <version>${gradleVersion}</version>
d6a86f
       </dependency>
d6a86f
       <dependency>
d6a86f
         <groupId>org.gradle</groupId>
d6a86f
+        <artifactId>gradle-model-core</artifactId>
d6a86f
+        <version>${gradleVersion}</version>
d6a86f
+      </dependency>
d6a86f
+      <dependency>
d6a86f
+        <groupId>org.gradle</groupId>
d6a86f
         <artifactId>gradle-dependency-management</artifactId>
d6a86f
         <version>${gradleVersion}</version>
d6a86f
       </dependency>
d6a86f
@@ -292,6 +302,11 @@
d6a86f
         <version>${gradleVersion}</version>
d6a86f
       </dependency>
d6a86f
       <dependency>
d6a86f
+        <groupId>org.gradle</groupId>
d6a86f
+        <artifactId>gradle-logging</artifactId>
d6a86f
+        <version>${gradleVersion}</version>
d6a86f
+      </dependency>
d6a86f
+      <dependency>
d6a86f
         <groupId>org.codehaus.groovy</groupId>
d6a86f
         <artifactId>groovy-all</artifactId>
d6a86f
         <version>${groovyVersion}</version>
d6a86f
-- 
d6a86f
2.13.6
d6a86f