Skip to content

Commit a81bee3

Browse files
authored
Fix aggregating mojos (#174)
Changes: * parent-child-tree made aggregator * subproject-tree made agregator * project-dependency-tree made aggregator Former two should be run from same spot from where you'd invoke 'full build', while latter allows targeting project using `-Dselector=` where value may be `:A`, `:A:V`, `G:A` or `G:A:V`. Selector must match exactly 1 project, otherwise (0 or 2+ matches) it will fail.
1 parent 903b3ac commit a81bee3

File tree

5 files changed

+78
-12
lines changed

5 files changed

+78
-12
lines changed

toolbox/src/main/java/eu/maveniverse/maven/toolbox/plugin/MPMojoSupport.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ protected boolean isReactorDependency(Dependency dependency) {
105105
p.getVersion(), dependency.getArtifact().getVersion()));
106106
}
107107

108-
protected ReactorLocator getReactorLocator() {
109-
return new MavenReactorLocator(mavenSession);
108+
protected ReactorLocator getReactorLocator(String selector) {
109+
return new MavenReactorLocator(mavenSession, selector);
110110
}
111111
}

toolbox/src/main/java/eu/maveniverse/maven/toolbox/plugin/MavenReactorLocator.java

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111

1212
import eu.maveniverse.maven.toolbox.shared.ProjectLocator;
1313
import eu.maveniverse.maven.toolbox.shared.ReactorLocator;
14+
import java.util.Arrays;
1415
import java.util.List;
1516
import java.util.Objects;
1617
import java.util.Optional;
18+
import java.util.function.Predicate;
1719
import java.util.stream.Collectors;
1820
import java.util.stream.Stream;
1921
import org.apache.maven.RepositoryUtils;
@@ -34,17 +36,55 @@ public class MavenReactorLocator implements ReactorLocator {
3436
private final Project current;
3537
private final List<Project> allProjects;
3638

37-
public MavenReactorLocator(MavenSession session) {
39+
public MavenReactorLocator(MavenSession session, String selector) {
3840
requireNonNull(session, "session");
3941
this.allProjects = session.getAllProjects().stream()
4042
.map(p -> convert(session.getRepositorySession(), p))
4143
.collect(Collectors.toList());
4244
this.topLevel = locateProject(
4345
RepositoryUtils.toArtifact(session.getTopLevelProject().getArtifact()))
4446
.orElseThrow();
45-
this.current = locateProject(
46-
RepositoryUtils.toArtifact(session.getCurrentProject().getArtifact()))
47-
.orElseThrow();
47+
if (selector != null) {
48+
List<MavenProject> candidates = session.getAllProjects().stream()
49+
.filter(createSelector(selector))
50+
.collect(Collectors.toList());
51+
if (candidates.size() != 1) {
52+
List<String> matches = candidates.stream()
53+
.map(p -> ArtifactIdUtils.toId(RepositoryUtils.toArtifact(p.getArtifact())))
54+
.collect(Collectors.toList());
55+
throw new IllegalArgumentException("Could not find 1 matching project: " + matches);
56+
}
57+
this.current = locateProject(
58+
RepositoryUtils.toArtifact(candidates.get(0).getArtifact()))
59+
.orElseThrow();
60+
} else {
61+
this.current = locateProject(RepositoryUtils.toArtifact(
62+
session.getCurrentProject().getArtifact()))
63+
.orElseThrow();
64+
}
65+
}
66+
67+
private Predicate<MavenProject> createSelector(String selector) {
68+
String[] elems =
69+
Arrays.stream(selector.split(":", -1)).filter(s -> !s.isEmpty()).toArray(String[]::new);
70+
if (selector.startsWith(":")) {
71+
// :A or :A:V
72+
if (elems.length == 1) {
73+
return p -> p.getArtifactId().equals(elems[0]);
74+
} else if (elems.length == 2) {
75+
return p -> p.getArtifactId().equals(elems[0]) && p.getVersion().equals(elems[1]);
76+
}
77+
} else {
78+
// G:A or G:A:V
79+
if (elems.length == 2) {
80+
return p -> p.getGroupId().equals(elems[0]) && p.getArtifactId().equals(elems[1]);
81+
} else if (elems.length == 3) {
82+
return p -> p.getGroupId().equals(elems[0])
83+
&& p.getArtifactId().equals(elems[1])
84+
&& p.getVersion().equals(elems[2]);
85+
}
86+
}
87+
throw new IllegalArgumentException("Unsupported selector expression: '" + selector + "'");
4888
}
4989

5090
private Project convert(RepositorySystemSession session, MavenProject project) {

toolbox/src/main/java/eu/maveniverse/maven/toolbox/plugin/mp/ParentChildTreeMojo.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,24 @@
1010
import eu.maveniverse.maven.toolbox.plugin.MPMojoSupport;
1111
import eu.maveniverse.maven.toolbox.shared.Result;
1212
import org.apache.maven.plugins.annotations.Mojo;
13+
import org.apache.maven.plugins.annotations.Parameter;
1314
import org.eclipse.aether.collection.CollectResult;
1415

1516
/**
1617
* Displays project inheritance of Maven Projects.
1718
*/
18-
@Mojo(name = "parent-child-tree", threadSafe = true)
19+
@Mojo(name = "parent-child-tree", aggregator = true, threadSafe = true)
1920
public class ParentChildTreeMojo extends MPMojoSupport {
21+
/**
22+
* Set the project selector, like {@code -rf} Maven command uses it, can be {@code :A} or {@code G:A}. If the
23+
* selector is set, it must match exactly one project within reactor, otherwise it will fail. By default,
24+
* selector is {@code null}, and Maven session "current project" is used.
25+
*/
26+
@Parameter(property = "selector")
27+
private String selector;
28+
2029
@Override
2130
protected Result<CollectResult> doExecute() throws Exception {
22-
return getToolboxCommando().parentChildTree(getReactorLocator());
31+
return getToolboxCommando().parentChildTree(getReactorLocator(selector));
2332
}
2433
}

toolbox/src/main/java/eu/maveniverse/maven/toolbox/plugin/mp/ProjectDependencyTreeMojo.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
/**
1717
* Displays project interdependencies of Maven Projects.
1818
*/
19-
@Mojo(name = "project-dependency-tree", threadSafe = true)
19+
@Mojo(name = "project-dependency-tree", aggregator = true, threadSafe = true)
2020
public class ProjectDependencyTreeMojo extends MPMojoSupport {
2121

2222
/**
@@ -25,8 +25,16 @@ public class ProjectDependencyTreeMojo extends MPMojoSupport {
2525
@Parameter(property = "showExternal", defaultValue = "false", required = true)
2626
private boolean showExternal;
2727

28+
/**
29+
* Set the project selector, like {@code -rf} Maven command uses it, can be {@code :A} or {@code G:A}. If the
30+
* selector is set, it must match exactly one project within reactor, otherwise it will fail. By default,
31+
* selector is {@code null}, and Maven session "current project" is used.
32+
*/
33+
@Parameter(property = "selector")
34+
private String selector;
35+
2836
@Override
2937
protected Result<CollectResult> doExecute() throws Exception {
30-
return getToolboxCommando().projectDependencyTree(getReactorLocator(), showExternal);
38+
return getToolboxCommando().projectDependencyTree(getReactorLocator(selector), showExternal);
3139
}
3240
}

toolbox/src/main/java/eu/maveniverse/maven/toolbox/plugin/mp/SubprojectTreeMojo.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,24 @@
1010
import eu.maveniverse.maven.toolbox.plugin.MPMojoSupport;
1111
import eu.maveniverse.maven.toolbox.shared.Result;
1212
import org.apache.maven.plugins.annotations.Mojo;
13+
import org.apache.maven.plugins.annotations.Parameter;
1314
import org.eclipse.aether.collection.CollectResult;
1415

1516
/**
1617
* Displays subproject collection of Maven Projects.
1718
*/
18-
@Mojo(name = "subproject-tree", threadSafe = true)
19+
@Mojo(name = "subproject-tree", aggregator = true, threadSafe = true)
1920
public class SubprojectTreeMojo extends MPMojoSupport {
21+
/**
22+
* Set the project selector, like {@code -rf} Maven command uses it, can be {@code :A} or {@code G:A}. If the
23+
* selector is set, it must match exactly one project within reactor, otherwise it will fail. By default,
24+
* selector is {@code null}, and Maven session "current project" is used.
25+
*/
26+
@Parameter(property = "selector")
27+
private String selector;
28+
2029
@Override
2130
protected Result<CollectResult> doExecute() throws Exception {
22-
return getToolboxCommando().subprojectTree(getReactorLocator());
31+
return getToolboxCommando().subprojectTree(getReactorLocator(selector));
2332
}
2433
}

0 commit comments

Comments
 (0)