pditommaso opened a new pull request, #2513:
URL: https://github.com/apache/groovy/pull/2513

   ## Summary
   
   Adds an opt-out system property that restores the pre-Groovy-5 truthy 
semantics for `java.io.File` and `java.nio.file.Path`: when 
`-Dgroovy.io.fileLegacyTruthy=true` is set, any non-`null` reference is truthy, 
regardless of whether the underlying file exists.
   
   The new default behaviour introduced in 5.0 (delegating to `File.exists()` / 
`Files.exists()`) is preserved when the property is absent or false.
   
   ## Why
   
   The new truthy semantics for `File`/`Path` introduced in Groovy 5 are a 
useful upgrade for greenfield code, but they silently change the behaviour of 
any existing code that uses `if (path) { … }` or `path ? a : b` to mean **"the 
reference is set"**. The release notes call this out and recommend rewriting 
affected sites to use explicit `!= null`.
   
   That recommendation is reasonable for code authors who control the codebase, 
but it does not generalise. In platforms that **execute user-supplied Groovy 
code** — Nextflow being one example, but the same applies to Gradle build 
scripts, Jenkins pipelines, and many other Groovy-based DSLs — the upgrade does 
not just affect the platform itself. Every existing user pipeline written 
against earlier Groovy versions can be silently affected, and there is no 
realistic path to audit and rewrite all of them. The end-user authoring those 
pipelines may have no idea Groovy was upgraded under them, and a 
previously-working `if(file)` may now silently skip a branch when the 
referenced file happens not to exist yet at evaluation time.
   
   A toggle flag here lets such platforms upgrade to Groovy 5 without forcing a 
coordinated rewrite of an unbounded set of downstream user code. Greenfield 
Groovy 5 users continue to get the new default; platform integrators have an 
explicit, well-named knob to preserve compatibility for their users.
   
   ## Implementation
   
   - New system property: `groovy.io.fileLegacyTruthy` (single shared flag 
covering both `File` and `Path`, named per Groovy's existing convention — see 
`groovy.compiler.strictNames`, `groovy.json.internKeys`, etc.).
   - Two changes:
     - `ResourceGroovyMethods.asBoolean(File)` — opt-out branch returns `file 
!= null`.
     - `NioExtensions.asBoolean(Path)` — opt-out branch returns `path != null`.
   - Read once at class load via `SystemUtil.getBooleanSafe(...)` to match the 
pattern used elsewhere (`StaticTypeCheckingVisitor.DEBUG_GENERATED_CODE`, 
`CompilerConfiguration.parameters`, …).
   - Javadoc updated on both methods.
   
   The default path is unchanged (no behaviour change, no perf impact beyond a 
single boolean read at JVM start).
   
   ## Test plan
   
   - [ ] Verify default behaviour (property absent) still calls `File.exists()` 
/ `Files.exists()` — covered by the existing 
`ResourceGroovyMethodsTest.test_asBoolean`.
   - [ ] Add a test exercising the opt-out path. Note: because the constant is 
initialised at class load, this test needs to set the system property before 
the class is loaded (forked JVM, or junit-pioneer `@SetSystemProperty`). Happy 
to add the test in this PR if a particular fixture style is preferred — let me 
know.
   
   ## Notes
   
   - Single property covers both `File` and `Path` because the breaking change 
is conceptually the same; users are likely to want to flip both together.
   - No CHANGELOG / release-note entry yet — happy to add one in the form 
preferred by the project.
   


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