From 47ec84157c649848ea807681489d0cf74c190bf3 Mon Sep 17 00:00:00 2001
From: Alexey Loubyansky <loubyansky@gmail.com>
Date: Fri, 19 Jul 2019 15:00:45 +0200
Subject: [PATCH] Runtime artifact's POM repos aren't propagated to resolve the
 corresponding deployment deps

---
 .../resolver/BootstrapAppModelResolver.java   | 137 +++++++++---------
 .../DeploymentInjectingDependencyVisitor.java |   8 +-
 .../resolver/maven/MavenArtifactResolver.java |  43 ++++--
 3 files changed, 110 insertions(+), 78 deletions(-)

diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/BootstrapAppModelResolver.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/BootstrapAppModelResolver.java
index 3f1ba98fb0cc7..b6e7057a7ff75 100644
--- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/BootstrapAppModelResolver.java
+++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/BootstrapAppModelResolver.java
@@ -17,6 +17,7 @@
 import org.eclipse.aether.graph.DependencyNode;
 import org.eclipse.aether.graph.DependencyVisitor;
 import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.resolution.ArtifactDescriptorResult;
 import org.eclipse.aether.resolution.ArtifactRequest;
 import org.eclipse.aether.resolution.ArtifactResult;
 import org.eclipse.aether.resolution.VersionRangeResult;
@@ -134,68 +135,15 @@ public AppModel resolveManagedModel(AppArtifact appArtifact, List<AppDependency>
 
     private AppModel doResolveModel(AppArtifact appArtifact, List<Dependency> directMvnDeps, AppArtifact managingProject) throws AppModelResolverException {
         List<Dependency> managedDeps = Collections.emptyList();
+        List<RemoteRepository> managedRepos = Collections.emptyList();
         if(managingProject != null) {
-            managedDeps = mvn.resolveDescriptor(toAetherArtifact(managingProject)).getManagedDependencies();
+            final ArtifactDescriptorResult managingDescr = mvn.resolveDescriptor(toAetherArtifact(managingProject));
+            managedDeps = managingDescr.getManagedDependencies();
+            managedRepos = mvn.newResolutionRepositories(managingDescr.getRepositories());
         }
-        return injectDeploymentDependencies(appArtifact, mvn.resolveManagedDependencies(toAetherArtifact(appArtifact),
-                directMvnDeps, managedDeps, devmode ? new String[] { "test" } : new String[0]).getRoot(), managedDeps);
-    }
-
-    @Override
-    public List<String> listLaterVersions(AppArtifact appArtifact, String upToVersion, boolean inclusive) throws AppModelResolverException {
-        final VersionRangeResult rangeResult = resolveVersionRangeResult(appArtifact, appArtifact.getVersion(), false, upToVersion, inclusive);
-        final List<Version> resolvedVersions = rangeResult.getVersions();
-        final List<String> versions = new ArrayList<>(resolvedVersions.size());
-        for (Version v : resolvedVersions) {
-            versions.add(v.toString());
-        }
-        return versions;
-    }
-
-    @Override
-    public String getNextVersion(AppArtifact appArtifact, String fromVersion, boolean fromVersionIncluded, String upToVersion, boolean upToVersionInclusive) throws AppModelResolverException {
-        final VersionRangeResult rangeResult = resolveVersionRangeResult(appArtifact, fromVersion, fromVersionIncluded, upToVersion, upToVersionInclusive);
-        final List<Version> versions = rangeResult.getVersions();
-        if(versions.isEmpty()) {
-            return null;
-        }
-        Version next = versions.get(0);
-        for(int i = 1; i < versions.size(); ++i) {
-            final Version candidate = versions.get(i);
-            if(next.compareTo(candidate) > 0) {
-                next = candidate;
-            }
-        }
-        return next.toString();
-    }
-
-    @Override
-    public String getLatestVersion(AppArtifact appArtifact, String upToVersion, boolean inclusive) throws AppModelResolverException {
-        final VersionRangeResult rangeResult = resolveVersionRangeResult(appArtifact, appArtifact.getVersion(), false, upToVersion, inclusive);
-        final List<Version> versions = rangeResult.getVersions();
-        if(versions.isEmpty()) {
-            return appArtifact.getVersion();
-        }
-        Version latest = versions.get(0);
-        for(int i = 1; i < versions.size(); ++i) {
-            final Version candidate = versions.get(i);
-            if(latest.compareTo(candidate) < 0) {
-                latest = candidate;
-            }
-        }
-        return latest.toString();
-    }
-
-    public List<RemoteRepository> resolveArtifactRepos(AppArtifact appArtifact) throws AppModelResolverException {
-        return mvn.resolveDescriptor(toAetherArtifact(appArtifact)).getRepositories();
-    }
-
-    public void install(AppArtifact appArtifact, Path localPath) throws AppModelResolverException {
-        mvn.install(new DefaultArtifact(appArtifact.getGroupId(), appArtifact.getArtifactId(), appArtifact.getClassifier(),
-                appArtifact.getType(), appArtifact.getVersion(), Collections.emptyMap(), localPath.toFile()));
-    }
 
-    private AppModel injectDeploymentDependencies(AppArtifact appArtifact, DependencyNode root, List<Dependency> managedDeps) throws AppModelResolverException {
+        DependencyNode resolvedDeps = mvn.resolveManagedDependencies(toAetherArtifact(appArtifact),
+                directMvnDeps, managedDeps, managedRepos, devmode ? new String[] { "test" } : new String[0]).getRoot();
 
         final Set<AppArtifactKey> appDeps = new HashSet<>();
         final List<AppDependency> userDeps = new ArrayList<>();
@@ -215,15 +163,16 @@ public boolean visitLeave(DependencyNode node) {
                 }
                 return true;
             }});
