diff --git a/src/it/dependency-properties/pom.xml b/src/it/dependency-properties/pom.xml new file mode 100644 index 0000000..a723216 --- /dev/null +++ b/src/it/dependency-properties/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + + de.eitco.build.essentials.test + cmn-build-essentials-test + @project.version@ + + + + + com.fasterxml.jackson + jackson-bom + 2.17.1 + pom + import + + + + + + + com.fasterxml.jackson.core + jackson-annotations + + + org.springframework.boot + spring-boot-starter + 3.2.5 + + + com.fasterxml.jackson.datatype + jackson-datatype-guava + + + + + + + @project.groupId@ + build-utilities-maven-plugin + @project.version@ + + target/properties.txt + true + + + + + dependencies-version-properties + list-properties + + + + + + + + diff --git a/src/it/dependency-properties/verify.groovy b/src/it/dependency-properties/verify.groovy new file mode 100644 index 0000000..da964b4 --- /dev/null +++ b/src/it/dependency-properties/verify.groovy @@ -0,0 +1,16 @@ +import java.nio.charset.StandardCharsets +import java.nio.file.Files + + + +File propertyInfo = new File(new File("$basedir"), 'target/properties.txt') + +assert propertyInfo.isFile() + +String fileContent = new String(Files.readAllBytes(propertyInfo.toPath()), StandardCharsets.UTF_8) + +assert fileContent.contains('maven.dependency.org.springframework.boot:spring-boot-starter:jar.version = 3.2.5') +assert fileContent.contains('maven.dependency.com.fasterxml.jackson.core:jackson-annotations:jar.version = 2.17.1') +assert fileContent.contains('maven.dependency.com.google.guava:guava:jar.version = 25.1-jre') +assert fileContent.contains('maven.dependency.org.springframework:spring-core:jar.version = 6.1.6') + diff --git a/src/main/java/de/eitco/cicd/build/utilities/DependenciesVersionPropertiesMojo.java b/src/main/java/de/eitco/cicd/build/utilities/DependenciesVersionPropertiesMojo.java index 481b853..42e4a4e 100644 --- a/src/main/java/de/eitco/cicd/build/utilities/DependenciesVersionPropertiesMojo.java +++ b/src/main/java/de/eitco/cicd/build/utilities/DependenciesVersionPropertiesMojo.java @@ -7,15 +7,26 @@ */ package de.eitco.cicd.build.utilities; -import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.*; +import org.apache.maven.project.DefaultProjectBuildingRequest; import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuildingRequest; +import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder; +import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException; +import org.apache.maven.shared.dependency.graph.DependencyNode; +import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor; +import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate; +import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult; -import java.util.Set; +import java.io.File; +import java.util.List; /** * This goal generates properties, containing the version and file system path of every direct dependency the @@ -23,7 +34,6 @@ * set to the absolute file system path of the dependency and 'maven.dependency.<dependency-conflict-id>.version' * set to the version of the dependency. * The dependency conflict id is constructed as follows: <groupId>:<artifactId>:<type>[<classifier>] - * */ @Mojo(name = "dependencies-version-properties", requiresDependencyResolution = ResolutionScope.TEST, defaultPhase = LifecyclePhase.INITIALIZE, threadSafe = true) public class DependenciesVersionPropertiesMojo extends AbstractMojo { @@ -37,8 +47,23 @@ public class DependenciesVersionPropertiesMojo extends AbstractMojo { @Parameter(property = "dependencies-version-properties.skip", defaultValue = "false") private boolean skip; + @Parameter(property = "dependencies-version-properties.add-files", defaultValue = "false") + private boolean addFiles; + + @Parameter(defaultValue = "${session}", readonly = true, required = true) + private MavenSession session; + + @Parameter(defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true) + private List remoteRepositories; + + @Component(hint = "default") + private DependencyGraphBuilder dependencyGraphBuilder; + + @Component + private ArtifactResolver artifactResolver; + @Override - public void execute() { + public void execute() throws MojoExecutionException { if (skip) { @@ -46,14 +71,80 @@ public void execute() { return; } - Set artifacts = project.getDependencyArtifacts(); + ProjectBuildingRequest buildingRequest = + new DefaultProjectBuildingRequest(session.getProjectBuildingRequest()); + + buildingRequest.setProject(project); + + try { + + DependencyNode dependencyNode = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, null); + + dependencyNode.accept(new DependencyNodeVisitor() { + @Override + public boolean visit(DependencyNode node) { + + getLog().debug("setting properties maven.dependency." + node.getArtifact().getDependencyConflictId() + ".[file/version]"); + + if (addFiles) { + + File file = node.getArtifact().getFile(); + + if (file == null) { + + ProjectBuildingRequest buildingRequest = + new DefaultProjectBuildingRequest(session.getProjectBuildingRequest()); + + buildingRequest.setRemoteRepositories(remoteRepositories); - for (Artifact artifact : artifacts) { + ArtifactCoordinate coordinate = getArtifactCoordinate(node); - getLog().debug("setting properties maven.dependency." + artifact.getDependencyConflictId() + ".[file/version]"); + try { - project.getProperties().setProperty("maven.dependency." + artifact.getDependencyConflictId() + ".file", artifact.getFile().getAbsolutePath()); - project.getProperties().setProperty("maven.dependency." + artifact.getDependencyConflictId() + ".version", artifact.getVersion()); + ArtifactResult artifactResult = artifactResolver.resolveArtifact(buildingRequest, coordinate); + + file = artifactResult.getArtifact().getFile(); + + } catch (ArtifactResolverException e) { + + getLog().warn("unable to resolve artifact " + coordinate, e); + } + } + + if (file != null) { + + project.getProperties().setProperty("maven.dependency." + node.getArtifact().getDependencyConflictId() + ".file", file.getAbsolutePath()); + } + } + project.getProperties().setProperty("maven.dependency." + node.getArtifact().getDependencyConflictId() + ".version", node.getArtifact().getVersion()); + + + return true; + } + + @Override + public boolean endVisit(DependencyNode node) { + return true; + } + }); + + + } catch (DependencyGraphBuilderException e) { + + throw new MojoExecutionException(e); } + + } + + private static ArtifactCoordinate getArtifactCoordinate(DependencyNode node) { + + DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate(); + coordinate.setGroupId(node.getArtifact().getGroupId()); + coordinate.setArtifactId(node.getArtifact().getArtifactId()); + coordinate.setVersion(node.getArtifact().getVersion()); + coordinate.setClassifier(node.getArtifact().getClassifier()); + coordinate.setExtension(node.getArtifact().getType()); + + return coordinate; } } diff --git a/src/main/java/de/eitco/cicd/build/utilities/ListPropertiesMojo.java b/src/main/java/de/eitco/cicd/build/utilities/ListPropertiesMojo.java index d1b3a41..75f87d3 100644 --- a/src/main/java/de/eitco/cicd/build/utilities/ListPropertiesMojo.java +++ b/src/main/java/de/eitco/cicd/build/utilities/ListPropertiesMojo.java @@ -7,12 +7,18 @@ */ package de.eitco.cicd.build.utilities; +import org.apache.commons.io.FileUtils; import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.Map; /** @@ -30,8 +36,14 @@ public class ListPropertiesMojo extends AbstractMojo { @Parameter private String prefix; + /** + * This parameter sets the file to write the properties to. If not set the properties will simply be logged. + */ + @Parameter + private File outputFile; + @Override - public void execute() { + public void execute() throws MojoExecutionException { StringBuilder builder = new StringBuilder(); @@ -46,7 +58,24 @@ public void execute() { builder.append(property.getKey()).append(" = ").append(property.getValue()).append("\n"); } - getLog().info("project properties : \n" + builder); + if (outputFile != null) { + + try { + + FileUtils.forceMkdir(outputFile.getParentFile()); + + Files.writeString(outputFile.toPath(), builder.toString()); + + } catch (IOException e) { + + throw new MojoExecutionException(e); + } + + + } else { + + getLog().info("project properties : \n" + builder); + } } }