diff --git a/src/it/compare-mono/verify.groovy b/src/it/compare-mono/verify.groovy index fcf257c..6a1de16 100644 --- a/src/it/compare-mono/verify.groovy +++ b/src/it/compare-mono/verify.groovy @@ -54,3 +54,11 @@ assert buildinfoFile.isFile() String buildinfo = buildinfoFile.text assert buildinfo.contains( "mvn.rebuild-args=-Dmaven.session.versionFilter=e(org.slf4j:slf4j-api:(1.7.36,))" ) + +// check existence of build log +File buildLogFile = new File( basedir, "build.log" ); +assert buildLogFile.isFile() + +String buildLog = buildLogFile.text +assert buildLog.contains("[WARNING] The artifact org.slf4j:slf4j-api:1.7.36 is stemming from a local install to your local Maven repository. Please ensure that this is intended. If not, consider removing this artifact and rebuilding. and that your locally installed artifact from") +assert buildLog.contains("slf4j-api-1.7.36.jar matches public reference from remote.") \ No newline at end of file diff --git a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/CompareMojo.java b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/CompareMojo.java index 9c5ca01..6ddfcd3 100644 --- a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/CompareMojo.java +++ b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/CompareMojo.java @@ -157,7 +157,7 @@ private File downloadOrCreateReferenceBuildinfo(boolean mono, Map artifacts, File referenceBuildinfo) diff --git a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/ReferenceBuildinfoUtil.java b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/ReferenceBuildinfoUtil.java index b3a69df..013fdf9 100644 --- a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/ReferenceBuildinfoUtil.java +++ b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/ReferenceBuildinfoUtil.java @@ -31,6 +31,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.jar.Attributes; @@ -48,6 +49,13 @@ import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.collection.CollectResult; +import org.eclipse.aether.collection.DependencyCollectionException; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.repository.ArtifactRepository; +import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.repository.WorkspaceReader; import org.eclipse.aether.resolution.ArtifactRequest; @@ -100,7 +108,12 @@ class ReferenceBuildinfoUtil { } File downloadOrCreateReferenceBuildinfo( - RemoteRepository repo, MavenProject project, File buildinfoFile, boolean mono) + RemoteRepository repo, + MavenProject project, + File buildinfoFile, + boolean mono, + RepositorySystemSession repoSession, + List remoteRepos) throws MojoExecutionException { File referenceBuildinfo = downloadReferenceBuildinfo(repo, project, buildinfoFile); @@ -179,9 +192,12 @@ File downloadOrCreateReferenceBuildinfo( for (Map.Entry entry : artifacts.entrySet()) { Artifact artifact = entry.getKey(); - String prefix = entry.getValue(); + + checkForLocalResolution(repoSession, remoteRepos, artifact); + File referenceFile = referenceArtifacts.get(artifact); if (referenceFile != null) { + String prefix = entry.getValue(); bi.printFile(prefix, artifact.getGroupId(), referenceFile); } } @@ -199,6 +215,61 @@ File downloadOrCreateReferenceBuildinfo( return referenceBuildinfo; } + public void checkForLocalResolution( + RepositorySystemSession repoSession, List remoteRepos, Artifact artifact) { + + try { + CollectRequest collectRequest = new CollectRequest(new Dependency(artifact, null), null); + CollectResult collectResult = repoSystem.collectDependencies(repoSession, collectRequest); + + for (DependencyNode child : collectResult.getRoot().getChildren()) { + checkDependenciesForLocalResolution(repoSession, child, remoteRepos); + } + + } catch (ArtifactResolutionException | DependencyCollectionException e) { + log.warn("Checking for potential local artifact resolution not possible " + e); + } + } + + private void checkDependenciesForLocalResolution( + RepositorySystemSession repoSession, DependencyNode child, List remoteRepos) + throws ArtifactResolutionException { + // check for every dependency in the dependency tree + if (!child.getChildren().isEmpty()) { + for (DependencyNode node : child.getChildren()) { + checkDependenciesForLocalResolution(repoSession, node, remoteRepos); + } + } else { + printWarningForLocalRepositoryArtifactResolution(repoSession, child, remoteRepos); + } + } + + /* An artifact stemming from a local repo is most likely an issue during release builds. See #146. */ + private void printWarningForLocalRepositoryArtifactResolution( + RepositorySystemSession repoSession, DependencyNode child, List remoteRepos) + throws ArtifactResolutionException { + Artifact defaultArtifact = child.getDependency().getArtifact(); + ArtifactRequest artifactRequest = new ArtifactRequest(); + artifactRequest.setArtifact(defaultArtifact); + artifactRequest.setRepositories(remoteRepos); + ArtifactResult artifactResult = repoSystem.resolveArtifact(repoSession, artifactRequest); + Artifact artifact = artifactResult.getArtifact(); + ArtifactRepository resultRepo = artifactResult.getRepository(); + + if (resultRepo instanceof LocalRepository) { + log.warn(String.format( + "The artifact %s:%s:%s is stemming from a local install to your local Maven repository. " + + "Please ensure that this is intended. " + + "If not, consider removing this artifact and rebuilding " + + "and that your locally installed artifact from %s matches public reference from remote.", + artifact.getGroupId(), + artifact.getArtifactId(), + artifact.getVersion(), + // if the artifact was resolved successfully, there is a file we can access + artifact.getFile().getAbsolutePath())); + } + } + private ReproducibleEnv extractEnv(File file, Artifact artifact) { log.debug("Guessing java.version and os.name from jar " + file); try (JarFile jar = new JarFile(file)) {