Skip to content

Commit

Permalink
Merge pull request #543 from axonivy/validate-different-versions
Browse files Browse the repository at this point in the history
 XIVY-10541 Detect different plugin versions
  • Loading branch information
ivy-lli authored Dec 19, 2024
2 parents 6b9cea4 + 5d64508 commit 09aaa8a
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 0 deletions.
71 changes: 71 additions & 0 deletions src/main/java/ch/ivyteam/ivy/maven/validate/ValidateMojo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package ch.ivyteam.ivy.maven.validate;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;

@Mojo(name = ValidateMojo.GOAL, requiresProject = true)
public class ValidateMojo extends AbstractMojo {

public static final String GOAL = "validate";
protected static final String PLUGIN_GROUPID = "com.axonivy.ivy.ci";
protected static final String PLUGIN_ARTIFACTID = "project-build-plugin";

@Parameter(defaultValue = "${session}", readonly = true, required = true)
private MavenSession session;

@Override
public void execute() throws MojoExecutionException, MojoFailureException {
validateConsistentPluginVersion(session.getAllProjects());
}

void validateConsistentPluginVersion(List<MavenProject> projects) throws MojoExecutionException {
var versionToProjectsMap = new HashMap<String, Set<MavenProject>>();
for (var project : projects) {
findProjectBuildPlugin(project.getBuild().getPlugins()).ifPresent(plugin -> {
var version = plugin.getVersion();
getLog().debug(PLUGIN_GROUPID + ":" + plugin.getArtifactId() + ":" + version + " configured in " + project);
var projectSet = versionToProjectsMap.computeIfAbsent(version, v -> new LinkedHashSet<>());
projectSet.add(project);
});
}
if (versionToProjectsMap.size() > 1) {
var versions = new ArrayList<>(versionToProjectsMap.keySet());
Collections.sort(versions);
var error = "Several versions of project-build-plugins are configured " + versions + ":\n";
error += versions.stream().map(v -> versionProjects(versionToProjectsMap, v)).collect(Collectors.joining("\n"));
getLog().error(error);
throw new MojoExecutionException("All project-build-plugins configured in one reactor must use the same version");
}
}

private Optional<Plugin> findProjectBuildPlugin(List<Plugin> plugins) {
return plugins.stream()
.filter(p -> PLUGIN_GROUPID.equals(p.getGroupId()) && PLUGIN_ARTIFACTID.equals(p.getArtifactId()))
.filter(p -> p.getVersion() != null) // Skip plug-ins that do not have a version
.findFirst();
}

private String versionProjects(Map<String, Set<MavenProject>> versionToProjectsMap, String version) {
return version + " -> [" +
versionToProjectsMap.get(version).stream()
.map(p -> p.getArtifactId())
.collect(Collectors.joining(", ")) +
"]";
}
}
2 changes: 2 additions & 0 deletions src/main/resources/META-INF/plexus/components.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<configuration>
<phases>
<clean>com.axonivy.ivy.ci:project-build-plugin:maven-dependency-cleanup</clean>
<validate>com.axonivy.ivy.ci:project-build-plugin:validate</validate>
<initialize>com.axonivy.ivy.ci:project-build-plugin:installEngine</initialize>
<process-resources>
com.axonivy.ivy.ci:project-build-plugin:ivy-resources-properties,
Expand Down Expand Up @@ -38,6 +39,7 @@
</implementation>
<configuration>
<phases>
<validate>com.axonivy.ivy.ci:project-build-plugin:validate</validate>
<initialize>com.axonivy.ivy.ci:project-build-plugin:installEngine</initialize>
<process-resources>
com.axonivy.ivy.ci:project-build-plugin:ivy-resources-properties,
Expand Down
77 changes: 77 additions & 0 deletions src/test/java/ch/ivyteam/ivy/maven/validate/TestValidateMojo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package ch.ivyteam.ivy.maven.validate;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.io.File;
import java.nio.file.Path;
import java.util.List;

import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.junit.Rule;
import org.junit.Test;

import ch.ivyteam.ivy.maven.ProjectMojoRule;
import ch.ivyteam.ivy.maven.log.LogCollector;


public class TestValidateMojo {
private ValidateMojo mojo;

@Rule
public ProjectMojoRule<ValidateMojo> rule = new ProjectMojoRule<ValidateMojo>(
Path.of("src/test/resources/base"), ValidateMojo.GOAL) {
@Override
protected void before() throws Throwable {
super.before();
TestValidateMojo.this.mojo = getMojo();
}
};

@Test
public void samePluginVersions() throws Exception {
var log = new LogCollector();
rule.getMojo().setLog(log);
var p1 = createMavenProject("project1", "12.0.0");
var p2 = createMavenProject("project2", "12.0.0");
mojo.validateConsistentPluginVersion(List.of(p1, p2));
assertThat(log.getDebug()).hasSize(2);
assertThat(log.getDebug().get(0).toString())
.contains("com.axonivy.ivy.ci:project-build-plugin:12.0.0 configured in MavenProject: group:project1:12.0.0-SNAPSHOT");
assertThat(log.getDebug().get(1).toString())
.contains("com.axonivy.ivy.ci:project-build-plugin:12.0.0 configured in MavenProject: group:project2:12.0.0-SNAPSHOT");
assertThat(log.getErrors()).isEmpty();
}

@Test
public void differentPluginVersions() throws Exception {
var log = new LogCollector();
rule.getMojo().setLog(log);
var p1 = createMavenProject("project1", "12.0.0");
var p2 = createMavenProject("project2", "12.0.1");
assertThatThrownBy(() -> mojo.validateConsistentPluginVersion(List.of(p1, p2)))
.isInstanceOf(MojoExecutionException.class);
assertThat(log.getErrors()).hasSize(1);
assertThat(log.getErrors().get(0).toString())
.isEqualTo("""
Several versions of project-build-plugins are configured [12.0.0, 12.0.1]:
12.0.0 -> [project1]
12.0.1 -> [project2]""");
}

private MavenProject createMavenProject(String projectId, String version) {
var project = new MavenProject();
project.setGroupId("group");
project.setArtifactId(projectId);
project.setVersion("12.0.0-SNAPSHOT");
project.setFile(new File("src/test/resources/" + projectId));
var plugin = new Plugin();
plugin.setGroupId(ValidateMojo.PLUGIN_GROUPID);
plugin.setArtifactId(ValidateMojo.PLUGIN_ARTIFACTID);
plugin.setVersion(version);
project.getBuild().getPlugins().add(plugin);
return project;
}
}

0 comments on commit 09aaa8a

Please sign in to comment.