Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve project artifacts by Resolver API #526

Merged
merged 1 commit into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,5 @@ updates:
interval: daily
open-pull-requests-limit: 10
ignore:
- dependency-name: org.apache.maven:maven-artifact
versions:
- "> 3.5.0"
- dependency-name: org.apache.maven:maven-core
versions:
- "> 3.5.0"
- dependency-name: org.apache.maven:maven-plugin-api
versions:
- "> 3.5.0"
- dependency-name: org.apache.maven:*
- dependency-name: org.apache.maven.resolve:*
16 changes: 10 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,12 @@
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-api</artifactId>
<version>1.9.18</version>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-util</artifactId>
<version>1.0.3</version>
</dependency>
<!-- /maven core -->

Expand All @@ -143,11 +148,6 @@
<artifactId>httpcore</artifactId>
<version>4.4.16</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-shared-utils</artifactId>
Expand Down Expand Up @@ -336,6 +336,10 @@
<artifactId>maven-resolver-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-util</artifactId>
</dependency>
<!-- /maven core -->

<!-- apache -->
Expand Down
63 changes: 59 additions & 4 deletions src/main/java/org/simplify4u/plugins/ArtifactResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -52,6 +53,7 @@
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.util.artifact.SubArtifact;
import org.simplify4u.plugins.skipfilters.CompositeSkipper;
import org.simplify4u.plugins.skipfilters.ScopeSkipper;
import org.simplify4u.plugins.skipfilters.SkipFilter;
Expand Down Expand Up @@ -85,6 +87,8 @@ public class ArtifactResolver {

private final List<ArtifactRepository> remoteRepositories;

private final List<RemoteRepository> aeRemoteRepositories;

/**
* Copy of remote repositories with check sum policy set to ignore, we need it for pgp signature resolving.
* <p>
Expand All @@ -98,6 +102,7 @@ public class ArtifactResolver {
this.repositorySystem = requireNonNull(repositorySystem);
this.localRepository = requireNonNull(session.getLocalRepository());
this.remoteRepositories = requireNonNull(session.getCurrentProject().getRemoteArtifactRepositories());
this.aeRemoteRepositories = requireNonNull(session.getCurrentProject().getRemoteProjectRepositories());
this.remoteRepositoriesIgnoreCheckSum =
repositoriesIgnoreCheckSum(session.getCurrentProject().getRemoteProjectRepositories());
this.aetherRepositorySystem = aetherRepositorySystem;
Expand Down Expand Up @@ -143,10 +148,12 @@ private static RepositoryPolicy policyIgnoreCheckSum(RepositoryPolicy policy) {
* @param config configuration for the artifact resolver
* @return Returns set of all artifacts whose signature needs to be verified.
*/
@SuppressWarnings( {"deprecation", "java:S1874"})
// @SuppressWarnings( {"deprecation", "java:S1874"})
Set<Artifact> resolveProjectArtifacts(MavenProject project, Configuration config) throws MojoExecutionException {
final LinkedHashSet<Artifact> allArtifacts = new LinkedHashSet<>(resolveArtifacts(project.getArtifacts(),
config.dependencyFilter, null, config.verifyPomFiles, false));

final LinkedHashSet<Artifact> allArtifacts = new LinkedHashSet<>(resolveProjectArtifacts(project.getArtifacts(),
config.dependencyFilter, config.verifyPomFiles));

if (config.verifyPlugins) {
// Resolve transitive dependencies for build plug-ins and reporting plug-ins and their dependencies.
// The transitive closure is computed for each plug-in with its dependencies, as individual executions may
Expand Down Expand Up @@ -285,6 +292,53 @@ Map<Artifact, Artifact> resolveSignatures(Collection<Artifact> artifacts) {
return result;
}

/**
* Resolve all dependencies provided as input. POMs corresponding to the dependencies may optionally be resolved.
*
* @param artifacts Dependencies to be resolved.
* @param artifactFilter Skip filter to test against to determine whether dependency must be skipped.
* @param verifyPom Boolean indicating whether or not POMs corresponding to dependencies should be
* resolved.
* @return Returns set of resolved artifacts.
*/
private Set<Artifact> resolveProjectArtifacts(Iterable<Artifact> artifacts, SkipFilter artifactFilter,
boolean verifyPom) {
final LinkedHashSet<org.eclipse.aether.artifact.Artifact> collection = new LinkedHashSet<>();
for (Artifact artifact : artifacts) {
if (artifactFilter.shouldSkipArtifact(artifact)) {
LOG.debug("Skipping artifact: {}", artifact);
continue;
}
org.eclipse.aether.artifact.Artifact aeArtifact = RepositoryUtils.toArtifact(artifact);
collection.add(aeArtifact);
if (verifyPom) {
SubArtifact pomArtifact = new SubArtifact(aeArtifact, null, "pom");
collection.add(pomArtifact);
}
}

List<ArtifactRequest> requestList = collection.stream()
.map(a -> new ArtifactRequest(a, aeRemoteRepositories, null))
.collect(Collectors.toList());

List<ArtifactResult> artifactResults =
Try.of(() -> aetherRepositorySystem.resolveArtifacts(repositorySession, requestList))
.recover(ArtifactResolutionException.class, ArtifactResolutionException::getResults)
.get();

Set<Artifact> result = new HashSet<>();
artifactResults.forEach(aResult -> {
if (aResult.isResolved()) {
result.add(RepositoryUtils.toArtifact(aResult.getArtifact()));
} else {
aResult.getExceptions().forEach(
e -> LOG.debug("Failed to resolve {}: {}", aResult.getRequest().getArtifact(),
e.getMessage()));
}
});
return result;
}

/**
* Resolve all dependencies provided as input. POMs corresponding to the dependencies may optionally be resolved.
*
Expand All @@ -299,7 +353,8 @@ Map<Artifact, Artifact> resolveSignatures(Collection<Artifact> artifacts) {
* @return Returns set of resolved artifacts.
*/
private Set<Artifact> resolveArtifacts(Iterable<Artifact> artifacts, SkipFilter artifactFilter,
SkipFilter dependenciesFilter, boolean verifyPom, boolean transitive) throws MojoExecutionException {
SkipFilter dependenciesFilter, boolean verifyPom, boolean transitive)
throws MojoExecutionException {
final LinkedHashSet<Artifact> collection = new LinkedHashSet<>();
for (final Artifact artifact : artifacts) {
Artifact resolved = resolveArtifact(artifact);
Expand Down
66 changes: 41 additions & 25 deletions src/test/java/org/simplify4u/plugins/ArtifactResolverTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
package org.simplify4u.plugins;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand All @@ -29,8 +31,6 @@
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
Expand All @@ -55,13 +55,11 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.internal.verification.VerificationModeFactory.times;

@ExtendWith(MockitoExtension.class)
class ArtifactResolverTest {
Expand Down Expand Up @@ -131,17 +129,23 @@ void testResolveProjectArtifactsEmpty() throws MojoExecutionException {
}

@Test
void testResolveProjectArtifactsWithoutPoms() throws MojoExecutionException {
void testResolveProjectArtifactsWithoutPoms() throws Exception {

// given
when(repositorySystem.resolve(isA(ArtifactResolutionRequest.class))).thenAnswer((Answer<ArtifactResolutionResult>) invocation -> {
Artifact artifact = invocation.<ArtifactResolutionRequest>getArgument(0).getArtifact();
artifact.setResolvedVersion(artifact.getVersion());
artifact.setResolved(true);
return new ArtifactResolutionResult();
DefaultArtifact artifact = new DefaultArtifact("g", "a", "1.0", "compile", "jar", "classifier", new DefaultArtifactHandler("jar"));

when(aetherRepositorySystem.resolveArtifacts(any(), any())).thenAnswer((Answer<List<ArtifactResult>>) invocation -> {
Collection<ArtifactRequest> artifactsRequests = invocation.getArgument(1);
assertThat(artifactsRequests).hasSize(1);
ArtifactRequest artifactRequest = artifactsRequests.iterator().next();
ArtifactResult artifactResult = new ArtifactResult(artifactRequest);
org.eclipse.aether.artifact.Artifact resolvedArtifact = artifactRequest.getArtifact();
resolvedArtifact = resolvedArtifact.setFile(new File("."));
artifactResult.setArtifact(resolvedArtifact);
return Collections.singletonList(artifactResult);
});

DefaultArtifact artifact = new DefaultArtifact("g", "a", "1.0", "compile", "jar", "classifier", null);

when(project.getArtifacts()).thenReturn(singleton(artifact));

Configuration config = new Configuration(new CompositeSkipper(emptyList()),
Expand All @@ -157,19 +161,33 @@ void testResolveProjectArtifactsWithoutPoms() throws MojoExecutionException {
}

@Test
void testResolveProjectArtifactsWithPoms() throws MojoExecutionException {
void testResolveProjectArtifactsWithPoms() throws Exception {

// given
when(repositorySystem.resolve(isA(ArtifactResolutionRequest.class))).thenAnswer((Answer<ArtifactResolutionResult>) invocation -> {
Artifact artifact = invocation.<ArtifactResolutionRequest>getArgument(0).getArtifact();
artifact.setResolved(true);
return new ArtifactResolutionResult();
});
DefaultArtifact artifact = new DefaultArtifact("g", "a", "1.0", "compile", "jar", "classifier", new DefaultArtifactHandler("jar"));
when(aetherRepositorySystem.resolveArtifacts(any(), any())).thenAnswer((Answer<List<ArtifactResult>>) invocation -> {
Collection<ArtifactRequest> artifactsRequests = invocation.getArgument(1);
assertThat(artifactsRequests).hasSize(2);

Iterator<ArtifactRequest> iterator = artifactsRequests.iterator();
List<ArtifactResult> results = new ArrayList<>();
ArtifactRequest artifactRequest = iterator.next();
ArtifactResult artifactResult = new ArtifactResult(artifactRequest);
org.eclipse.aether.artifact.Artifact resolvedArtifact = artifactRequest.getArtifact();
resolvedArtifact = resolvedArtifact.setFile(new File("."));
artifactResult.setArtifact(resolvedArtifact);
results.add(artifactResult);

when(repositorySystem.createProjectArtifact("g", "a", "1.0"))
.thenReturn(new DefaultArtifact("g", "a", "1.0", "compile", "pom", "classifier", null));
artifactRequest = iterator.next();
artifactResult = new ArtifactResult(artifactRequest);
resolvedArtifact = artifactRequest.getArtifact();
resolvedArtifact = resolvedArtifact.setFile(new File("."));
artifactResult.setArtifact(resolvedArtifact);
results.add(artifactResult);

return results;
});

DefaultArtifact artifact = new DefaultArtifact("g", "a", "1.0", "compile", "jar", "classifier", null);
when(project.getArtifacts()).thenReturn(singleton(artifact));

Configuration config = new Configuration(new CompositeSkipper(emptyList()),
Expand All @@ -179,8 +197,6 @@ void testResolveProjectArtifactsWithPoms() throws MojoExecutionException {
Set<Artifact> resolved = resolver.resolveProjectArtifacts(project, config);

// then
verify(repositorySystem, times(1))
.createProjectArtifact("g", "a", "1.0");

assertThat(resolved).hasSize(2)
.allMatch(Artifact::isResolved)
Expand All @@ -189,7 +205,7 @@ void testResolveProjectArtifactsWithPoms() throws MojoExecutionException {
}

@Test
void testResolveSignaturesEmpty() throws MojoExecutionException {
void testResolveSignaturesEmpty() {

// when
Map<Artifact, Artifact> resolved = resolver.resolveSignatures(emptyList());
Expand All @@ -205,7 +221,7 @@ void testResolveSignaturesResolved() throws ArtifactResolutionException {
DefaultArtifact artifact = new DefaultArtifact("g", "a", "1.0", "compile", "jar", null, new DefaultArtifactHandler());

when(aetherRepositorySystem.resolveArtifacts(any(), any())).thenAnswer((Answer<List<ArtifactResult>>) invocation -> {
Collection<ArtifactRequest> artifactsRequests = invocation.<Collection<ArtifactRequest>>getArgument(1);
Collection<ArtifactRequest> artifactsRequests = invocation.getArgument(1);
assertThat(artifactsRequests).hasSize(1);
ArtifactRequest artifactRequest = artifactsRequests.iterator().next();
ArtifactResult artifactResult = new ArtifactResult(artifactRequest);
Expand Down Expand Up @@ -240,7 +256,7 @@ void testResolveSignaturesUnresolvedNone() throws ArtifactResolutionException {
DefaultArtifact artifact = new DefaultArtifact("g", "a", "1.0", "compile", "jar", null, new DefaultArtifactHandler());

when(aetherRepositorySystem.resolveArtifacts(any(), any())).thenAnswer((Answer<List<ArtifactResult>>) invocation -> {
Collection<ArtifactRequest> artifactsRequests = invocation.<Collection<ArtifactRequest>>getArgument(1);
Collection<ArtifactRequest> artifactsRequests = invocation.getArgument(1);
assertThat(artifactsRequests).hasSize(1);
ArtifactRequest artifactRequest = artifactsRequests.iterator().next();
ArtifactResult artifactResult = new ArtifactResult(artifactRequest);
Expand Down