Message-ID: From: "vlsi (@vlsi)" To: "pgjdbc/pgjdbc" Date: Mon, 25 May 2026 17:42:45 +0000 Subject: [pgjdbc/pgjdbc] PR #4106: build: use explicit fileTree for gettext .po inputs List-Id: X-GitHub-Additions: 1 X-GitHub-Author-Id: 213894 X-GitHub-Author-Login: vlsi X-GitHub-Base: master X-GitHub-Changed-Files: 1 X-GitHub-Commits: 1 X-GitHub-Deletions: 1 X-GitHub-Head-Branch: claude/condescending-lalande-55d456 X-GitHub-Head-SHA: 95cb867c94f448dc0491eb2576d611c073308327 X-GitHub-Issue: 4106 X-GitHub-Labels: chore X-GitHub-Merge-SHA: 2829bd890cd0fdda7a6de859a437e2de16bf0e97 X-GitHub-Merged-By: vlsi X-GitHub-Repo: pgjdbc/pgjdbc X-GitHub-State: merged X-GitHub-Type: pull_request X-GitHub-Url: https://github.com/pgjdbc/pgjdbc/pull/4106 Content-Type: text/plain; charset=utf-8 ### Changes to Existing Features: * No behavioural change at runtime — only the Gradle build wiring for the gettext task chain. ## Summary The `poFiles` input to `remove_obsolete_translations` was wired through: ```kotlin files(sourceSets.main.get().allSource).filter { it.path.endsWith(".po") } ``` That collection is a poor fit for an incremental task input: - `allSource` is a `SourceDirectorySet` whose `srcDirs` change between runs — for example, `build/jcp/preprocessVersion` appears only after the `preprocessVersion` task has executed once. - Wrapping it in `files(...).filter { ... }` produces a `FilteredFileTree` whose snapshot depends on the upstream aggregation, not on the `.po` files themselves. - With `@PathSensitive(PathSensitivity.NONE)`, Gradle has been observed to emit a `+1/-1` pair of `ADDED` + `REMOVED` events for the same physical `.po` file across runs: ``` Task ':postgresql:remove_obsolete_translations' is not up-to-date because: Input property 'poFiles' file .../translation/ru.po has been added. Input property 'poFiles' file .../translation/ru.po has been removed. ``` `MsgAttribTask` / `MsgMergeTask` / `MsgFmtTask` process change events in order, so the `REMOVED` branch deletes the output the `ADDED` branch just produced. The effect cascades: `add_new_messages_to_po` loses `ru.po`, `generate_java_resources` never sees it, and `generateGettextSources` has no `messages_ru.java` to copy back into `src/main/java`. `--rerun-tasks` masks the issue by bypassing incremental change detection. I was **not able to fully reproduce the spurious `ADDED`+`REMOVED`** on the current checkout — instrumenting the build shows `allSource` contains each `.po` exactly once, and a delete-then-rebuild loop converges. So the precise trigger inside Gradle's snapshotter is not pinned down in this PR. Either way, the input is structurally unstable and the right shape is an explicit, narrowly scoped `FileTree`. ## Fix Replace the input expression with an explicit `FileTree` rooted at the translation directory: ```kotlin poFiles.from(fileTree("src/main/java/org/postgresql/translation") { include("*.po") }) ``` Now each `.po` file appears exactly once, the input is independent of any `SourceDirectorySet` evolution, and the snapshot is stable run-to-run. ## Where the real fix belongs A more general fix belongs in `vlsi-release-plugins/gettext-plugin` itself: collapse per-output-file changes, with `ADDED`/`MODIFIED` winning over `REMOVED`, so any flaky `+1/-1` from an upstream input collection cannot delete a freshly produced output. That would protect any other consumer of these tasks. This PR takes the one-line pgjdbc-side route to unbreak the build chain immediately. ## Verification 1. Deleted `pgjdbc/src/main/java/org/postgresql/translation/messages_ru.java`. 2. Ran `./gradlew :postgresql:generateGettextSources` (no `--rerun-tasks`). - `msgattrib` / `msgmerge` / `msgfmt` each processed all 16 locales, including `ru`. - `messages_ru.java` was regenerated (18.1K, identical size to the original). 3. Re-ran with no further changes. - `remove_obsolete_translations`, `add_new_messages_to_po`, `generate_java_resources` all reported `UP-TO-DATE`. - No `has been added` / `has been removed` events for `ru.po` in `--info` output. 🤖 Generated with [Claude Code](https://claude.com/claude-code) diff --git a/pgjdbc/build.gradle.kts b/pgjdbc/build.gradle.kts index c66ecd67f9..2f1a281281 100644 --- a/pgjdbc/build.gradle.kts +++ b/pgjdbc/build.gradle.kts @@ -199,7 +199,7 @@ val update_pot_with_new_messages by tasks.registering(GettextTask::class) { val remove_obsolete_translations by tasks.registering(MsgAttribTask::class) { args.add("--no-obsolete") // remove obsolete messages // TODO: move *.po to resources? - poFiles.from(files(sourceSets.main.get().allSource).filter { it.path.endsWith(".po") }) + poFiles.from(fileTree("src/main/java/org/postgresql/translation") { include("*.po") }) } val add_new_messages_to_po by tasks.registering(MsgMergeTask::class) {