Skip to content

Add lombok.config recipes - #1236

Open
sullis wants to merge 3 commits into
openrewrite:mainfrom
sullis:consolidate-lombok-config
Open

sullis wants to merge 3 commits into
openrewrite:mainfrom
sullis:consolidate-lombok-config

Conversation

@sullis

@sullis sullis commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Adds two lombok.config recipes, built on a shared LombokConfig helper that parses and classifies the directives of a config file following the line grammar of Lombok's own ConfigurationParser. Both recipes act on the lombok.config at the root of the repository, and read any *.config file that was parsed as text, since an import names a file by path rather than by name.

Neither recipe is added to LombokBestPractices; both are registered in META-INF/rewrite/recipes.csv and are run on their own.

ConsolidateLombokConfig

Merges the directives of every nested lombok.config into the root lombok.config and deletes the nested files, so a project has a single place where Lombok is configured.

  • Directives are appended to the root file; whatever the root already contains is left exactly as written (formatting, comments, line endings, trailing newline).
  • Nested files are merged shallowest first, which is the order Lombok reads them in, so a += from a directory above another still adds to the list before it does.
  • Directives the root already declares are dropped rather than repeated. Whitespace around =, += and -= is normalized for comparison only, so key=value and key = value dedupe against each other, as do keys spelled with a different case.
  • A key assigned more than once in the same nested file carries over only the assignment Lombok would take — the last one. A += is carried over once per distinct value, since each adds to the same list rather than replacing what came before.
  • What the root imports is read as part of the root, so a directive an imported file already declares is neither repeated nor overridden.
  • Comments in a nested file are carried over with the directive they precede, and dropped when that directive isn't hoisted. A comment at the end of a file, documenting no directive, is carried over as it stands, since the file is about to be deleted.

What is intentionally left alone

A nested file stays in place when hoisting it would change what Lombok does:

  • config.stopBubbling opts its directory, and everything under it, out of the root configuration. Only an explicit false keeps bubbling on; a value that can't be read as a boolean is treated as stopping bubbling, so the directory is left alone rather than hoisted on a guess.
  • import resolves relative to the file that declares it.
  • clear and -= depend on their order relative to the additions they undo.
  • A lombok.config between it and the root speaks about one of the same directives, or imports a file that may, since that file would outrank the root once the directive moved there. A file that says exactly the same thing isn't shadowing it and doesn't block the hoist.
  • Another lombok.config imports it, so deleting it would leave that import pointing at nothing.
  • No Java source sits at or below it — a fixture under src/test/resources, say — since Lombok never reads it. A source counts by its .java name, so one Lombok compiles but this recipe didn't parse counts all the same. A config governing test sources is ordinary configuration and is hoisted; when a project has no Java sources at all there's no layout to judge against, so each config is taken at its word.
  • Lines Lombok cannot parse are preserved rather than guessed at.
  • There is nothing to hoist — the file holds only comments or blank lines.

The recipe makes no changes at all when:

  • There is no lombok.config at the root of the repository, since there is nowhere to consolidate to.
  • Two files assign conflicting values to the same key, since there is no way to tell which value the consolidated configuration should keep. Only plain = assignments can conflict; several += and -= of one key are expected to coexist, and an assignment a file supersedes later on isn't weighed against another file.
  • The root clears or -=s a key that a nested file speaks about, since appending that directive after the root's line would put back what the root deliberately took away.
  • The root imports a file that is not among the sources, or the imports lead back around in a cycle.

Note that hoisting widens a directive's scope from one directory to the whole project, which is called out in the recipe description (e.g. lombok.val.flagUsage = error).

AddStopBubblingToLombokConfig

Appends config.stopBubbling = true to the root lombok.config when it does not already declare that key, so Lombok reads the project's configuration and nothing else. Lombok resolves a key by walking up from the directory of the Java file it is compiling and does not stop at the project, so without this key a lombok.config in a parent directory of wherever the project happens to be checked out takes part in the build.

  • Nothing is added when the key is already declared, whatever value it is assigned — a project that turns bubbling off explicitly, or back on again, is doing so deliberately. A key an imported file declares counts as declared, whatever case it is spelled with.
  • Nothing is added when the root imports a file that is not among the sources, or when the imports form a cycle, as there is then no telling whether the key is declared.
  • Nested lombok.config files are left alone; only the root file is changed.
  • This cuts the project off from an ancestor lombok.config whether or not it was meant to be read, so the recipe is standalone rather than part of LombokBestPractices.

Tests

ConsolidateLombokConfigTest (62 tests) covers merging, merge ordering of deeply nested configs, deduplication, conflict detection, each non-hoistable case above, stopBubbling ancestors (including one that turns bubbling back on), import resolution and cycles, comment handling, case-insensitive keys, mixed hoistable/unhoistable trees, Java-source layout, CRLF and missing-trailing-newline root files, and the no-root-config and no-config-at-all cases. AddStopBubblingToLombokConfigTest (16 tests) covers the addition, each case where nothing is added, and the same formatting-preservation cases.

🤖 Generated with Claude Code

@github-project-automation github-project-automation Bot moved this to In Progress in OpenRewrite Sep 9, 2026
@sullis
sullis force-pushed the consolidate-lombok-config branch 4 times, most recently from d5a4e5d to 6850300 Compare September 10, 2026 02:11
@sullis sullis changed the title Add ConsolidateLombokConfig Add lombok.config recipes Sep 10, 2026
@sullis
sullis force-pushed the consolidate-lombok-config branch 2 times, most recently from c66c2be to 028c6d2 Compare September 10, 2026 02:42
@sullis
sullis force-pushed the consolidate-lombok-config branch from 028c6d2 to dfc4575 Compare September 10, 2026 02:48
@sullis
sullis marked this pull request as ready for review September 10, 2026 03:13
@sullis

sullis commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

Ready for review @greg-at-moderne @timtebeek

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

1 participant