jdaugherty commented on code in PR #16528:
URL: https://github.com/apache/grails-core/pull/16528#discussion_r4190556936


##########
grails-forge/grails-forge-core/src/main/java/org/grails/forge/feature/asciidoctor/template/asciidocGradle.rocker.raw:
##########
@@ -45,3 +45,9 @@ asciidoctorj {
                "revnumber": "$project.version"
 }
 
+// The Asciidoctor Gradle plugin does not support the configuration cache, so 
a build that runs
+// its tasks runs without the cache instead of failing
+tasks.withType(org.asciidoctor.gradle.jvm.AsciidoctorTask).configureEach {

Review Comment:
   Fixed in b1fef67: the template names the task, `tasks.named('asciidoctor')`. 
I added `AsciidoctorBuildSpec` to `test-core`, which generates an app with the 
`asciidoctor` feature and runs `./gradlew asciidoctor`: it builds the guide, 
and the configuration cache entry is discarded instead of the build failing.



##########
gradle.properties:
##########
@@ -70,17 +70,17 @@ codenarcVersion=4.0.0
 jacocoVersion=0.8.15
 pmdVersion=7.27.0
 spotbugsPluginVersion=6.4.8
-sonatypeScanPluginVersion=3.1.6
 snakeyamlVersion=2.6
 
 # This prevents the Grails Gradle Plugin from unnecessarily excluding 
slf4j-simple in the generated POMs
 # https://github.com/apache/grails-gradle-plugin/issues/222
 slf4jPreventExclusion=true
 
 org.gradle.caching=true
-# Configuration cache is explicitly disabled until known issues are resolved.
-# See: https://github.com/apache/grails-core/issues/15497
-org.gradle.configuration-cache=false
+# A build that runs the same tasks again skips configuration and reuses the 
stored task graph.
+# Build logic must stay compatible: task actions may not reach the project, 
other tasks or script
+# state, see the gradle-developer skill.
+org.gradle.configuration-cache=true

Review Comment:
   Fixed in b1fef67: the task reads the project directory while it is 
configured and logs through the task. I ran the task's code in a scratch build 
with the configuration cache set to fail on problems; it stores an entry and 
reuses it.



##########
build-logic/vulnerability-scan/src/main/groovy/org/apache/grails/buildsrc/scan/VulnerabilityScanExtension.groovy:
##########
@@ -0,0 +1,51 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.grails.buildsrc.scan
+
+import groovy.transform.CompileStatic
+
+import org.gradle.api.provider.ListProperty
+import org.gradle.api.provider.Property
+
+/**
+ * Configures the {@link VulnerabilityScanTask vulnerability scan} of a 
project.
+ */
+@CompileStatic
+abstract class VulnerabilityScanExtension {
+
+    /** The configurations whose dependencies are scanned, {@code 
runtimeClasspath} and {@code compileClasspath} unless set. */
+    abstract ListProperty<String> getConfigurations()
+
+    /** The vulnerabilities the scan does not report. */
+    abstract ListProperty<VulnerabilityExclusion> getExclusions()
+
+    /** Whether to only report the vulnerabilities instead of failing the 
build. */
+    abstract Property<Boolean> getIgnoreFailures()
+
+    /**
+     * Excludes a vulnerability from the scan.
+     *
+     * @param vulnerabilityId the OSV or Sonatype Guide id of the 
vulnerability, or one of its aliases such as its CVE
+     * @param module the {@code group:artifact} it is excluded for, or {@code 
null} for every module
+     * @param reason why it is excluded and when the exclusion can be removed
+     */
+    void exclude(String vulnerabilityId, String module, String reason) {
+        exclusions.add(new VulnerabilityExclusion(vulnerabilityId, module, 
reason))

Review Comment:
   Fixed in b1fef67. `ListProperty` has no public `append` in Gradle 9.8, only 
`add`, so the plugin now sets the built-in exclusions as the property's value 
instead of its convention, which `add` builds on. A new 
`VulnerabilityScanPluginSpec` case calls `exclude(...)` and checks that every 
built-in exclusion is still in the report.



##########
build-logic/vulnerability-scan/src/main/groovy/org/apache/grails/buildsrc/scan/VulnerabilityScanReportTask.groovy:
##########
@@ -0,0 +1,174 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.grails.buildsrc.scan
+
+import groovy.json.JsonSlurper
+import groovy.transform.CompileDynamic
+import groovy.transform.CompileStatic
+
+import org.gradle.api.DefaultTask
+import org.gradle.api.file.ConfigurableFileCollection
+import org.gradle.api.file.RegularFileProperty
+import org.gradle.api.provider.Property
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.InputFiles
+import org.gradle.api.tasks.OutputFile
+import org.gradle.api.tasks.PathSensitive
+import org.gradle.api.tasks.PathSensitivity
+import org.gradle.api.tasks.TaskAction
+import org.gradle.api.tasks.UntrackedTask
+
+/**
+ * Summarizes the reports of {@link VulnerabilityScanTask vulnerability scans} 
in Markdown: each vulnerable
+ * dependency once, with the projects it was found in and the databases that 
know of each vulnerability, the
+ * vulnerabilities that were excluded, and the exclusions that no longer match 
anything. The last are only listed
+ * when every database was consulted.
+ */
+@CompileStatic
+@UntrackedTask(because = 'It summarizes scans whose results change without the 
build changing')
+abstract class VulnerabilityScanReportTask extends DefaultTask {
+
+    /** The reports of the scans; those that do not exist are skipped. */
+    @InputFiles
+    @PathSensitive(PathSensitivity.RELATIVE)
+    abstract ConfigurableFileCollection getReports()
+
+    /** Truncates the listing to this many bytes; {@code 0} keeps all of it. */
+    @Input
+    abstract Property<Integer> getMaxBytes()
+
+    @OutputFile
+    abstract RegularFileProperty getSummaryFile()
+
+    @TaskAction
+    void summarize() {
+        List<Map<String, Object>> scans = reports.files.findAll { it.isFile() 
}.sort().collect { File file ->

Review Comment:
   Fixed in b1fef67: when a lookup fails, `scan()` writes the project, its 
dependency count, the error and its exclusions to the report before rethrowing. 
The summary lists those projects with ⚠️, never prints ✅ while one of them 
failed, and leaves out "Exclusions that match nothing". A new spec has an OSV 
stub answer 503 for one project's dependency and checks the summary.



##########
grails-doc/src/en/guide/upgrading/upgrading80x.adoc:
##########
@@ -4718,3 +4718,17 @@ for template renders:
 
 Objects passed with `bean` or `collection` are not part of `model`. See
 link:theWebLayer.html#definingInterceptors[Defining Interceptors].
+
+==== 85. Gradle Configuration Cache

Review Comment:
   Moved in b1fef67 to a new `upgrading81x.adoc`, "Upgrading from Grails 8.0 to 
Grails 8.1". It says the property needs the Grails 8.1 Gradle plugins and BOM, 
and not to add it to a project still on the 8.0 plugins. Note 85 is gone from 
the Grails 7 to 8 page, and the guide section and the `grails-8-upgrade` skill 
say the same now.



##########
grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy:
##########
@@ -228,16 +228,14 @@ class GrailsGradlePlugin implements Plugin<Project> {
         }
     }
 
+    /**
+     * The main class the {@code findMainClass} task found. The value is read 
from the task's output when it is
+     * queried, so the configuration cache keeps it lazy instead of storing 
whatever the file held before the task ran.
+     */
     protected static Provider<String> getMainClassProvider(Project project) {
-        Provider<FindMainClassTask> findMainClassTask = 
project.tasks.named('findMainClass', FindMainClassTask)
-        project.provider {
-            File cacheFile = 
findMainClassTask.get().mainClassCacheFile.orNull?.asFile
-            if (!cacheFile?.exists()) {
-                return null
-            }
-
-            cacheFile?.text
-        }
+        project.tasks.named('findMainClass', FindMainClassTask)
+                .flatMap { FindMainClassTask task -> task.mainClassCacheFile }
+                .map { RegularFile cacheFile -> cacheFile.asFile.exists() ? 
cacheFile.asFile.text : null }

Review Comment:
   Fixed in b1fef67. As you suspected, a provider mapped from the task output 
would make `springBoot.mainClass.get()` fail during configuration, so 
`springBoot.mainClass` and `ext.mainClassName` now read the cache file through 
a `ValueSource` (`FoundMainClassValueSource`). It has no value during 
configuration on a clean build, as before, and Gradle obtains it again when an 
entry is reused. `MainClassConfigurationCacheSpec` covers a task reading both 
with a stored and with a reused entry, and a script reading 
`springBoot.mainClass` while it is configured.



##########
build-logic/docs-core/src/main/groovy/grails/doc/gradle/ConvertAsciidocTask.groovy:
##########
@@ -0,0 +1,165 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package grails.doc.gradle
+
+import javax.inject.Inject
+
+import groovy.transform.CompileStatic
+
+import org.gradle.api.DefaultTask
+import org.gradle.api.Project
+import org.gradle.api.file.DirectoryProperty
+import org.gradle.api.file.FileSystemOperations
+import org.gradle.api.file.FileVisitDetails
+import org.gradle.api.model.ObjectFactory
+import org.gradle.api.provider.ListProperty
+import org.gradle.api.provider.MapProperty
+import org.gradle.api.provider.Property
+import org.gradle.api.tasks.CacheableTask
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.InputDirectory
+import org.gradle.api.tasks.Internal
+import org.gradle.api.tasks.OutputDirectory
+import org.gradle.api.tasks.PathSensitive
+import org.gradle.api.tasks.PathSensitivity
+import org.gradle.api.tasks.TaskAction
+import org.gradle.api.tasks.util.PatternSet
+import org.gradle.workers.WorkQueue
+import org.gradle.workers.WorkerExecutor
+
+/**
+ * Converts the AsciiDoc documents of a directory to HTML pages.
+ *
+ * <p>Every document matching {@link #getIncludes()} and not {@link 
#getExcludes()} - by default
+ * every {@code .adoc} file whose name does not start with an underscore - is 
converted on its
+ * own, with its own directory as the base directory, to the same relative 
path under
+ * {@link #getOutputDir()}. The {@code images} directory of the source 
directory is copied
+ * alongside the pages.</p>
+ *
+ * <p>Like the Asciidoctor Gradle plugin, the task sets {@code revnumber} and 
the
+ * {@code gradle-project-name}, {@code gradle-project-group} and {@code 
gradle-project-version}
+ * attributes from the project, and {@code includedir} to the source 
directory, unless
+ * {@link #getAttributes()} sets them.</p>
+ *
+ * <p>The conversion runs in a forked worker process, like {@link 
PublishGuideTask}, so the JRuby
+ * runtime AsciidoctorJ starts never lands in the Gradle daemon.</p>
+ *
+ * @since 8.0
+ */
+@CompileStatic
+@CacheableTask

Review Comment:
   Fixed in b1fef67. The task has `includedFiles` (`@InputFiles 
@PathSensitive(RELATIVE)`) and `pathAttributes`: the documents get those paths 
absolute, while the task's inputs only have them relative to the root project. 
The MongoDB, Hibernate 5/7 and Neo4j docs declare the example sources they 
include, and Neo4j's and GraphQL's absolute paths moved to `pathAttributes`. 
The new spec checks that a changed included file converts the documents again 
and that a copy of the project at another path gets the result FROM-CACHE.
   
   One thing I found on the way: GraphQL's `{sourcedir}/core/...` and 
`{sourcedir}/examples/...` includes do not resolve in this repository (the 
files are under `grails-data-graphql/core` and `grails-test-examples/graphql` 
now), so those examples are missing from its guide. That predates this PR and 
needs its own fix of the include paths.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to