Skip to content

DeleteProperty should not remove pre-existing empty mappings#7145

Merged
steve-aom-elliott merged 3 commits intomainfrom
fix-delete-property-empty-mapping
Mar 25, 2026
Merged

DeleteProperty should not remove pre-existing empty mappings#7145
steve-aom-elliott merged 3 commits intomainfrom
fix-delete-property-empty-mapping

Conversation

@steve-aom-elliott
Copy link
Copy Markdown
Contributor

Summary

  • DeleteProperty.visitMapping() unconditionally removed mapping entries whose value was an empty Yaml.Mapping (e.g. workflow_dispatch: {}), even when those entries had nothing to do with the property being deleted
  • This caused the Spring Boot migration recipes (which use DeleteSpringPropertyDeleteProperty on all YAML files) to strip workflow_dispatch: {} from GitHub Actions workflow files
  • The empty-mapping removal was redundant — cascading deletes are already handled by the ToBeRemoved marker propagation

Test plan

  • New test doesNotDeletePreExistingEmptyMappings — verifies that workflow_dispatch: {} in a workflow file is left untouched when deleting an unrelated property
  • New test deletesEmptyMappingThatBecameEmptyFromDeletion — verifies that cascading deletion still works (a parent mapping that becomes empty after its children are deleted is still removed)
  • All existing DeletePropertyKeyTest tests pass
  • All existing DeleteKeyTest tests pass

The visitMapping method in DeleteProperty unconditionally removed any
mapping entry whose value was an empty Yaml.Mapping. This caused
unrelated entries like `workflow_dispatch: {}` in GitHub Actions
workflow files to be deleted when DeleteProperty visited those files
looking for a completely different property key.

The empty-mapping check was intended to cascade deletions upward (when
a mapping becomes empty because all its children were deleted). But
this cascading is already handled correctly by the ToBeRemoved marker
propagation: when visitMapping filters out all entries, it marks the
now-empty mapping with ToBeRemoved, which the parent visitMapping
picks up via the existing `ToBeRemoved.hasMarker(entry.getValue())`
check.

Removing the redundant empty-mapping condition fixes the regression
without breaking the cascading delete behavior.
Verifies that deleting `on.push` preserves the sibling
`workflow_dispatch: {}` entry under the same parent mapping.
Verifies that deleting a 4-level deep property correctly cascades
upward, and that pre-existing empty mapping siblings at intermediate
levels are preserved during the cascade.
@steve-aom-elliott steve-aom-elliott moved this from In Progress to Ready to Review in OpenRewrite Mar 25, 2026
@steve-aom-elliott steve-aom-elliott added bug Something isn't working test provided Already replicated with a unit test, using JUnit pioneer's ExpectedToFail yaml labels Mar 25, 2026
@steve-aom-elliott steve-aom-elliott merged commit 2f095d2 into main Mar 25, 2026
1 check passed
@steve-aom-elliott steve-aom-elliott deleted the fix-delete-property-empty-mapping branch March 25, 2026 20:40
@github-project-automation github-project-automation bot moved this from Ready to Review to Done in OpenRewrite Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working test provided Already replicated with a unit test, using JUnit pioneer's ExpectedToFail yaml

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants