|
7 | 7 | * %% |
8 | 8 | * Redistribution and use in source and binary forms, with or without |
9 | 9 | * modification, are permitted provided that the following conditions are met: |
10 | | - * |
| 10 | + * |
11 | 11 | * 1. Redistributions of source code must retain the above copyright notice, |
12 | 12 | * this list of conditions and the following disclaimer. |
13 | 13 | * 2. Redistributions in binary form must reproduce the above copyright notice, |
14 | 14 | * this list of conditions and the following disclaimer in the documentation |
15 | 15 | * and/or other materials provided with the distribution. |
16 | | - * |
| 16 | + * |
17 | 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
18 | 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
19 | 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
30 | 30 |
|
31 | 31 | package org.scijava.maven.plugin; |
32 | 32 |
|
| 33 | +import java.io.File; |
| 34 | +import java.util.ArrayList; |
| 35 | +import java.util.HashSet; |
| 36 | +import java.util.List; |
| 37 | +import java.util.Properties; |
| 38 | +import java.util.Set; |
| 39 | + |
33 | 40 | import org.apache.maven.artifact.Artifact; |
34 | 41 | import org.apache.maven.artifact.repository.ArtifactRepository; |
35 | 42 | import org.apache.maven.artifact.resolver.filter.AndArtifactFilter; |
36 | 43 | import org.apache.maven.artifact.resolver.filter.ArtifactFilter; |
37 | 44 | import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; |
| 45 | +import org.apache.maven.execution.MavenSession; |
| 46 | +import org.apache.maven.profiles.DefaultProfileManager; |
| 47 | +import org.apache.maven.profiles.ProfileManager; |
38 | 48 | import org.apache.maven.project.MavenProject; |
| 49 | +import org.apache.maven.project.MavenProjectBuilder; |
| 50 | +import org.apache.maven.project.ProjectBuildingException; |
39 | 51 | import org.apache.maven.shared.dependency.tree.DependencyNode; |
40 | 52 | import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder; |
41 | 53 | import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException; |
| 54 | +import org.codehaus.plexus.PlexusContainer; |
42 | 55 |
|
43 | 56 | /** |
44 | 57 | * Utility class for initiating Maven-based dependency checks. |
@@ -126,8 +139,91 @@ public static void checkDependencies(final MavenProject mavenProject, |
126 | 139 | } |
127 | 140 | } |
128 | 141 |
|
| 142 | + /** |
| 143 | + * Manually constructs an list of effective reactor projects by recursively |
| 144 | + * searching parent and submodule projects. This allows the intention of the |
| 145 | + * reactor to be preserved, as long as it is fully available on disk, even |
| 146 | + * when building a submodule directly. |
| 147 | + * |
| 148 | + * @param defaultReactor Return value to use if a comprehensive list can not |
| 149 | + * be discovered. |
| 150 | + * @param baseProject {@link MavenProject} where invocation started. |
| 151 | + * @return A list of MavenProjects that can be treated as though within the |
| 152 | + * current reactor. |
| 153 | + * @throws ProjectBuildingException |
| 154 | + */ |
| 155 | + public static List<MavenProject> findEffectiveReactor( |
| 156 | + final List<MavenProject> defaultReactor, final MavenSession session, |
| 157 | + final MavenProject baseProject, final MavenProjectBuilder projectBuilder, |
| 158 | + final ArtifactRepository localRepository) throws ProjectBuildingException |
| 159 | + { |
| 160 | + final Set<MavenProject> reactor = new HashSet<MavenProject>(); |
| 161 | + final Set<MavenProject> visited = new HashSet<MavenProject>(); |
| 162 | + final ProfileManager profileManager = getProfileManager(session); |
| 163 | + |
| 164 | + findEffectiveReactor(reactor, visited, baseProject, baseProject, |
| 165 | + projectBuilder, localRepository, profileManager); |
| 166 | + |
| 167 | + if (reactor.size() <= 1 || !reactor.contains(baseProject)) return defaultReactor; |
| 168 | + return new ArrayList<MavenProject>(reactor); |
| 169 | + } |
| 170 | + |
129 | 171 | // -- Helper methods -- |
130 | 172 |
|
| 173 | + /** |
| 174 | + * Helper method to recursively populate a set of {@link MavenProject}s that |
| 175 | + * can be considered to be within the same reactor. |
| 176 | + */ |
| 177 | + private static void findEffectiveReactor(final Set<MavenProject> reactor, |
| 178 | + final Set<MavenProject> visited, final MavenProject currentProject, |
| 179 | + final MavenProject target, final MavenProjectBuilder projectBuilder, |
| 180 | + final ArtifactRepository localRepository, |
| 181 | + final ProfileManager profileManager) throws ProjectBuildingException |
| 182 | + { |
| 183 | + // short-circuit if already visited this project |
| 184 | + if (!visited.add(currentProject)) return; |
| 185 | + |
| 186 | + final File baseDir = currentProject.getBasedir(); |
| 187 | + |
| 188 | + // We only are interested in local projects |
| 189 | + if (baseDir != null && baseDir.exists()) { |
| 190 | + |
| 191 | + // If the current project lists any modules , then that project itself |
| 192 | + // needs to be included in the reactor |
| 193 | + if (currentProject.getModules().size() > 0) { |
| 194 | + reactor.add(currentProject); |
| 195 | + } |
| 196 | + |
| 197 | + // Recursively add each submodule to the reactor |
| 198 | + for (final Object o : currentProject.getModules()) { |
| 199 | + final File submodule = |
| 200 | + new File(baseDir.getAbsolutePath() + File.separator + o.toString() + |
| 201 | + File.separator + "pom.xml"); |
| 202 | + final MavenProject p = |
| 203 | + projectBuilder.build(submodule, localRepository, profileManager); |
| 204 | + reactor.add(p); |
| 205 | + findEffectiveReactor(reactor, visited, p, target, projectBuilder, |
| 206 | + localRepository, profileManager); |
| 207 | + } |
| 208 | + } |
| 209 | + |
| 210 | + // Recurse into parent |
| 211 | + if (currentProject.hasParent()) findEffectiveReactor(reactor, visited, |
| 212 | + currentProject.getParent(), target, projectBuilder, localRepository, |
| 213 | + profileManager); |
| 214 | + } |
| 215 | + |
| 216 | + /** |
| 217 | + * Convenience method to get the {@link ProfileManager} for a given |
| 218 | + * {@link MavenSession}. |
| 219 | + */ |
| 220 | + @SuppressWarnings("deprecation") |
| 221 | + private static ProfileManager getProfileManager(final MavenSession session) { |
| 222 | + final PlexusContainer container = session.getContainer(); |
| 223 | + final Properties execution = session.getExecutionProperties(); |
| 224 | + return new DefaultProfileManager(container, execution); |
| 225 | + } |
| 226 | + |
131 | 227 | /** |
132 | 228 | * Helper method to build an {@link ArtifactFilter}. Multiple filters can be |
133 | 229 | * unioned together via the {@link AndArtifactFilter}. |
|
0 commit comments