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));
 

Reply via email to