This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/maven.git
commit c6b008b507cc5efaedca2aaa3dd69912b027e684 Author: Martin Desruisseaux <[email protected]> AuthorDate: Sun Oct 26 00:16:55 2025 +0200 Add a `Project.getOutputDirectory(ProjectScope)` for avoiding the need to repeat the same code in the plugins. The `SourceRoot.targetPath(Project)` method become simpler, delegating most of the work to the new method. --- .../main/java/org/apache/maven/api/Project.java | 30 ++++++++++++++++++ .../main/java/org/apache/maven/api/SourceRoot.java | 36 ++++++++-------------- .../java/org/apache/maven/api/SourceRootTest.java | 2 ++ 3 files changed, 44 insertions(+), 24 deletions(-) diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java index 8e989ad4ae..2fb4f4f7ba 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java @@ -24,6 +24,7 @@ import org.apache.maven.api.annotations.Experimental; import org.apache.maven.api.annotations.Nonnull; +import org.apache.maven.api.annotations.Nullable; import org.apache.maven.api.model.Build; import org.apache.maven.api.model.Model; import org.apache.maven.api.model.Profile; @@ -172,6 +173,35 @@ default Build getBuild() { @Nonnull Path getBasedir(); + /** + * Returns the directory where files generated by the build are placed. + * The directory depends on the scope: + * + * <ul> + * <li>If {@link ProjectScope#MAIN}, returns the directory where compiled application classes are placed.</li> + * <li>If {@link ProjectScope#TEST}, returns the directory where compiled test classes are placed.</li> + * <li>Otherwise (including {@code null}), returns the parent directory where all generated files are placed.</li> + * </ul> + * + * @param scope the scope of the generated files for which to get the directory, or {@code null} for all + * @return the output directory of files that are generated for the given scope + * + * @see SourceRoot#targetPath(Project) + */ + @Nonnull + default Path getOutputDirectory(@Nullable ProjectScope scope) { + String dir; + Build build = getBuild(); + if (scope == ProjectScope.MAIN) { + dir = build.getOutputDirectory(); + } else if (scope == ProjectScope.TEST) { + dir = build.getTestOutputDirectory(); + } else { + dir = build.getDirectory(); + } + return getBasedir().resolve(dir); + } + /** * {@return the project direct dependencies (directly specified or inherited)}. */ diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/SourceRoot.java b/api/maven-api-core/src/main/java/org/apache/maven/api/SourceRoot.java index c8b4d3b771..12ac480044 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/SourceRoot.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/SourceRoot.java @@ -25,7 +25,6 @@ import java.util.Optional; import org.apache.maven.api.annotations.Nonnull; -import org.apache.maven.api.model.Build; /** * A root directory of source files. @@ -156,34 +155,23 @@ default Optional<Path> targetPath() { /** * {@return the explicit target path resolved against the default target path} - * If the {@linkplain #targetPath() explicit target path} is present and absolute, then it is returned as-is. - * If absent, then the one of the following value is returned by default: - * - * <ul> - * <li>{@link Build#getOutputDirectory()} if the scope is {@link ProjectScope#MAIN},</li> - * <li>{@link Build#getTestOutputDirectory()} if the scope is {@link ProjectScope#TEST},</li> - * <li>{@link Build#getDirectory()} otherwise.</li> - * </ul> - * - * If the {@linkplain #targetPath() explicit target path} is present but relative, - * then it is resolved against the above-cited default directory. + * Invoking this method is equivalent to getting the default output directory + * by a call to {@code project.getOutputDirectory(scope())}, then resolving the + * {@linkplain #targetPath() target path} (if present) against that default directory. + * Note that if the target path is absolute, the result is that target path unchanged. * * @param project the project to use for getting default directories + * + * @see Project#getOutputDirectory(ProjectScope) */ @Nonnull default Path targetPath(@Nonnull Project project) { - Build build = project.getBuild(); - ProjectScope scope = scope(); - String base; - if (scope == ProjectScope.MAIN) { - base = build.getOutputDirectory(); - } else if (scope == ProjectScope.TEST) { - base = build.getTestOutputDirectory(); - } else { - base = build.getDirectory(); - } - Path dir = project.getBasedir().resolve(base); - return targetPath().map(dir::resolve).orElse(dir); + Optional<Path> targetPath = targetPath(); + // The test for `isAbsolute()` is a small optimization for avoiding the call to `getOutputDirectory(…)`. + return targetPath.filter(Path::isAbsolute).orElseGet(() -> { + Path base = project.getOutputDirectory(scope()); + return targetPath.map(base::resolve).orElse(base); + }); } /** diff --git a/api/maven-api-core/src/test/java/org/apache/maven/api/SourceRootTest.java b/api/maven-api-core/src/test/java/org/apache/maven/api/SourceRootTest.java index 9f65f5d0af..a316550aee 100644 --- a/api/maven-api-core/src/test/java/org/apache/maven/api/SourceRootTest.java +++ b/api/maven-api-core/src/test/java/org/apache/maven/api/SourceRootTest.java @@ -27,6 +27,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -78,6 +79,7 @@ void testTargetPath() { Project project = mock(Project.class); when(project.getBuild()).thenReturn(build); when(project.getBasedir()).thenReturn(Path.of("myproject")); + when(project.getOutputDirectory(any(ProjectScope.class))).thenCallRealMethod(); assertEquals(Path.of("myproject", "target", "classes"), targetPath(project));
