1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.commonjava.maven.plugins.execroot;
17
18 import java.io.File;
19 import java.nio.file.Path;
20 import java.util.ArrayDeque;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Comparator;
24 import java.util.Deque;
25 import java.util.List;
26 import java.util.Locale;
27
28 import org.apache.maven.plugin.MojoExecutionException;
29 import org.apache.maven.plugins.annotations.LifecyclePhase;
30 import org.apache.maven.plugins.annotations.Mojo;
31 import org.apache.maven.plugins.annotations.Parameter;
32 import org.apache.maven.project.MavenProject;
33
34
35
36
37 @Mojo(name = "highest-basedir", defaultPhase = LifecyclePhase.INITIALIZE, requiresProject = true, threadSafe = true)
38 public class HighestBasedirGoal extends AbstractDirectoryGoal {
39
40
41
42
43 public static final class PathComparator implements Comparator<File> {
44 @Override
45 public int compare(final File first, final File second) {
46 if (System.getProperty("os.name").startsWith("Windows")) {
47 return first.getAbsolutePath().compareToIgnoreCase(second.getAbsolutePath());
48 }
49 return first.getAbsolutePath().compareTo(second.getAbsolutePath());
50 }
51 }
52
53
54 protected static final String HIGHEST_DIR_CONTEXT_KEY = "directories.highestDir";
55
56
57 @Parameter(defaultValue = "${reactorProjects}", readonly = true)
58 protected List<MavenProject> projects;
59
60 @Override
61 protected File findDirectory() throws MojoExecutionException {
62 final Deque<MavenProject> toCheck = new ArrayDeque<>(projects);
63
64 String localRepoBaseDir = session.getRepositorySession().getLocalRepository().getBasedir().getAbsolutePath();
65
66 final List<File> files = new ArrayList<>();
67 while (!toCheck.isEmpty()) {
68 final MavenProject mavenProject = toCheck.pop();
69 if (mavenProject.getBasedir() == null
70 || mavenProject.getBasedir().toString().startsWith(localRepoBaseDir)) {
71
72 continue;
73 }
74
75 Path path = Path.of(mavenProject.getBasedir().toURI()).normalize();
76
77 if (!files.contains(path.toFile())) {
78
79 files.add(0, path.toFile());
80 }
81
82 if (mavenProject.getParent() != null) {
83 toCheck.add(mavenProject.getParent());
84 }
85 }
86
87 if (files.isEmpty()) {
88 throw new MojoExecutionException("No project base directories found! Are you sure you're "
89 + "executing this on a valid Maven project?");
90 }
91
92 Collections.sort(files, new PathComparator());
93 final File dir = files.get(0);
94
95 if (files.size() > 1) {
96 final File next = files.get(1);
97 String dirPath = dir.getAbsolutePath();
98 String nextPath = next.getAbsolutePath();
99 if (System.getProperty("os.name").startsWith("Windows")) {
100 dirPath = dirPath.toLowerCase(Locale.ENGLISH);
101 nextPath = nextPath.toLowerCase(Locale.ENGLISH);
102 }
103 if (!nextPath.startsWith(dirPath)) {
104 getLog().error("Candidate 1: " + dirPath);
105 getLog().error("Candidate 2: " + nextPath);
106 throw new MojoExecutionException("Cannot find a single highest directory for this project set. "
107 + "First two candidates directories don't share a common root." + " Candidate 1: " + dirPath
108 + " Candidate 2: " + nextPath);
109 }
110 }
111
112 return dir;
113 }
114
115 @Override
116 protected String getContextKey() {
117 return HIGHEST_DIR_CONTEXT_KEY;
118 }
119
120 @Override
121 protected String getLogLabel() {
122 return "Highest basedir";
123 }
124
125 }