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


##########
grails-testing-support-core/src/main/groovy/org/grails/compiler/injection/testing/IntegrationTestAstTransformation.groovy:
##########
@@ -131,6 +132,29 @@ class IntegrationTestAstTransformation implements 
ASTTransformation, TransformWi
 
     }
 
+    /**
+     * The classpath the spec is compiled with: the compiler configuration's 
entries and those of the class loaders it
+     * compiles against. It carries the application's main classes directory 
wherever the build puts it. Dynamic, as
+     * static flow typing would hold the loop's class loader to the first 
one's type and fail on its parent.
+     */
+    @CompileDynamic
+    private static Collection<File> compileClasspath(SourceUnit source) {

Review Comment:
   Nothing tests `compileClasspath`. `MainClassFinderSpec` passes the classpath 
in directly, so no test checks what the transform hands it, and Codecov reports 
the new lines in this file as uncovered. Could a spec compile an `@Integration` 
class the way a build does? That means a source file inside a project 
directory, compiled against an application class in a classes directory that 
isn't under `build/`, and then checking that the compiled class has 
`@ContextConfiguration(classes = Application)`. It would also be the natural 
place to cover the root-level layout from the other comment.



##########
grails-gradle/model/src/main/groovy/org/grails/io/support/MainClassFinder.groovy:
##########
@@ -85,6 +100,13 @@ class MainClassFinder {
             }
 
             if (rootDir) {
+                File projectDir = rootDir.canonicalFile
+                for (File entry in classpath) {
+                    if (entry.isDirectory() && 
findRootDirectory(entry)?.canonicalFile == projectDir) {

Review Comment:
   This only accepts a classes directory inside the spec's own project, so a 
build directory at the root or outside the checkout still finds nothing. The 
`bootRun` provider handles those layouts (the `../` feature), but 
`@Integration` doesn't.
   
   I moved `enable-mvc-check`'s build directory to `<root>/build-out/<project>` 
from an init script, which is the 
`rootProject.layout.buildDirectory.dir(project.name)` layout, and left no 
`build/` in the project. The spec gets no `@ContextConfiguration`, and all 7 
`integrationTest` tests fail with `No baseUrl set`. Calling `searchMainClass` 
directly with the classes from this head gives the same answer. It returns null 
for a root-level build directory and for one outside the checkout, and finds 
`example.Application` when the build directory is inside the project.
   
   The compile's own output directory could decide this instead of where the 
directory sits. Gradle sets `CompilerConfiguration.targetDirectory` to the 
task's destination (`<build>/classes/groovy/integrationTest`), and the main 
classes directory is next to it under `<build>/classes`, wherever the build 
directory is. A plugin subproject's classes directory is under that 
subproject's own build directory, so it is still left out. As a throwaway 
probe, I passed `source.configuration.targetDirectory` from the transform and 
also accepted a classpath directory that shares the target's `<build>/classes` 
parent. With that change the root-level layout passes all 7 tests. The current 
check could stay as the fallback for a compile with no target directory.
   
   While some layouts find nothing, this also affects the build cache. Whether 
the application class is found isn't part of `compileIntegrationTestGroovy`'s 
cache key, because Gradle compares the compile classpath by its contents, not 
by where its directories are. After the root-level run, a run with the build 
directory inside the project restored the spec from the local build cache 
without `@ContextConfiguration`, and all 7 tests failed. The same run with 
`--no-build-cache` and a clean output directory passed. Once every layout finds 
the class, the compiled output is the same for all of them and this goes away.



##########
grails-gradle/model/src/main/groovy/grails/util/BuildSettings.groovy:
##########
@@ -335,6 +337,24 @@ class BuildSettings {
         BASE_DIR = System.getProperty(APP_BASE_DIR) ? new 
File(System.getProperty(APP_BASE_DIR)) : 
(IOUtils.findApplicationDirectoryFile() ?: new File('.'))
         GRAILS_APP_DIR_PRESENT = new File(BASE_DIR, 'grails-app').exists() || 
new File(BASE_DIR, 'Application.groovy').exists()
         TARGET_DIR = new File(BASE_DIR, 
System.getProperty('project.target.dir', 'build'))
-        RESOURCES_DIR = !GRAILS_APP_DIR_PRESENT ? null : 
(System.getProperty(PROJECT_RESOURCES_DIR) ? new 
File(System.getProperty(PROJECT_RESOURCES_DIR)) : new File(TARGET_DIR, 
'resources/main'))
+        RESOURCES_DIR = !GRAILS_APP_DIR_PRESENT ? null : 
resourcesDir(System.getProperty(PROJECT_RESOURCES_DIR), BASE_DIR, TARGET_DIR)
+    }
+
+    /**
+     * {@link #RESOURCES_DIR}: a {@link #PROJECT_RESOURCES_DIR} that is 
relative, as the Gradle plugin passes it, joined
+     * to the application directory rather than the working directory, which a 
build can move; one that is absolute
+     * as it is; and without one, {@code resources/main} in the target 
directory.
+     *
+     * @param fromSystem the {@link #PROJECT_RESOURCES_DIR} system property, 
or null
+     * @param baseDir the application directory
+     * @param targetDir the target directory
+     * @return the resources directory
+     */
+    static File resourcesDir(String fromSystem, File baseDir, File targetDir) {

Review Comment:
   Minor: `resourcesDir` is public, so `BuildSettings` gains a public static 
method that only the first feature in `BuildSettingsSpec` calls. Could it be 
private, with that feature's absolute case moved into the forked-JVM feature? 
That feature already checks `RESOURCES_DIR` itself, which is what the 
application reads.



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