This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch GROOVY-12019
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY-12019 by this push:
     new 8908904dc4 Enhance task handling in SharedConfiguration for 
documentation and Apache publishing
8908904dc4 is described below

commit 8908904dc49854cebb79b39cf44ef0d2a7f8ff91
Author: Daniel Sun <[email protected]>
AuthorDate: Thu May 28 02:12:36 2026 +0900

    Enhance task handling in SharedConfiguration for documentation and Apache 
publishing
---
 .../src/main/groovy/org.apache.groovy-base.gradle  |   6 +-
 .../main/groovy/org.apache.groovy-library.gradle   |   8 +-
 .../org.apache.groovy-published-library.gradle     |   4 +-
 .../org/apache/groovy/gradle/JarJarTask.groovy     |  24 +++--
 .../groovy/gradle/SharedConfiguration.groovy       | 102 ++++++++++++++++++++-
 5 files changed, 129 insertions(+), 15 deletions(-)

diff --git a/build-logic/src/main/groovy/org.apache.groovy-base.gradle 
b/build-logic/src/main/groovy/org.apache.groovy-base.gradle
index 22784c8e60..9386ea793a 100644
--- a/build-logic/src/main/groovy/org.apache.groovy-base.gradle
+++ b/build-logic/src/main/groovy/org.apache.groovy-base.gradle
@@ -47,9 +47,9 @@ if (sharedConfiguration.hasCodeCoverage.get()) {
 }
 
 if (sharedConfiguration.isDocumentationBuild && 
layout.projectDirectory.dir('src/spec/doc').asFile.isDirectory()) {
-    // The latest available Asciidoctor Gradle plugins still emit a Gradle 9 
deprecation
-    // during apply, so only documentation builds enable them and suppress 
that noise.
-    gradle.startParameter.warningMode = 
org.gradle.api.logging.configuration.WarningMode.None
+    // asciidoctor-gradle-jvm 4.0.5 still emits a Gradle 9 deprecation during 
apply.
+    // Keep docs builds opt-in, but leave warnings enabled so unrelated 
deprecations stay visible.
+    // TODO: Drop this note once the build can move to asciidoctor-gradle-jvm 
4.0.6+.
     pluginManager.apply('org.apache.groovy-asciidoctor')
 }
 
diff --git a/build-logic/src/main/groovy/org.apache.groovy-library.gradle 
b/build-logic/src/main/groovy/org.apache.groovy-library.gradle
index ae7618ddcd..860b14392d 100644
--- a/build-logic/src/main/groovy/org.apache.groovy-library.gradle
+++ b/build-logic/src/main/groovy/org.apache.groovy-library.gradle
@@ -37,11 +37,11 @@ tasks.named('jarjar') { JarJarTask jjt ->
     jjt.bndInstruction('Fragment-Host', 'groovy') // GROOVY-9402, GROOVY-11570
     def folder = file("${projectDir}/src/main/resources/META-INF/services")
     if (folder.exists() && folder.listFiles().count { it.name ==~ 
/^(?!(org.codehaus.groovy.transform.ASTTransformation)$).*$/ } > 0) {
-        jjt.bndInstruction('Require-Capability', 
'osgi.extender;filter:="(osgi.extender=osgi.serviceloader.processor)"')
-        jjt.bndInstruction('Require-Capability', 
'osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)"')
+        jjt.appendBndInstruction('Require-Capability', 
'osgi.extender;filter:="(osgi.extender=osgi.serviceloader.processor)"')
+        jjt.appendBndInstruction('Require-Capability', 
'osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)"')
         
folder.eachFileMatch(~/^(?!(org.codehaus.groovy.transform.ASTTransformation)$).*$/)
 {
-            jjt.bndInstruction('Require-Capability', 
"osgi.serviceloader;filter:=\"(osgi.serviceloader=${it.name})\";cardinality:=multiple")
-            jjt.bndInstruction('Provide-Capability', 
"osgi.serviceloader;osgi.serviceloader=\"${it.name}\"")
+            jjt.appendBndInstruction('Require-Capability', 
"osgi.serviceloader;filter:=\"(osgi.serviceloader=${it.name})\";cardinality:=multiple")
+            jjt.appendBndInstruction('Provide-Capability', 
"osgi.serviceloader;osgi.serviceloader=\"${it.name}\"")
         }
     }
 }
