[repository libraries] explicitly exclude transitive dependencies which was rejected during conflict resolution (IDEA-274162)

Some of transitive dependencies of an artifact may be rejected during conflict resolution. If we disable other dependencies, they may become not rejected and will be unexpectedly added to the library. In order to prevent this, we now show all dependencies including rejected ones in the transitive dependencies tree, and explicitly exclude rejected dependencies if needed.

GitOrigin-RevId: 2ed449dda66bee8a990e15fe4026f57ad563936e
This commit is contained in:
Nikolay Chashnikov
2021-07-21 19:01:05 +03:00
committed by intellij-monorepo-bot
parent 3d7c0061ae
commit b610cb44f9
4 changed files with 67 additions and 13 deletions

View File

@@ -9,10 +9,12 @@ import java.util.List;
public class ArtifactDependencyNode {
private final Artifact myArtifact;
private final List<ArtifactDependencyNode> myDependencies;
private final boolean myRejected;
public ArtifactDependencyNode(@NotNull Artifact artifact, @NotNull List<ArtifactDependencyNode> dependencies) {
public ArtifactDependencyNode(@NotNull Artifact artifact, @NotNull List<ArtifactDependencyNode> dependencies, boolean rejected) {
myArtifact = artifact;
myDependencies = dependencies;
myRejected = rejected;
}
@NotNull
@@ -24,4 +26,11 @@ public class ArtifactDependencyNode {
public List<ArtifactDependencyNode> getDependencies() {
return myDependencies;
}
/**
* Returns {@code true} if this dependency was rejected by conflict resolution process
*/
public boolean isRejected() {
return myRejected;
}
}

View File

@@ -29,6 +29,7 @@ import org.eclipse.aether.util.artifact.JavaScopes;
import org.eclipse.aether.util.filter.DependencyFilterUtils;
import org.eclipse.aether.util.graph.selector.AndDependencySelector;
import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector;
import org.eclipse.aether.util.graph.transformer.ConflictResolver;
import org.eclipse.aether.util.graph.visitor.FilteringDependencyVisitor;
import org.eclipse.aether.util.graph.visitor.TreeDependencyVisitor;
import org.eclipse.aether.util.version.GenericVersionScheme;
@@ -158,6 +159,17 @@ public final class ArtifactRepositoryManager {
return defaultSession;
}
/**
* Return session which will include dependencies rejected by conflict resolver to the results.
* @see ArtifactDependencyNode#isRejected()
*/
RepositorySystemSession createVerboseSession() {
DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(defaultSession);
session.setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, Boolean.TRUE);
session.setReadOnly();
return session;
}
RepositorySystemSession createSession(@NotNull List<String> excludedDependencies) {
if (excludedDependencies.isEmpty()) {
return defaultSession;
@@ -242,7 +254,7 @@ public final class ArtifactRepositoryManager {
Set<VersionConstraint> constraints = Collections.singleton(asVersionConstraint(versionConstraint));
CollectRequest collectRequest = createCollectRequest(groupId, artifactId, constraints, EnumSet.of(ArtifactKind.ARTIFACT));
ArtifactDependencyTreeBuilder builder = new ArtifactDependencyTreeBuilder();
DependencyNode root = ourSystem.collectDependencies(mySessionFactory.getDefaultSession(), collectRequest).getRoot();
DependencyNode root = ourSystem.collectDependencies(mySessionFactory.createVerboseSession(), collectRequest).getRoot();
if (root.getArtifact() == null && root.getChildren().size() == 1) {
root = root.getChildren().get(0);
}
@@ -582,7 +594,8 @@ public final class ArtifactRepositoryManager {
if (artifact != null) {
List<ArtifactDependencyNode> last = myCurrentChildren.get(myCurrentChildren.size() - 1);
myCurrentChildren.remove(myCurrentChildren.size() - 1);
myCurrentChildren.get(myCurrentChildren.size() - 1).add(new ArtifactDependencyNode(artifact, last));
boolean rejected = node.getData().get(ConflictResolver.NODE_DATA_WINNER) != null;
myCurrentChildren.get(myCurrentChildren.size() - 1).add(new ArtifactDependencyNode(artifact, last, rejected));
}
return true;
}