-        for(DependencyNode child : root.getChildren()) {
+        for(DependencyNode child : resolvedDeps.getChildren()) {
             child.accept(visitor);
         }
 
-        final DeploymentInjectingDependencyVisitor deploymentInjector = new DeploymentInjectingDependencyVisitor(mvn, managedDeps);
+        final DeploymentInjectingDependencyVisitor deploymentInjector = new DeploymentInjectingDependencyVisitor(mvn,
+                managedDeps, mvn.aggregateRepositories(managedRepos, mvn.newResolutionRepositories(mvn.resolveDescriptor(toAetherArtifact(appArtifact)).getRepositories())));
         try {
-            root.accept(new TreeDependencyVisitor(deploymentInjector));
+            resolvedDeps.accept(new TreeDependencyVisitor(deploymentInjector));
         } catch (DeploymentInjectionException e) {
-            throw new AppModelResolverException("Failed to inject extension deployment dependencies for " + root.getArtifact(), e.getCause());
+            throw new AppModelResolverException("Failed to inject extension deployment dependencies for " + resolvedDeps.getArtifact(), e.getCause());
         }
 
         List<AppDependency> deploymentDeps = Collections.emptyList();
@@ -231,15 +180,15 @@ public boolean visitLeave(DependencyNode node) {
             final DependencyGraphTransformationContext context = new SimpleDependencyGraphTransformationContext(mvn.getSession());
             try {
                 // add conflict IDs to the added deployments
-                root = new ConflictMarker().transformGraph(root, context);
+                resolvedDeps = new ConflictMarker().transformGraph(resolvedDeps, context);
                 // resolves version conflicts
-                root = new ConflictIdSorter().transformGraph(root, context);
-                root = mvn.getSession().getDependencyGraphTransformer().transformGraph(root, context);
+                resolvedDeps = new ConflictIdSorter().transformGraph(resolvedDeps, context);
+                resolvedDeps = mvn.getSession().getDependencyGraphTransformer().transformGraph(resolvedDeps, context);
             } catch (RepositoryException e) {
                 throw new AppModelResolverException("Failed to normalize the dependency graph", e);
             }
             final BuildDependencyGraphVisitor buildDepsVisitor = new BuildDependencyGraphVisitor(appDeps, buildTreeConsumer);
-            buildDepsVisitor.visit(root);
+            buildDepsVisitor.visit(resolvedDeps);
             final List<ArtifactRequest> requests = buildDepsVisitor.getArtifactRequests();
             if(!requests.isEmpty()) {
                 final List<ArtifactResult> results = mvn.resolve(requests);
@@ -262,6 +211,60 @@ public boolean visitLeave(DependencyNode node) {
         return new AppModel(appArtifact, userDeps, deploymentDeps);
     }
 
+    @Override
+    public List<String> listLaterVersions(AppArtifact appArtifact, String upToVersion, boolean inclusive) throws AppModelResolverException {
+        final VersionRangeResult rangeResult = resolveVersionRangeResult(appArtifact, appArtifact.getVersion(), false, upToVersion, inclusive);
+        final List<Version> resolvedVersions = rangeResult.getVersions();
+        final List<String> versions = new ArrayList<>(resolvedVersions.size());
+        for (Version v : resolvedVersions) {
+            versions.add(v.toString());
+        }
+        return versions;
+    }
+
+    @Override
+    public String getNextVersion(AppArtifact appArtifact, String fromVersion, boolean fromVersionIncluded, String upToVersion, boolean upToVersionInclusive) throws AppModelResolverException {
+        final VersionRangeResult rangeResult = resolveVersionRangeResult(appArtifact, fromVersion, fromVersionIncluded, upToVersion, upToVersionInclusive);
+        final List<Version> versions = rangeResult.getVersions();
+        if(versions.isEmpty()) {
+            return null;
+        }
+        Version next = versions.get(0);
+        for(int i = 1; i < versions.size(); ++i) {
+            final Version candidate = versions.get(i);
+            if(next.compareTo(candidate) > 0) {
+                next = candidate;
+            }
+        }
+        return next.toString();
+    }
+
+    @Override
+    public String getLatestVersion(AppArtifact appArtifact, String upToVersion, boolean inclusive) throws AppModelResolverException {
+        final VersionRangeResult rangeResult = resolveVersionRangeResult(appArtifact, appArtifact.getVersion(), false, upToVersion, inclusive);
+        final List<Version> versions = rangeResult.getVersions();
+        if(versions.isEmpty()) {
+            return appArtifact.getVersion();
+        }
+        Version latest = versions.get(0);
+        for(int i = 1; i < versions.size(); ++i) {
+            final Version candidate = versions.get(i);
+            if(latest.compareTo(candidate) < 0) {
+                latest = candidate;
+            }
+        }
+        return latest.toString();
+    }
+
+    public List<RemoteRepository> resolveArtifactRepos(AppArtifact appArtifact) throws AppModelResolverException {
+        return mvn.resolveDescriptor(toAetherArtifact(appArtifact)).getRepositories();
+    }
+
+    public void install(AppArtifact appArtifact, Path localPath) throws AppModelResolverException {
+        mvn.install(new DefaultArtifact(appArtifact.getGroupId(), appArtifact.getArtifactId(), appArtifact.getClassifier(),
+                appArtifact.getType(), appArtifact.getVersion(), Collections.emptyMap(), localPath.toFile()));
+    }
+
     private VersionRangeResult resolveVersionRangeResult(AppArtifact appArtifact, String fromVersion, boolean fromVersionIncluded, String upToVersion, boolean upToVersionIncluded)
             throws AppModelResolverException {
         return mvn.resolveVersionRange(new DefaultArtifact(appArtifact.getGroupId(),
diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/maven/DeploymentInjectingDependencyVisitor.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/maven/DeploymentInjectingDependencyVisitor.java
index 22d9890183aa8..5199430f4a419 100644
--- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/maven/DeploymentInjectingDependencyVisitor.java
+++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/maven/DeploymentInjectingDependencyVisitor.java
@@ -15,6 +15,7 @@
 import org.eclipse.aether.graph.Dependency;
 import org.eclipse.aether.graph.DependencyNode;
 import org.eclipse.aether.graph.DependencyVisitor;
+import org.eclipse.aether.repository.RemoteRepository;
 import org.jboss.logging.Logger;
 import io.quarkus.bootstrap.BootstrapConstants;
 import io.quarkus.bootstrap.BootstrapDependencyProcessingException;
@@ -37,13 +38,15 @@ public static Artifact getInjectedDependency(DependencyNode dep) {
 
     private final MavenArtifactResolver resolver;
     private final List<Dependency> managedDeps;
+    private final List<RemoteRepository> mainRepos;
     private DependencyNode node;
 
     boolean injectedDeps;
 
-    public DeploymentInjectingDependencyVisitor(MavenArtifactResolver resolver, List<Dependency> managedDeps) {
+    public DeploymentInjectingDependencyVisitor(MavenArtifactResolver resolver, List<Dependency> managedDeps, List<RemoteRepository> mainRepos) {
         this.resolver = resolver;
         this.managedDeps = managedDeps;
+        this.mainRepos = mainRepos;
     }
 
     public boolean isInjectedDeps() {
@@ -124,7 +127,8 @@ private DependencyNode collectDependencies(Artifact artifact) throws BootstrapDe
             artifact = artifact.setVersion(node.getArtifact().getVersion());
         }
         try {
-            return managedDeps.isEmpty() ? resolver.collectDependencies(artifact).getRoot() : resolver.collectManagedDependencies(artifact, Collections.emptyList(), managedDeps).getRoot();
+            return managedDeps.isEmpty() ? resolver.collectDependencies(artifact, Collections.emptyList(), mainRepos).getRoot()
+                    : resolver.collectManagedDependencies(artifact, Collections.emptyList(), managedDeps, mainRepos).getRoot();
         } catch (AppModelResolverException e) {
             throw new DeploymentInjectionException(e);
         }
diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/maven/MavenArtifactResolver.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/maven/MavenArtifactResolver.java
index 8d52d76cc5bad..a626b3552cc30 100644
--- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/maven/MavenArtifactResolver.java
+++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/maven/MavenArtifactResolver.java
@@ -221,7 +221,11 @@ public DependencyResult resolveDependencies(Artifact artifact) throws AppModelRe
     }
 
     public CollectResult collectDependencies(Artifact artifact, List<Dependency> deps) throws AppModelResolverException {
-        final CollectRequest request = newCollectRequest(artifact);
+        return collectDependencies(artifact, deps, Collections.emptyList());
+    }
+
+    public CollectResult collectDependencies(Artifact artifact, List<Dependency> deps, List<RemoteRepository> mainRepos) throws AppModelResolverException {
+        final CollectRequest request = newCollectRequest(artifact, mainRepos);
         request.setDependencies(deps);
         try {
             return repoSystem.collectDependencies(repoSession, request);
@@ -231,7 +235,11 @@ public CollectResult collectDependencies(Artifact artifact, List<Dependency> dep
     }
 
     public DependencyResult resolveDependencies(Artifact artifact, List<Dependency> deps) throws AppModelResolverException {
-        final CollectRequest request = newCollectRequest(artifact);
+        return resolveDependencies(artifact, deps, Collections.emptyList());
+    }
+
+    public DependencyResult resolveDependencies(Artifact artifact, List<Dependency> deps, List<RemoteRepository> mainRepos) throws AppModelResolverException {
+        final CollectRequest request = newCollectRequest(artifact, mainRepos);
         request.setDependencies(deps);
         try {
             return repoSystem.resolveDependencies(repoSession,
@@ -254,7 +262,7 @@ public DependencyResult resolveDependencies(Artifact artifact, String... exclude
                 deps.add(dep);
             }
         }
-        final List<RemoteRepository> requestRepos = remoteRepoManager.aggregateRepositories(repoSession, remoteRepos, descr.getRepositories(), true);
+        final List<RemoteRepository> requestRepos = aggregateRepositories(remoteRepos, newResolutionRepositories(descr.getRepositories()));
         try {
             return repoSystem.resolveDependencies(repoSession,
                     new DependencyRequest().setCollectRequest(
@@ -269,24 +277,32 @@ public DependencyResult resolveDependencies(Artifact artifact, String... exclude
     }
 
     public DependencyResult resolveManagedDependencies(Artifact artifact, List<Dependency> deps, List<Dependency> managedDeps, String... excludedScopes) throws AppModelResolverException {
+        return resolveManagedDependencies(artifact, deps, managedDeps, Collections.emptyList(), excludedScopes);
+    }
+
+    public DependencyResult resolveManagedDependencies(Artifact artifact, List<Dependency> deps, List<Dependency> managedDeps, List<RemoteRepository> mainRepos, String... excludedScopes) throws AppModelResolverException {
         try {
             return repoSystem.resolveDependencies(repoSession,
                     new DependencyRequest().setCollectRequest(
-                            newCollectManagedRequest(artifact, deps, managedDeps, excludedScopes)));
+                            newCollectManagedRequest(artifact, deps, managedDeps, mainRepos, excludedScopes)));
         } catch (DependencyResolutionException e) {
             throw new AppModelResolverException("Failed to resolve dependencies for " + artifact, e);
         }
     }
 
     public CollectResult collectManagedDependencies(Artifact artifact, List<Dependency> deps, List<Dependency> managedDeps, String... excludedScopes) throws AppModelResolverException {
+        return collectManagedDependencies(artifact, deps, managedDeps, Collections.emptyList(), excludedScopes);
+    }
+
+    public CollectResult collectManagedDependencies(Artifact artifact, List<Dependency> deps, List<Dependency> managedDeps, List<RemoteRepository> mainRepos, String... excludedScopes) throws AppModelResolverException {
         try {
-            return repoSystem.collectDependencies(repoSession, newCollectManagedRequest(artifact, deps, managedDeps, excludedScopes));
+            return repoSystem.collectDependencies(repoSession, newCollectManagedRequest(artifact, deps, managedDeps, mainRepos, excludedScopes));
         } catch (DependencyCollectionException e) {
             throw new AppModelResolverException("Failed to collect dependencies for " + artifact, e);
         }
     }
 
-    private CollectRequest newCollectManagedRequest(Artifact artifact, List<Dependency> deps, List<Dependency> managedDeps, String... excludedScopes) throws AppModelResolverException {
+    private CollectRequest newCollectManagedRequest(Artifact artifact, List<Dependency> deps, List<Dependency> managedDeps, List<RemoteRepository> mainRepos, String... excludedScopes) throws AppModelResolverException {
         final ArtifactDescriptorResult descr = resolveDescriptor(artifact);
         Collection<String> excluded;
         if(excludedScopes.length == 0) {
@@ -325,11 +341,20 @@ private CollectRequest newCollectManagedRequest(Artifact artifact, List<Dependen
             }
         }
 
+        final List<RemoteRepository> repos = aggregateRepositories(mainRepos, remoteRepos);
         return new CollectRequest()
                 .setRootArtifact(artifact)
                 .setDependencies(mergeDeps(deps, originalDeps, managedVersions))
                 .setManagedDependencies(mergedManagedDeps)
-                .setRepositories(remoteRepoManager.aggregateRepositories(repoSession, remoteRepos, descr.getRepositories(), true));
+                .setRepositories(aggregateRepositories(repos, newResolutionRepositories(descr.getRepositories())));
+    }
+
+    public List<RemoteRepository> newResolutionRepositories(List<RemoteRepository> repos) {
+        return repos.isEmpty() ? Collections.emptyList() : repoSystem.newResolutionRepositories(repoSession, repos);
+    }
+
+    public List<RemoteRepository> aggregateRepositories(List<RemoteRepository> dominant, List<RemoteRepository> recessive) {
+        return dominant.isEmpty() ? recessive : remoteRepoManager.aggregateRepositories(repoSession, dominant, recessive, false);
     }
 
     public void install(Artifact artifact) throws AppModelResolverException {
@@ -340,10 +365,10 @@ public void install(Artifact artifact) throws AppModelResolverException {
         }
     }
 
-    private CollectRequest newCollectRequest(Artifact artifact) throws AppModelResolverException {
+    private CollectRequest newCollectRequest(Artifact artifact, List<RemoteRepository> mainRepos) throws AppModelResolverException {
         return new CollectRequest()
                 .setRoot(new Dependency(artifact, JavaScopes.RUNTIME))
-                .setRepositories(remoteRepos);
+                .setRepositories(aggregateRepositories(mainRepos, remoteRepos));
     }
 
     private List<Dependency> mergeDeps(List<Dependency> dominant, List<Dependency> recessive, Map<AppArtifactKey, String> managedVersions) {