diff --git 
a/build-logic/src/main/groovy/org.apache.groovy-published-library.gradle 
b/build-logic/src/main/groovy/org.apache.groovy-published-library.gradle
index b7e0e90aa4..4804167999 100644
--- a/build-logic/src/main/groovy/org.apache.groovy-published-library.gradle
+++ b/build-logic/src/main/groovy/org.apache.groovy-published-library.gradle
@@ -828,7 +828,9 @@ signing {
 }
 
 gradle.taskGraph.whenReady { taskGraph ->
-    if (sharedConfiguration.signing.shouldSign()) {
+    boolean shouldSign = sharedConfiguration.signing.shouldSign(taskGraph)
+    signing.required = shouldSign
+    if (shouldSign) {
         // Use Java 6's console or Swing to read input (not suitable for CI)
         if (!sharedConfiguration.signing.hasAllKeyDetails()) {
             printf '\n\nWe have to sign some things in this build.' +
diff --git 
a/build-logic/src/main/groovy/org/apache/groovy/gradle/JarJarTask.groovy 
b/build-logic/src/main/groovy/org/apache/groovy/gradle/JarJarTask.groovy
index 65be072eb8..ce199744d0 100644
--- a/build-logic/src/main/groovy/org/apache/groovy/gradle/JarJarTask.groovy
+++ b/build-logic/src/main/groovy/org/apache/groovy/gradle/JarJarTask.groovy
@@ -97,9 +97,8 @@ class JarJarTask extends DefaultTask {
 
     /**
      * BND instructions used when generating the OSGi manifest.
-     * Keys that are added multiple times are accumulated with 
comma-separators,
-     * which is the correct BND syntax for multi-value headers such as
-     * {@code Require-Capability} and {@code Provide-Capability}.
+     * Entries override the default analyzer properties unless explicitly 
appended
+     * through {@link #appendBndInstruction(String, String)}.
      */
     @Input
     Map<String, String> bndInstructions = [:]
@@ -118,11 +117,24 @@ class JarJarTask extends DefaultTask {
     }
 
     /**
-     * Adds (or accumulates) a BND manifest instruction.
-     * If {@code key} already has a value, the new {@code value} is appended
-     * with a comma separator — matching BND's multi-value header syntax.
+     * Sets a BND manifest instruction, replacing any previous value for 
{@code key}.
      */
     void bndInstruction(String key, String value) {
+        setBndInstruction(key, value)
+    }
+
+    /**
+     * Sets a BND manifest instruction, replacing any previous value for 
{@code key}.
+     */
+    void setBndInstruction(String key, String value) {
+        bndInstructions[key] = value
+    }
+
+    /**
+     * Appends a BND manifest instruction using a comma separator, matching 
BND's
+     * syntax for multi-value headers such as {@code Require-Capability}.
+     */
+    void appendBndInstruction(String key, String value) {
         def existing = bndInstructions.get(key)
         bndInstructions[key] = existing != null ? "${existing},${value}" : 
value
     }
diff --git 
a/build-logic/src/main/groovy/org/apache/groovy/gradle/SharedConfiguration.groovy
 
b/build-logic/src/main/groovy/org/apache/groovy/gradle/SharedConfiguration.groovy
index 1158b3292d..b18030bcfa 100644
--- 
a/build-logic/src/main/groovy/org/apache/groovy/gradle/SharedConfiguration.groovy
+++ 
b/build-logic/src/main/groovy/org/apache/groovy/gradle/SharedConfiguration.groovy
@@ -20,6 +20,7 @@ package org.apache.groovy.gradle
 
 import groovy.transform.CompileStatic
 import org.gradle.StartParameter
+import org.gradle.api.execution.TaskExecutionGraph
 import org.gradle.api.file.Directory
 import org.gradle.api.file.ProjectLayout
 import org.gradle.api.file.RegularFile
@@ -32,6 +33,24 @@ import org.gradle.api.tasks.Nested
 
 @CompileStatic
 class SharedConfiguration {
+    private static final List<String> DOCUMENTATION_TASK_NAMES = [
+            'asciidocAll',
+            'asciidoctor',
+            'asciidoctorPdf',
+            'doc',
+            'docGDK',
+            'dist',
+            'distBin',
+            'distDoc',
+            'distSdk',
+            'groovydocAll',
+            'javadocAll'
+    ]
+    private static final List<String> APACHE_PUBLISH_TASK_PATHS = [
+            ':artifactoryPublish',
+            ':publishAllPublicationsToApacheRepository'
+    ]
+
     final Provider<String> groovyVersion
     final Provider<Boolean> isReleaseVersion
     final Provider<Date> buildDate
@@ -114,7 +133,8 @@ class SharedConfiguration {
                 normalized.contains('docgdk') ||
                 normalized == 'dist' ||
                 normalized.startsWith('dist') ||
-                normalized.contains(':dist')
+                normalized.contains(':dist') ||
+                matchesTaskAbbreviation(taskName, DOCUMENTATION_TASK_NAMES)
     }
 
     private static boolean isApachePublishTask(String taskName) {
@@ -125,6 +145,79 @@ class SharedConfiguration {
                 
normalized.endsWith(':publishAllPublicationsToApacheRepository')
     }
 
+    // Gradle keeps the originally requested selector in 
startParameter.taskNames and expands
+    // task abbreviations only later, after configuration. Recognize 
camel-case prefixes here
+    // so requests like `jA` still opt into the documentation wiring they 
resolve to.
+    private static boolean matchesTaskAbbreviation(String taskName, 
List<String> candidateTaskNames) {
+        String selector = taskSelector(taskName)
+        selector && candidateTaskNames.any { String candidateTaskName ->
+            matchesTaskSelector(selector, candidateTaskName)
+        }
+    }
+
+    private static String taskSelector(String taskName) {
+        String normalized = taskName.trim()
+        int lastSeparator = normalized.lastIndexOf(':')
+        lastSeparator >= 0 ? normalized.substring(lastSeparator + 1) : 
normalized
+    }
+
+    private static boolean matchesTaskSelector(String requestedTaskName, 
String actualTaskName) {
+        if (actualTaskName.regionMatches(true, 0, requestedTaskName, 0, 
requestedTaskName.length())) {
+            return true
+        }
+
+        List<String> requestedSegments = taskNameSegments(requestedTaskName)
+        List<String> actualSegments = taskNameSegments(actualTaskName)
+        if (requestedSegments.size() > actualSegments.size()) {
+            return false
+        }
+
+        for (int i = 0; i < requestedSegments.size(); i += 1) {
+            String requestedSegment = 
requestedSegments.get(i).toLowerCase(Locale.ROOT)
+            String actualSegment = 
actualSegments.get(i).toLowerCase(Locale.ROOT)
+            if (!actualSegment.startsWith(requestedSegment)) {
+                return false
+            }
+        }
+        true
+    }
+
+    private static List<String> taskNameSegments(String taskName) {
+        List<String> segments = []
+        StringBuilder currentSegment = new StringBuilder()
+        for (int i = 0; i < taskName.length(); i += 1) {
+            char current = taskName.charAt(i)
+            if (current in ['-', '_', '.']) {
+                if (currentSegment.length() > 0) {
+                    segments.add(currentSegment.toString())
+                    currentSegment.setLength(0)
+                }
+                continue
+            }
+            if (currentSegment.length() > 0 && startsNewSegment(taskName, i, 
currentSegment.charAt(currentSegment.length() - 1))) {
+                segments.add(currentSegment.toString())
+                currentSegment.setLength(0)
+            }
+            currentSegment.append(current)
+        }
+        if (currentSegment.length() > 0) {
+            segments.add(currentSegment.toString())
+        }
+        segments
+    }
+
+    private static boolean startsNewSegment(String taskName, int index, char 
previous) {
+        char current = taskName.charAt(index)
+        if (!Character.isUpperCase(current)) {
+            return false
+        }
+        if (Character.isLowerCase(previous)) {
+            return true
+        }
+        int nextIndex = index + 1
+        nextIndex < taskName.length() && 
Character.isLowerCase(taskName.charAt(nextIndex))
+    }
+
     static class Artifactory {
         final Provider<String> username
         final Provider<String> password
@@ -199,6 +292,13 @@ class SharedConfiguration {
                     (forceSign.get() || apachePublishRequested))
         }
 
+        boolean shouldSign(TaskExecutionGraph taskGraph) {
+            trySign.get() || (config.isReleaseVersion.get() &&
+                    (forceSign.get() || apachePublishRequested || 
APACHE_PUBLISH_TASK_PATHS.any {
+                        taskGraph.hasTask(it)
+                    }))
+        }
+
         boolean hasAllKeyDetails() {
             return useGpgCmd.get() ||
                     keyId.present && secretKeyRingFile.present && 
password.present

Reply via email to