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


The following commit(s) were added to refs/heads/master by this push:
     new 9a088c602b [MNG-8647] Set the default source directory to 
`src/${scope}/${lang}` as per documentation (#2180)
9a088c602b is described below

commit 9a088c602b70157a2ec23da1d4e645bbf82517c1
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Thu Mar 27 18:27:54 2025 +0100

    [MNG-8647] Set the default source directory to `src/${scope}/${lang}` as 
per documentation (#2180)
    
    Set the default source directory to `src/${scope}/${lang}` as documented in 
`maven.mdo`.
---
 .../main/java/org/apache/maven/api/SourceRoot.java | 25 +++++++++++++++++++---
 api/maven-api-model/src/main/mdo/maven.mdo         | 16 +++++++-------
 .../org/apache/maven/impl/DefaultSourceRoot.java   | 16 ++++++++------
 3 files changed, 39 insertions(+), 18 deletions(-)

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 35a18c82e6..0b77dbcec5 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
@@ -26,13 +26,24 @@
 /**
  * A root directory of source files.
  * The sources may be Java main classes, test classes, resources or anything 
else identified by the scope.
+ *
+ * <h2>Default values</h2>
+ * The properties in this interface are defined in the {@code <Source>} 
element of the
+ * {@linkplain org.apache.maven.api.model.Model Maven project descriptor}.
+ * For each property, the default value is either empty or documented in the 
project descriptor.
  */
 public interface SourceRoot {
     /**
      * {@return the root directory where the sources are stored}.
      * The path is relative to the <abbr>POM</abbr> file.
+     *
+     * <h4>Default implementation</h4>
+     * The default value is <code>src/{@linkplain #scope() scope}/{@linkplain 
#language() language}</code>
+     * as a relative path. Implementation classes may override this default 
with an absolute path instead.
      */
-    Path directory();
+    default Path directory() {
+        return Path.of("src", scope().id(), language().id());
+    }
 
     /**
      * {@return the list of pattern matchers for the files to include}.
@@ -54,7 +65,10 @@ default List<PathMatcher> excludes() {
 
     /**
      * {@return in which context the source files will be used}.
-     * The default value is {@link ProjectScope#MAIN}.
+     * Not to be confused with dependency scope.
+     * The default value is {@code "main"}.
+     *
+     * @see ProjectScope#MAIN
      */
     default ProjectScope scope() {
         return ProjectScope.MAIN;
@@ -62,8 +76,13 @@ default ProjectScope scope() {
 
     /**
      * {@return the language of the source files}.
+     * The default value is {@code "java"}.
+     *
+     * @see Language#JAVA_FAMILY
      */
-    Language language();
+    default Language language() {
+        return Language.JAVA_FAMILY;
+    }
 
     /**
      * {@return the name of the Java module (or other language-specific 
module) which is built by the sources}.
diff --git a/api/maven-api-model/src/main/mdo/maven.mdo 
b/api/maven-api-model/src/main/mdo/maven.mdo
index 1ba9e93a1f..34cfe87020 100644
--- a/api/maven-api-model/src/main/mdo/maven.mdo
+++ b/api/maven-api-model/src/main/mdo/maven.mdo
@@ -874,9 +874,9 @@
           <version>4.1.0+</version>
           <description>
             All the sources to compile and resources files to copy for a 
project or it's unit tests.
-            The sources can be Java source files, generated source files, 
scripts or resources for examples.
-            Each source is specified by a mandatory {@code directory} element, 
which is relative to the POM.
-            The kind of sources (codes to compile or resources to copy) and 
their usage (for the main code
+            The sources can be Java source files, generated source files, 
scripts, or resources for examples.
+            Each source is specified by a {@code directory} element, which is 
relative to the POM.
+            The kind of sources (source files to compile or resources to copy) 
and their usage (for the main code
             or for the tests) is specified by the {@code scope} element 
together with each source directory.
           </description>
           <association>
@@ -2004,9 +2004,9 @@
       <description>
         <![CDATA[
         Description of the sources associated with a project main code or unit 
tests.
-        The sources can be Java source files, generated source files, scripts 
or resources for examples.
-        A source is specified by a mandatory {@code directory} element, which 
is relative to the POM.
-        The directory content can optionally by reduced to a subset with the 
{@code includes} and
+        The sources can be Java source files, generated source files, scripts, 
or resources for examples.
+        A source is specified by a {@code directory} element, which is 
relative to the POM.
+        The directory content can optionally be reduced to a subset with the 
{@code includes} and
         {@code excludes} elements. The kind of sources (codes, resources, 
<i>etc.</i>) and their
         usage (main code, tests, <i>etc.</i>) is specified by the {@code 
scope} element.
 
@@ -2084,7 +2084,7 @@
             resource file will be copied as {@code 
foo.biz/foo/bar.properties}.</p>
 
             <p>This element can be combined with the {@code targetVersion} 
element for specifying sources,
-            scripts or resources that are specific to both a particular module 
and a target version.</p>
+            scripts, or resources that are specific to both a particular 
module and a target version.</p>
             ]]>
           </description>
           <type>String</type>
@@ -2108,7 +2108,7 @@
             resource file will be copied as {@code 
META-INF/versions/17/foo/bar.properties}.</p>
 
             <p>This element can be combined with the {@code module} element 
for specifying sources,
-            scripts or resources that are specific to both a particular module 
and a target version.</p>
+            scripts, or resources that are specific to both a particular 
module and a target version.</p>
             ]]>
           </description>
           <type>String</type>
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSourceRoot.java 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSourceRoot.java
index 1225ad538c..cc24ee6089 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSourceRoot.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSourceRoot.java
@@ -65,24 +65,26 @@ public final class DefaultSourceRoot implements SourceRoot {
      * @param source a source element from the model
      */
     public DefaultSourceRoot(final Session session, final Path baseDir, final 
Source source) {
-        String value = nonBlank(source.getDirectory());
-        if (value == null) {
-            throw new IllegalArgumentException("Source declaration without 
directory value.");
-        }
-        directory = baseDir.resolve(value);
-        FileSystem fs = directory.getFileSystem();
+        FileSystem fs = baseDir.getFileSystem();
         includes = matchers(fs, source.getIncludes());
         excludes = matchers(fs, source.getExcludes());
         stringFiltering = source.isStringFiltering();
         enabled = source.isEnabled();
         moduleName = nonBlank(source.getModule());
 
-        value = nonBlank(source.getScope());
+        String value = nonBlank(source.getScope());
         scope = (value != null) ? session.requireProjectScope(value) : 
ProjectScope.MAIN;
 
         value = nonBlank(source.getLang());
         language = (value != null) ? session.requireLanguage(value) : 
Language.JAVA_FAMILY;
 
+        value = nonBlank(source.getDirectory());
+        if (value != null) {
+            directory = baseDir.resolve(value);
+        } else {
+            directory = 
baseDir.resolve("src").resolve(scope.id()).resolve(language.id());
+        }
+
         value = nonBlank(source.getTargetVersion());
         targetVersion = (value != null) ? session.parseVersion(value) : null;
 

Reply via email to