Repository navigation
refactor: convert build-logic docs-core and grails-gradle common/model to Groovy - #16576
borinquenkid wants to merge 13 commits into
Conversation
…l to Groovy Converts the remaining Java sources of build-logic/docs-core, grails-gradle/common and grails-gradle/model to Groovy. Part of the per-project split requested by the maintainers on #16351; end state taken from the 9.0.x-java-to-groovy branch (origin/9.0.x..e55fd9e). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…nd fix ClassPathResource.equals - add specs for GrailsNameUtils, DefaultCommandLine and the file-resolving resources (file, jar and http), and extend the parser, loader, resource-utils and IO-utils specs - ClassPathResource.equals read the other resource's classLoader through its getter, which falls back to the class's loader, while reading its own field; two resources created from the same class were therefore never equal. Compare fields on both sides, as the Java original did. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
@borinquenkid Please make sure that all files are git moved and not deleted/added. |
…erve rename history git's default 50% rename-similarity threshold is what GitHub's PR view and 'git log --follow'/'blame' use to link a converted file back to its original .java predecessor. DefaultCommandLine's full idiomatic conversion landed at 41% similarity (confirmed: GitHub shows delete+add, not a rename, losing file history per matrei's review comment on #16576). This keeps the method-body semicolons (76% similarity, confirmed rename- detected, confirmed git log --follow/blame trace through to the real pre-conversion commits and author) while still applying every other idiom fix: dropped the public modifier, the 7 unnecessary java.util.* imports, and the 4 non-interpolated double-quoted string literals CodeNarc also flags. @SuppressWarnings('UnnecessarySemicolon') marks this as a known, temporary, scoped exception pending the stacked groovyism-cleanup PR, which removes both the semicolons and this suppression. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…on 57 files Rebuilds each of these 57 grails-datastore-core files from the original .java content with a minimal mechanical conversion (public removed from methods/class decls, unnecessary groovy auto-imports dropped, safe double-quote -> single-quote conversions) that deliberately keeps every semicolon, so git's default 50% rename-similarity threshold recognizes each as a rename of its .java predecessor instead of a delete+add, following the pattern proven on DefaultCommandLine.groovy (#16576).// Each file adds a scoped @SuppressWarnings('UnnecessarySemicolon') with an explanatory TODO, to be removed by the stacked groovyism-cleanup PR. A handful of files needed small additional, behavior-preserving fixes beyond the mechanical conversion, found by running the full test suite under @CompileStatic (matching the already-converted sibling code): Groovy's '==' operator calls equals() (AbstractPersistentEntity.equals used this.is(o) instead), Groovy's property-style getter/setter resolution prefers the nearest enclosing method of the same name over an outer-class field or the field itself (KeyValuePersistentEntity. getMappedForm, Query's Equals/IdEquals/NotEquals.setValue), a Java Class::methodRef bound to '.class' breaks once blanket dot-class removal strips it (Association.isHasOne), and two classes that override GroovyObject.getProperty(String) need @groovy.transform.stc.POJO so ordinary '.property' access is not routed through that override (BeanEntityAccess, FieldEntityAccess). GormProperties (a pure constants interface with no logic) and KeyValueMappingFactory needed a documented, targeted exception to clear the 50% threshold: GormProperties drops its semicolons entirely rather than keep them under a suppression that would push it below the threshold, and KeyValueMappingFactory omits @CompileStatic (no field/getter naming collision risk was found there). Verified: compileGroovy/compileTestGroovy clean, codenarcMain clean, and all 949 grails-datastore-core tests pass (same count as before, 0 failures), matching the pre-change baseline. All 57 files are now git-detected as R050+ renames against origin/10.0.x with git's default (no -M flag) similarity detection. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…n 3 files DefaultBeanConfiguration.java, DefaultRuntimeSpringConfiguration.java, and GrailsApplicationContext.java converted at 41-45% similarity, below git's default 50% rename-similarity threshold used by GitHub's PR view and git log --follow/blame (matrei's review comment on #16576). Rebuilt each from the original .java content, keeping semicolons and every other Java-ism, applying only the CodeNarc-minimal set: dropped public modifier, unnecessary java.util/groovy.lang imports, flagged non-interpolated double-quoted strings, and unnecessary .class literal references. Added @SuppressWarnings('UnnecessarySemicolon') + explanatory comment on each class. GrailsApplicationContext needed one addition beyond the mechanical transform: it hand-implements GroovyObject (metaClass field, getMetaClass/setMetaClass/ getProperty/setProperty/invokeMethod), and without @pojo + @CompileStatic - both already present on this class's current (post-groovyism-cleanup) sibling - Groovy's compiler-synthesized metaclass scaffolding for a GroovyObject-implementing class races the explicit field assignment in the constructor, throwing a NullPointerException ('this.mc' is null) the first time a context is constructed. Confirmed via the full test suite: 3 DefaultRuntimeSpringConfigurationSpec failures without @POJO/@CompileStatic, 0 with them. Verification: compileGroovy clean; codenarcMain clean; full grails-spring test suite 21/21, 0 failures (matching baseline). Rename detection confirmed via git diff --name-status (default, no -M): R077-R083 for all 3 files. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…by the rename-fix 580bd5e rebuilt DefaultCommandLine from the .java original, which carries no annotations, and so lost the @CompileStatic stage 1 had put on the class and the @PackageScope on systemProperties, undeclaredOptions, declaredOptions and remainingArgs. Without them the four fields became public Groovy properties with generated accessors and the class fell back to dynamic dispatch. Both are restored; similarity stays at R069. grails-gradle-model: compile, codenarc and 432 tests pass. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…y on 20 files Rebuilds these 20 grails-shell-cli files from the original .java content with a minimal mechanical conversion (public removed from methods/class decls, unnecessary groovy auto-imports dropped, safe double-quote -> single-quote conversions, unnecessary .class literal references removed) that deliberately keeps every semicolon, so git's default 50% rename-similarity threshold recognizes each as a rename of its .java predecessor instead of a delete+add, following the pattern proven on DefaultCommandLine.groovy (#16576) and already applied to grails-datastore-core and grails-spring. Each file adds a scoped @SuppressWarnings('UnnecessarySemicolon') with an explanatory TODO, to be removed by the stacked groovyism-cleanup PR. Four small files (GrailsCompilerAutoConfiguration, SpringBatchCompiler- AutoConfiguration, SpringIntegrationCompilerAutoConfiguration, SpringBootCompilerAutoConfiguration) stayed below the 50% threshold with semicolons alone, because their string-literal-dense bodies made the double-quote -> single-quote conversion (CodeNarc's UnnecessaryGString) proportionally too disruptive for their size; these also keep their original double-quoted strings under a documented, targeted @SuppressWarnings(['UnnecessarySemicolon', 'UnnecessaryGString']) exception, matching the GormProperties/KeyValueMappingFactory precedent in grails-datastore-core. Four files with nested/inner classes (GrailsApplicationCompiler- AutoConfiguration, ResourceMatcher, RunCommand, FetchAllTaskSelectorsBuildAction) needed one more fix: CodeNarc's @SuppressWarnings-on-class only suppresses UnnecessarySemicolon inside that class's own body, never on the file's package/import statements, which live outside any ClassNode. Moving a second @SuppressWarnings('UnnecessarySemicolon') onto the package declaration itself (a legal annotation target in Groovy, verified empirically) clears those violations file-wide. RunCommand's now-redundant explicit no-arg constructor and FetchAllTaskSelectorsBuildAction's missing blank-line-after-opening-brace were two further small, real CodeNarc findings fixed outright rather than suppressed. Verified: compileGroovy/compileTestGroovy clean, codenarcMain clean, and all 196 grails-shell-cli tests pass (0 failures, 0 errors, 2 pre-existing skips). All 20 files are now git-detected as R050+ renames against origin/10.0.x with git's default (no -M flag) similarity detection. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rebuild the grails-core main/test files from their original .java content with semicolons kept and CodeNarc UnnecessarySemicolon suppressed, so GitHub's default-threshold rename detection recognizes these as moves rather than delete+add (see matrei's review on #16576). Fixes a regression the mechanical conversion introduced in LazyMetaPropertyMap.groovy: isExcluded()'s `return` sat alone on its own line with the boolean expression starting on the next line. Java tolerates that (semicolon-terminated), but Groovy treats a bare `return` on its own line as a complete statement, so the method always returned false and let 'class' leak into keySet(). Fixed by keeping the first operand on the same line as `return`, confirmed via grails-core's full test suite (keySet excludes configurational and static properties now passes) and a sweep of all 20 files plus modules 1-7 for the same pattern. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Conflicts: GrailsResourceUtils.groovy takes upstream's getPathFromRoot change (18d8daf); the four grails-gradle/model specs upstream added in 186b59c with the same names as this branch's are kept verbatim, with the nine feature methods only this branch's versions asserted appended. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…10.0.x 10.0.x was branched from 9.1.x without the version bump, so gradle.properties still said projectVersion=9.1.0-SNAPSHOT and githubBranch=9.1.x. The 'Validate githubBranch' job therefore fails on every pull request whose base is 10.0.x. Same four files as the 9.1.x bump in 829de60. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit fb8ecf0)
Rebuild 11 of the 14 flagged grails-converters files directly from their original .java content, keeping semicolons and other Java-isms, so git recognizes the conversion as a move rather than delete+add. CodeNarc violations from the kept semicolons are suppressed with scoped @SuppressWarnings instead of being fixed, per matrei's review on #16576. Rebuilt: JSON.groovy, XML.groovy, ChainedConverterConfiguration.groovy, DefaultConverterConfiguration.groovy, ConverterUtil.groovy, ByteArrayMarshaller.groovy, ToStringBeanMarshaller.groovy (json + xml), ValidationErrorsMarshaller.groovy (json + xml), GroovyBeanMarshaller.groovy. Accepted exceptions (left as-is): ConvertersConfigurationHolder.groovy, ConvertersConfigurationInitializer.groovy, and DomainClassMarshaller.groovy (json). Their saved .java originals in /tmp/stage2-m19 turned out to be a later, Jackson-rewrite-era snapshot (importing tools.jackson.databind.json.JsonMapper and org.grails.web.converters.jackson.DomainClassRendering/DomainClassSerializer, none of which exist in this codebase) rather than the actual immediate-parent .java this module was converted from - that Jackson-based JSON rewrite was later reverted back to the classic approach, so rebuilding from those originals would reintroduce dependencies on deleted classes. The true immediate-parent .java for the other 11 files was recovered from git history (commit 3fa21fc~1) and used instead of the stale /tmp/stage2-m19 copies where they differed. Also required: qualifying switch-case enum labels (CircularReferenceBehaviour.DEFAULT etc. instead of bare DEFAULT, which Groovy's switch cannot resolve unqualified), renaming an empty catch parameter to the literal "ignored" required by CodeNarc's EmptyCatchBlock rule, and using this.value(value) in JSON#property to avoid Groovy static compilation misresolving the call against the same-named parameter. Verified: compileGroovy/compileTestGroovy clean, codenarcMain/codenarcTest 0 violations, full grails-converters test suite 194/194 passing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rebuild PageBindingCollector and WebRequestTemplateVariableBinding from their original .java content with semicolons kept and CodeNarc UnnecessarySemicolon suppressed, so GitHub's default-threshold rename detection recognizes these as moves rather than delete+add (see matrei's review on #16576). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…oovy-build-tooling
|
Note for reviewers: #16576 and #16572 are the only PRs of this effort that run full CI on every push. The PRs stacked above them carry a temporary commit ( |
…oovy-build-tooling
…oovy-build-tooling
…oovy-build-tooling
🚨 TestLens detected 237 failed tests 🚨Test SummaryTip Inspect all details with the TestLens CLI: Groovy Snapshot Canary Build / Build Grails (shard 0) > :grails-test-examples-mongodb-hibernate5:test
Groovy Snapshot Canary Build / Build Grails (shard 1) > :grails-data-mongodb-core:test (first 40 of 224)
Groovy Snapshot Canary Build / Build Grails (shard 1) > :grails-test-examples-mongodb-test-data-service:integrationTest
Groovy Snapshot Canary Build / Build Grails (shard 2) > :grails-data-mongodb-spring-boot:test
Groovy Snapshot Canary Build / Build Grails (shard 2) > :grails-test-examples-mongodb-base:test
🏷️ Commit: 7472c06 Test Failures (first 10 of 234)BookFongoSpec (:grails-test-examples-mongodb-hibernate5:test in Groovy Snapshot Canary Build / Build Grails (shard 0))AggregateMethodSpec (:grails-data-mongodb-core:test in Groovy Snapshot Canary Build / Build Grails (shard 1))AssignedIdentifierSpec (:grails-data-mongodb-core:test in Groovy Snapshot Canary Build / Build Grails (shard 1))AttachMethodSpec (:grails-data-mongodb-core:test in Groovy Snapshot Canary Build / Build Grails (shard 1))AutowireServicesSpec (:grails-data-mongodb-core:test in Groovy Snapshot Canary Build / Build Grails (shard 1))BasicArraySpec (:grails-data-mongodb-core:test in Groovy Snapshot Canary Build / Build Grails (shard 1))BasicCollectionTypeSpec (:grails-data-mongodb-core:test in Groovy Snapshot Canary Build / Build Grails (shard 1))BasicCollectionsSpec (:grails-data-mongodb-core:test in Groovy Snapshot Canary Build / Build Grails (shard 1))BatchUpdateDeleteSpec (:grails-data-mongodb-core:test in Groovy Snapshot Canary Build / Build Grails (shard 1))BeforeInsertUpdateSpec (:grails-data-mongodb-core:test in Groovy Snapshot Canary Build / Build Grails (shard 1))Rerun Controls (first 20 of 237)Select tests to mute in this pull request:
Reuse successful test results:
Click the checkbox to trigger a rerun:
Learn more about TestLens at testlens.app/docs. |
|
Closing this one, matrei's comment is right: the history of the converted files is recovered only by git guessing (the renames sit between 52% and 92% similar, none is a pure move). It will come back as a new pull request built the way #16572 now is, a commit that only moves the Java files to their Groovy paths and a second commit that converts them. The branch stays for reference. |
…va-to-groovy-core-leaves The build-tooling files of this branch come from the one-commit conversion of #16576, which is replaced by a conversion that moves the files first and converts them in a second commit. The new content of the three projects replaces the old one; nothing else changes. Claude-Session: https://claude.ai/code/session_01MDHn7fC3hsGJ27vFHD2o1p
What
Converts the remaining Java sources of
build-logic/docs-core,grails-gradle/common,grails-gradle/modelto Groovy: 20.javafiles removed, 30.groovyfiles added (32 files changed, 2531 insertions(+), 1545 deletions(-)).Why
The maintainers asked on #16351 for the Java-to-Groovy migration to land one Gradle project at a time as a stack of PRs, bottom-up in dependency order. #16572 did
grails-data-hibernate7; this PR is 1 of 30 in the next stack (base:9.0.x). The end state of every file is taken from the9.0.x-java-to-groovybranch, which already carries the regression fixes found by CI.Commits:
Changed outside the converted sources
Java-facing API sweep
Every deleted
.javawas compared with its Groovy twin viajavap -v -protected(class declaration, public/protected fields, constructors, methods incl. modifiers/throws/generics, interface default methods, nested class modifiers, and the annotations callers see). Result:See also the notes below.
Verification
classesandtestClasses(plusast/cli/testFixturessource sets where present) of the converted project(s) and of their direct dependents compile: nonecodeStyle,ratand a whole-repobuild -PskipTestsare run once on the tip of the stack.Notes
MIN_VALUE/MAX_VALUE/next()/previous(), property accessors appear for formerly package-private members, nested static classes with implicit constructors become public (they wereprotected), and generic type parameters that Groovy erases in constructors/methods (descriptors identical).static finalwithoutpubliccreates a property;==callsequals(); Closure/SAM coercions;@CompileStaticwith nested classes. All CI regression fixes found on the umbrella branch are included in the end state.🤖 Generated with Claude Code