Skip to content

Make subpackage recursion explicit where these renames depend on it - #141

Merged
timtebeek merged 1 commit into
mainfrom
tim/changepackage-recursive-subpackages
Aug 4, 2026
Merged

Make subpackage recursion explicit where these renames depend on it#141
timtebeek merged 1 commit into
mainfrom
tim/changepackage-recursive-subpackages

Conversation

@timtebeek

@timtebeek timtebeek commented Aug 4, 2026

Copy link
Copy Markdown
Member

Two ChangePackage rules omit recursive while depending on it to move types out of subpackages of oldPackageName.

apache-commons-math-2-3.ymlorg.apache.commons.mathorg.apache.commons.math3 has to carry org.apache.commons.math.stat.StatUtils along with it.

apache-httpclient-5.yml — this one is step 2 of a deliberate three-step chain:

org.apache.http.entity                          -> org.apache.hc.core5.http.io.entity      # recursive: true
org.apache.hc.core5.http.io.entity.mime         -> org.apache.hc.client5.http.entity.mime  # <-- omitted
org.apache.hc.client5.http.entity.mime.content  -> org.apache.hc.client5.http.entity.mime

Step 1 relocates org.apache.http.entity.mime.content.StringBody under core5, step 2 has to move the whole mime subtree over to client5, and step 3 flattens .content. Step 2 only reaches .content.StringBody by recursing, so without it the chain stalls at org.apache.hc.core5.http.io.entity.mime.content.StringBody — a package that doesn't exist in httpclient5.

Why now

ChangePackage.recursive is @Nullable with required = false and no documented default, and a null was read two different ways inside the same recipe: non-recursive by its preconditions, recursive by its visitor. The upshot was that a subpackage type got renamed only if the file also referenced a type sitting directly in oldPackageName — so these two rules worked in the test fixtures (which happen to mix both) and silently did nothing for a file that only touched a subpackage.

Verification

Full ./gradlew test on this branch, four ways:

without rewrite#8382 with rewrite#8382
origin/main 0 failures 2 failures
this branch 0 failures 0 failures
  • So this is correct on its own merits and safe to merge now, independently of rewrite#8382 — it makes explicit what these rules already relied on.

Both of these `ChangePackage` rules omit `recursive` while depending on it to
move types out of subpackages of `oldPackageName`.

`org.apache.commons.math` -> `org.apache.commons.math3` has to carry
`org.apache.commons.math.stat.StatUtils` along with it.

The httpclient rule is step 2 of a three-step chain:

    org.apache.http.entity                    -> org.apache.hc.core5.http.io.entity   (recursive: true)
    org.apache.hc.core5.http.io.entity.mime   -> org.apache.hc.client5.http.entity.mime
    org.apache.hc.client5.http.entity.mime.content -> org.apache.hc.client5.http.entity.mime

Step 1 relocates `org.apache.http.entity.mime.content.StringBody` under
`core5`, step 2 has to move the whole `mime` subtree over to `client5`, and
step 3 flattens `.content`. Step 2 only reaches `.content.StringBody` by
recursing, so without it the chain stalls at
`org.apache.hc.core5.http.io.entity.mime.content.StringBody`, a package that
does not exist in httpclient5.

Relying on the default here was always fragile: `ChangePackage.recursive` is
`@Nullable` with no documented default, and a null was read as non-recursive by
the recipe's preconditions but as recursive by its visitor, so subpackage
renames only happened for files that also referenced a type sitting directly in
`oldPackageName`. openrewrite/rewrite#8382 settles null as non-recursive, which
makes that latent dependency visible. Stating `recursive: true` is correct
either way and is green both with and without that change.
@github-project-automation github-project-automation Bot moved this to In Progress in OpenRewrite Aug 4, 2026
@timtebeek
timtebeek merged commit b5b78b2 into main Aug 4, 2026
1 check passed
@timtebeek
timtebeek deleted the tim/changepackage-recursive-subpackages branch August 4, 2026 22:16
@github-project-automation github-project-automation Bot moved this from In Progress to Done in OpenRewrite Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant