1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.graph;
20
21 import java.io.File;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collection;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.stream.Collectors;
28 import java.util.stream.Stream;
29
30 import org.apache.maven.MavenExecutionException;
31 import org.apache.maven.execution.BuildResumptionDataRepository;
32 import org.apache.maven.execution.MavenExecutionRequest;
33 import org.apache.maven.execution.MavenSession;
34 import org.apache.maven.execution.ProjectActivation;
35 import org.apache.maven.execution.ProjectDependencyGraph;
36 import org.apache.maven.model.Dependency;
37 import org.apache.maven.model.Parent;
38 import org.apache.maven.model.building.Result;
39 import org.apache.maven.model.locator.DefaultModelLocator;
40 import org.apache.maven.model.locator.ModelLocator;
41 import org.apache.maven.project.MavenProject;
42 import org.apache.maven.project.ProjectBuilder;
43 import org.apache.maven.project.ProjectBuildingException;
44 import org.apache.maven.project.ProjectBuildingRequest;
45 import org.apache.maven.project.ProjectBuildingResult;
46 import org.apache.maven.project.collector.DefaultProjectsSelector;
47 import org.apache.maven.project.collector.MultiModuleCollectionStrategy;
48 import org.apache.maven.project.collector.PomlessCollectionStrategy;
49 import org.apache.maven.project.collector.ProjectsSelector;
50 import org.apache.maven.project.collector.RequestPomCollectionStrategy;
51 import org.junit.jupiter.api.BeforeEach;
52 import org.junit.jupiter.api.Test;
53 import org.junit.jupiter.params.ParameterizedTest;
54 import org.junit.jupiter.params.provider.Arguments;
55 import org.junit.jupiter.params.provider.MethodSource;
56
57 import static java.util.Arrays.asList;
58 import static java.util.Collections.emptyList;
59 import static java.util.Collections.singletonList;
60 import static java.util.function.Function.identity;
61 import static java.util.stream.Collectors.toList;
62 import static org.apache.maven.execution.MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM;
63 import static org.apache.maven.execution.MavenExecutionRequest.REACTOR_MAKE_UPSTREAM;
64 import static org.apache.maven.graph.DefaultGraphBuilderTest.ScenarioBuilder.scenario;
65 import static org.assertj.core.api.Assertions.assertThat;
66 import static org.junit.jupiter.api.Assertions.assertEquals;
67 import static org.mockito.ArgumentMatchers.any;
68 import static org.mockito.ArgumentMatchers.anyBoolean;
69 import static org.mockito.ArgumentMatchers.anyList;
70 import static org.mockito.Mockito.mock;
71 import static org.mockito.Mockito.when;
72
73 class DefaultGraphBuilderTest {
74
75
76
77
78
79
80
81
82
83
84
85
86 private static final String GROUP_ID = "unittest";
87 private static final String PARENT_MODULE = "module-parent";
88 private static final String INDEPENDENT_MODULE = "module-independent";
89 private static final String MODULE_A = "module-a";
90 private static final String MODULE_B = "module-b";
91 private static final String MODULE_C = "module-c";
92 private static final String MODULE_D = "module-d";
93 private static final String MODULE_C_1 = "module-c-1";
94 private static final String MODULE_C_2 = "module-c-2";
95
96 private DefaultGraphBuilder graphBuilder;
97
98 private final ProjectBuilder projectBuilder = mock(ProjectBuilder.class);
99 private final MavenSession session = mock(MavenSession.class);
100 private final MavenExecutionRequest mavenExecutionRequest = mock(MavenExecutionRequest.class);
101
102 private final ProjectsSelector projectsSelector = new DefaultProjectsSelector(projectBuilder);
103
104
105
106 private final ModelLocator modelLocator = new DefaultModelLocator();
107 private final PomlessCollectionStrategy pomlessCollectionStrategy = new PomlessCollectionStrategy(projectBuilder);
108 private final MultiModuleCollectionStrategy multiModuleCollectionStrategy =
109 new MultiModuleCollectionStrategy(modelLocator, projectsSelector);
110 private final RequestPomCollectionStrategy requestPomCollectionStrategy =
111 new RequestPomCollectionStrategy(projectsSelector);
112
113 private Map<String, MavenProject> artifactIdProjectMap;
114
115 public static Stream<Arguments> parameters() {
116 return Stream.of(
117 scenario("Full reactor in order")
118 .expectResult(
119 PARENT_MODULE,
120 MODULE_C,
121 MODULE_C_1,
122 MODULE_A,
123 MODULE_B,
124 MODULE_C_2,
125 INDEPENDENT_MODULE),
126 scenario("Selected project").activeRequiredProjects(MODULE_B).expectResult(MODULE_B),
127 scenario("Selected aggregator project (including child modules)")
128 .activeRequiredProjects(MODULE_C)
129 .expectResult(MODULE_C, MODULE_C_1, MODULE_C_2),
130 scenario("Selected aggregator project with non-recursive")
131 .activeRequiredProjects(MODULE_C)
132 .nonRecursive()
133 .expectResult(MODULE_C),
134 scenario("Selected optional project")
135 .activeOptionalProjects(MODULE_B)
136 .expectResult(MODULE_B),
137 scenario("Selected missing optional project")
138 .activeOptionalProjects("non-existing-module")
139 .expectResult(
140 PARENT_MODULE,
141 MODULE_C,
142 MODULE_C_1,
143 MODULE_A,
144 MODULE_B,
145 MODULE_C_2,
146 INDEPENDENT_MODULE),
147 scenario("Selected missing optional and required project")
148 .activeOptionalProjects("non-existing-module")
149 .activeRequiredProjects(MODULE_B)
150 .expectResult(MODULE_B),
151 scenario("Excluded project")
152 .inactiveRequiredProjects(MODULE_B)
153 .expectResult(PARENT_MODULE, MODULE_C, MODULE_C_1, MODULE_A, MODULE_C_2, INDEPENDENT_MODULE),
154 scenario("Excluded optional project")
155 .inactiveOptionalProjects(MODULE_B)
156 .expectResult(PARENT_MODULE, MODULE_C, MODULE_C_1, MODULE_A, MODULE_C_2, INDEPENDENT_MODULE),
157 scenario("Excluded missing optional project")
158 .inactiveOptionalProjects("non-existing-module")
159 .expectResult(
160 PARENT_MODULE,
161 MODULE_C,
162 MODULE_C_1,
163 MODULE_A,
164 MODULE_B,
165 MODULE_C_2,
166 INDEPENDENT_MODULE),
167 scenario("Excluded missing optional and required project")
168 .inactiveOptionalProjects("non-existing-module")
169 .inactiveRequiredProjects(MODULE_B)
170 .expectResult(PARENT_MODULE, MODULE_C, MODULE_C_1, MODULE_A, MODULE_C_2, INDEPENDENT_MODULE),
171 scenario("Excluded aggregator project with non-recursive")
172 .inactiveRequiredProjects(MODULE_C)
173 .nonRecursive()
174 .expectResult(PARENT_MODULE, MODULE_C_1, MODULE_A, MODULE_B, MODULE_C_2, INDEPENDENT_MODULE),
175 scenario("Selected and excluded same project")
176 .activeRequiredProjects(MODULE_A)
177 .inactiveRequiredProjects(MODULE_A)
178 .expectResult(MavenExecutionException.class, "empty reactor"),
179 scenario("Excluded aggregator, but selected child")
180 .activeRequiredProjects(MODULE_C_1)
181 .inactiveRequiredProjects(MODULE_C)
182 .expectResult(MavenExecutionException.class, "empty reactor"),
183 scenario("Project selected with different selector resolves to same project")
184 .activeRequiredProjects(GROUP_ID + ":" + MODULE_A)
185 .inactiveRequiredProjects(MODULE_A)
186 .expectResult(MavenExecutionException.class, "empty reactor"),
187 scenario("Selected and excluded same project, but also selected another project")
188 .activeRequiredProjects(MODULE_A, MODULE_B)
189 .inactiveRequiredProjects(MODULE_A)
190 .expectResult(MODULE_B),
191 scenario("Selected missing project as required and as optional")
192 .activeRequiredProjects("non-existing-module")
193 .activeOptionalProjects("non-existing-module")
194 .expectResult(MavenExecutionException.class, "not find the selected project"),
195 scenario("Resuming from project")
196 .resumeFrom(MODULE_B)
197 .expectResult(MODULE_B, MODULE_C_2, INDEPENDENT_MODULE),
198 scenario("Selected project with also make dependencies")
199 .activeRequiredProjects(MODULE_C_2)
200 .makeBehavior(REACTOR_MAKE_UPSTREAM)
201 .expectResult(PARENT_MODULE, MODULE_C, MODULE_A, MODULE_B, MODULE_C_2),
202 scenario("Selected project with also make dependents")
203 .activeRequiredProjects(MODULE_B)
204 .makeBehavior(REACTOR_MAKE_DOWNSTREAM)
205 .expectResult(MODULE_B, MODULE_C_2),
206 scenario("Resuming from project with also make dependencies")
207 .makeBehavior(REACTOR_MAKE_UPSTREAM)
208 .resumeFrom(MODULE_C_2)
209 .expectResult(PARENT_MODULE, MODULE_C, MODULE_A, MODULE_B, MODULE_C_2, INDEPENDENT_MODULE),
210 scenario("Selected project with resume from and also make dependency (MNG-4960 IT#1)")
211 .activeRequiredProjects(MODULE_C_2)
212 .resumeFrom(MODULE_B)
213 .makeBehavior(REACTOR_MAKE_UPSTREAM)
214 .expectResult(PARENT_MODULE, MODULE_C, MODULE_A, MODULE_B, MODULE_C_2),
215 scenario("Selected project with resume from and also make dependent (MNG-4960 IT#2)")
216 .activeRequiredProjects(MODULE_B)
217 .resumeFrom(MODULE_C_2)
218 .makeBehavior(REACTOR_MAKE_DOWNSTREAM)
219 .expectResult(MODULE_C_2),
220 scenario("Excluding an also make dependency from selectedProject does take its transitive dependency")
221 .activeRequiredProjects(MODULE_C_2)
222 .inactiveRequiredProjects(MODULE_B)
223 .makeBehavior(REACTOR_MAKE_UPSTREAM)
224 .expectResult(PARENT_MODULE, MODULE_C, MODULE_A, MODULE_C_2),
225 scenario("Excluding a project also excludes its children")
226 .inactiveRequiredProjects(MODULE_C)
227 .expectResult(PARENT_MODULE, MODULE_A, MODULE_B, INDEPENDENT_MODULE),
228 scenario("Excluding an also make dependency from resumeFrom does take its transitive dependency")
229 .resumeFrom(MODULE_C_2)
230 .inactiveRequiredProjects(MODULE_B)
231 .makeBehavior(REACTOR_MAKE_UPSTREAM)
232 .expectResult(PARENT_MODULE, MODULE_C, MODULE_A, MODULE_C_2, INDEPENDENT_MODULE),
233 scenario("Resume from exclude project downstream")
234 .resumeFrom(MODULE_A)
235 .inactiveRequiredProjects(MODULE_B)
236 .expectResult(MODULE_A, MODULE_C_2, INDEPENDENT_MODULE),
237 scenario("Exclude the project we are resuming from (as proposed in MNG-6676)")
238 .resumeFrom(MODULE_B)
239 .inactiveRequiredProjects(MODULE_B)
240 .expectResult(MODULE_C_2, INDEPENDENT_MODULE),
241 scenario("Selected projects in wrong order are resumed correctly in order")
242 .activeRequiredProjects(MODULE_C_2, MODULE_B, MODULE_A)
243 .resumeFrom(MODULE_B)
244 .expectResult(MODULE_B, MODULE_C_2),
245 scenario("Duplicate projects are filtered out")
246 .activeRequiredProjects(MODULE_A, MODULE_A)
247 .expectResult(MODULE_A),
248 scenario("Select reactor by specific pom")
249 .requestedPom(MODULE_C)
250 .expectResult(MODULE_C, MODULE_C_1, MODULE_C_2),
251 scenario("Select reactor by specific pom with also make dependencies")
252 .requestedPom(MODULE_C)
253 .makeBehavior(REACTOR_MAKE_UPSTREAM)
254 .expectResult(PARENT_MODULE, MODULE_C, MODULE_C_1, MODULE_A, MODULE_B, MODULE_C_2),
255 scenario("Select reactor by specific pom with also make dependents")
256 .requestedPom(MODULE_B)
257 .makeBehavior(REACTOR_MAKE_DOWNSTREAM)
258 .expectResult(MODULE_B, MODULE_C_2));
259 }
260
261 interface ExpectedResult {}
262
263 static class SelectedProjectsResult implements ExpectedResult {
264 final List<String> projectNames;
265
266 public SelectedProjectsResult(List<String> projectSelectors) {
267 this.projectNames = projectSelectors;
268 }
269 }
270
271 static class ExceptionThrown implements ExpectedResult {
272 final Class<? extends Throwable> expected;
273 final String partOfMessage;
274
275 public ExceptionThrown(final Class<? extends Throwable> expected, final String partOfMessage) {
276 this.expected = expected;
277 this.partOfMessage = partOfMessage;
278 }
279 }
280
281 @ParameterizedTest
282 @MethodSource("parameters")
283 void testGetReactorProjects(
284 String parameterDescription,
285 List<String> parameterActiveRequiredProjects,
286 List<String> parameterActiveOptionalProjects,
287 List<String> parameterInactiveRequiredProjects,
288 List<String> parameterInactiveOptionalProjects,
289 String parameterResumeFrom,
290 String parameterMakeBehavior,
291 ExpectedResult parameterExpectedResult,
292 File parameterRequestedPom,
293 boolean parameterRecursive) {
294
295 ProjectActivation projectActivation = new ProjectActivation();
296 parameterActiveRequiredProjects.forEach(projectActivation::activateRequiredProject);
297 parameterActiveOptionalProjects.forEach(projectActivation::activateOptionalProject);
298 parameterInactiveRequiredProjects.forEach(projectActivation::deactivateRequiredProject);
299 parameterInactiveOptionalProjects.forEach(projectActivation::deactivateOptionalProject);
300
301 when(mavenExecutionRequest.getProjectActivation()).thenReturn(projectActivation);
302 when(mavenExecutionRequest.getMakeBehavior()).thenReturn(parameterMakeBehavior);
303 when(mavenExecutionRequest.getPom()).thenReturn(parameterRequestedPom);
304 when(mavenExecutionRequest.isRecursive()).thenReturn(parameterRecursive);
305 if (parameterResumeFrom != null && !parameterResumeFrom.isEmpty()) {
306 when(mavenExecutionRequest.getResumeFrom()).thenReturn(":" + parameterResumeFrom);
307 }
308
309
310 Result<ProjectDependencyGraph> result = graphBuilder.build(session);
311
312
313 if (parameterExpectedResult instanceof SelectedProjectsResult) {
314 assertThat(result.hasErrors())
315 .withFailMessage("Expected result not to have errors")
316 .isFalse();
317 List<String> expectedProjectNames = ((SelectedProjectsResult) parameterExpectedResult).projectNames;
318 List<MavenProject> actualReactorProjects = result.get().getSortedProjects();
319 List<MavenProject> expectedReactorProjects =
320 expectedProjectNames.stream().map(artifactIdProjectMap::get).collect(toList());
321 assertEquals(expectedReactorProjects, actualReactorProjects, parameterDescription);
322 } else {
323 assertThat(result.hasErrors())
324 .withFailMessage("Expected result to have errors")
325 .isTrue();
326 Class<? extends Throwable> expectedException = ((ExceptionThrown) parameterExpectedResult).expected;
327 String partOfMessage = ((ExceptionThrown) parameterExpectedResult).partOfMessage;
328
329 assertThat(result.getProblems()).hasSize(1);
330 result.getProblems().forEach(p -> assertThat(p.getException())
331 .isInstanceOf(expectedException)
332 .hasMessageContaining(partOfMessage));
333 }
334 }
335
336 @Test
337 void testProcessPackagingAttribute() throws ProjectBuildingException {
338 graphBuilder = new DefaultGraphBuilder(
339 mock(BuildResumptionDataRepository.class),
340 pomlessCollectionStrategy,
341 multiModuleCollectionStrategy,
342 requestPomCollectionStrategy);
343
344
345 MavenProject projectParent = getMavenProject(PARENT_MODULE);
346 MavenProject projectModuleD = getMavenProject(MODULE_D, projectParent, "bom");
347
348 projectParent.setCollectedProjects(singletonList(projectModuleD));
349
350
351 when(session.getRequest()).thenReturn(mavenExecutionRequest);
352 when(session.getProjects()).thenReturn(null);
353 when(mavenExecutionRequest.getProjectBuildingRequest()).thenReturn(mock(ProjectBuildingRequest.class));
354 List<ProjectBuildingResult> projectBuildingResults =
355 createProjectBuildingResultMocks(Stream.of(projectParent, projectModuleD)
356 .collect(Collectors.toMap(MavenProject::getArtifactId, identity()))
357 .values());
358 when(projectBuilder.build(anyList(), anyBoolean(), any(ProjectBuildingRequest.class)))
359 .thenReturn(projectBuildingResults);
360
361 ProjectActivation projectActivation = new ProjectActivation();
362
363 when(mavenExecutionRequest.getProjectActivation()).thenReturn(projectActivation);
364 when(mavenExecutionRequest.getPom()).thenReturn(new File(PARENT_MODULE, "pom.xml"));
365
366 Result<ProjectDependencyGraph> result = graphBuilder.build(session);
367
368 assertThat(result.hasErrors())
369 .withFailMessage("Expected result not to have errors")
370 .isFalse();
371 List<MavenProject> actualReactorProjects = result.get().getSortedProjects();
372 assertEquals(2, actualReactorProjects.size());
373 assertEquals("pom", actualReactorProjects.get(1).getPackaging());
374 }
375
376 @BeforeEach
377 void before() throws Exception {
378 graphBuilder = new DefaultGraphBuilder(
379 mock(BuildResumptionDataRepository.class),
380 pomlessCollectionStrategy,
381 multiModuleCollectionStrategy,
382 requestPomCollectionStrategy);
383
384
385 MavenProject projectParent = getMavenProject(PARENT_MODULE);
386 MavenProject projectIndependentModule = getMavenProject(INDEPENDENT_MODULE);
387 MavenProject projectModuleA = getMavenProject(MODULE_A, projectParent);
388 MavenProject projectModuleB = getMavenProject(MODULE_B, projectParent);
389 MavenProject projectModuleC = getMavenProject(MODULE_C, projectParent);
390 MavenProject projectModuleC1 = getMavenProject(MODULE_C_1, projectModuleC);
391 MavenProject projectModuleC2 = getMavenProject(MODULE_C_2, projectModuleC);
392
393 artifactIdProjectMap = Stream.of(
394 projectParent,
395 projectIndependentModule,
396 projectModuleA,
397 projectModuleB,
398 projectModuleC,
399 projectModuleC1,
400 projectModuleC2)
401 .collect(Collectors.toMap(MavenProject::getArtifactId, identity()));
402
403
404 projectModuleB.setDependencies(singletonList(toDependency(projectModuleA)));
405 projectModuleC2.setDependencies(singletonList(toDependency(projectModuleB)));
406 projectParent.setCollectedProjects(asList(
407 projectIndependentModule,
408 projectModuleA,
409 projectModuleB,
410 projectModuleC,
411 projectModuleC1,
412 projectModuleC2));
413 projectModuleC.setCollectedProjects(asList(projectModuleC1, projectModuleC2));
414
415
416 when(session.getRequest()).thenReturn(mavenExecutionRequest);
417 when(session.getProjects()).thenReturn(null);
418 when(mavenExecutionRequest.getProjectBuildingRequest()).thenReturn(mock(ProjectBuildingRequest.class));
419 List<ProjectBuildingResult> projectBuildingResults =
420 createProjectBuildingResultMocks(artifactIdProjectMap.values());
421 when(projectBuilder.build(anyList(), anyBoolean(), any(ProjectBuildingRequest.class)))
422 .thenReturn(projectBuildingResults);
423 }
424
425 private MavenProject getMavenProject(String artifactId, MavenProject parentProject) {
426 MavenProject project = getMavenProject(artifactId);
427 Parent parent = new Parent();
428 parent.setGroupId(parentProject.getGroupId());
429 parent.setArtifactId(parentProject.getArtifactId());
430 project.getModel().setParent(parent);
431 return project;
432 }
433
434 private MavenProject getMavenProject(String artifactId) {
435 MavenProject mavenProject = new MavenProject();
436 mavenProject.setGroupId(GROUP_ID);
437 mavenProject.setArtifactId(artifactId);
438 mavenProject.setVersion("1.0");
439 mavenProject.setPomFile(new File(artifactId, "pom.xml"));
440 mavenProject.setCollectedProjects(new ArrayList<>());
441 return mavenProject;
442 }
443
444 private MavenProject getMavenProject(String artifactId, MavenProject parentProject, String packaging) {
445 MavenProject project = getMavenProject(artifactId);
446 Parent parent = new Parent();
447 parent.setGroupId(parentProject.getGroupId());
448 parent.setArtifactId(parentProject.getArtifactId());
449 project.getModel().setParent(parent);
450 project.setPackaging(packaging);
451 return project;
452 }
453
454 private Dependency toDependency(MavenProject mavenProject) {
455 Dependency dependency = new Dependency();
456 dependency.setGroupId(mavenProject.getGroupId());
457 dependency.setArtifactId(mavenProject.getArtifactId());
458 dependency.setVersion(mavenProject.getVersion());
459 return dependency;
460 }
461
462 private List<ProjectBuildingResult> createProjectBuildingResultMocks(Collection<MavenProject> projects) {
463 return projects.stream()
464 .map(project -> {
465 ProjectBuildingResult result = mock(ProjectBuildingResult.class);
466 when(result.getProject()).thenReturn(project);
467 return result;
468 })
469 .collect(toList());
470 }
471
472 static class ScenarioBuilder {
473 private String description;
474 private List<String> activeRequiredProjects = emptyList();
475 private List<String> activeOptionalProjects = emptyList();
476 private List<String> inactiveRequiredProjects = emptyList();
477 private List<String> inactiveOptionalProjects = emptyList();
478 private String resumeFrom = "";
479 private String makeBehavior = "";
480 private File requestedPom = new File(PARENT_MODULE, "pom.xml");
481 private boolean recursive = true;
482
483 private ScenarioBuilder() {}
484
485 public static ScenarioBuilder scenario(String description) {
486 ScenarioBuilder scenarioBuilder = new ScenarioBuilder();
487 scenarioBuilder.description = description;
488 return scenarioBuilder;
489 }
490
491 public ScenarioBuilder activeRequiredProjects(String... activeRequiredProjects) {
492 this.activeRequiredProjects = prependWithColonIfNeeded(activeRequiredProjects);
493 return this;
494 }
495
496 public ScenarioBuilder activeOptionalProjects(String... activeOptionalProjects) {
497 this.activeOptionalProjects = prependWithColonIfNeeded(activeOptionalProjects);
498 return this;
499 }
500
501 public ScenarioBuilder inactiveRequiredProjects(String... inactiveRequiredProjects) {
502 this.inactiveRequiredProjects = prependWithColonIfNeeded(inactiveRequiredProjects);
503 return this;
504 }
505
506 public ScenarioBuilder inactiveOptionalProjects(String... inactiveOptionalProjects) {
507 this.inactiveOptionalProjects = prependWithColonIfNeeded(inactiveOptionalProjects);
508 return this;
509 }
510
511 public ScenarioBuilder resumeFrom(String resumeFrom) {
512 this.resumeFrom = resumeFrom;
513 return this;
514 }
515
516 public ScenarioBuilder makeBehavior(String makeBehavior) {
517 this.makeBehavior = makeBehavior;
518 return this;
519 }
520
521 public ScenarioBuilder requestedPom(String requestedPom) {
522 this.requestedPom = new File(requestedPom, "pom.xml");
523 return this;
524 }
525
526 public ScenarioBuilder nonRecursive() {
527 this.recursive = false;
528 return this;
529 }
530
531 public Arguments expectResult(String... expectedReactorProjects) {
532 ExpectedResult expectedResult = new SelectedProjectsResult(asList(expectedReactorProjects));
533 return createTestArguments(expectedResult);
534 }
535
536 public Arguments expectResult(Class<? extends Exception> expected, final String partOfMessage) {
537 ExpectedResult expectedResult = new ExceptionThrown(expected, partOfMessage);
538 return createTestArguments(expectedResult);
539 }
540
541 private Arguments createTestArguments(ExpectedResult expectedResult) {
542 return Arguments.arguments(
543 description,
544 activeRequiredProjects,
545 activeOptionalProjects,
546 inactiveRequiredProjects,
547 inactiveOptionalProjects,
548 resumeFrom,
549 makeBehavior,
550 expectedResult,
551 requestedPom,
552 recursive);
553 }
554
555 private List<String> prependWithColonIfNeeded(String[] selectors) {
556 return Arrays.stream(selectors).map(this::prependWithColonIfNeeded).collect(toList());
557 }
558
559 private String prependWithColonIfNeeded(String selector) {
560 return selector.indexOf(':') == -1 ? ":" + selector : selector;
561 }
562 }
563 }