review complete
All checks were successful
Build, test and publish / verify (push) Successful in 1m31s
All checks were successful
Build, test and publish / verify (push) Successful in 1m31s
This commit is contained in:
200
specs/implemented/S8_palentir-formatting-be
Normal file
200
specs/implemented/S8_palentir-formatting-be
Normal file
@@ -0,0 +1,200 @@
|
||||
# S8 — Palantir formatting for Java
|
||||
|
||||
Status: IMPLEMENTED
|
||||
|
||||
Agreed after the grill-me review; shared understanding confirmed.
|
||||
|
||||
## User story
|
||||
|
||||
As a developer, I want maintained Java code formatted using Palantir Java Format
|
||||
through the Maven workflow, so that local development and CI use consistent,
|
||||
reproducible formatting without unnecessary build overhead.
|
||||
|
||||
## Scope
|
||||
|
||||
### In scope
|
||||
|
||||
- Backend Java production code and Java tests.
|
||||
- Maintained Java CI/source-launcher helpers under `ci/`, despite those files
|
||||
being outside ordinary Maven source roots.
|
||||
- Integration with local Maven builds, CI checking and standalone format/check
|
||||
commands.
|
||||
- A separate initial formatting commit, performance measurements and README
|
||||
instructions.
|
||||
|
||||
### Out of scope
|
||||
|
||||
- Generated code and build output.
|
||||
- Frontend formatting, which remains under Prettier.
|
||||
- Additional coding conventions, naming rules, structural checks or refactorings.
|
||||
Those belong in S7.
|
||||
|
||||
## Formatter and integration
|
||||
|
||||
- Use the **actual Palantir Java Format engine** and its Palantir style.
|
||||
- OpenRewrite is the preferred integration route. S8 includes the custom
|
||||
Palantir adapter/recipe and bootstrap required to make that route work.
|
||||
- OpenRewrite's own `AutoFormat` is not an equivalent replacement for Palantir
|
||||
and must not be substituted silently.
|
||||
- Spotless is not the agreed default: the maintainer has experienced unacceptable
|
||||
slowness with it. Do not choose it merely because a native integration exists.
|
||||
- Pin the formatter, plugin and adapter dependencies to explicit versions in
|
||||
Maven configuration. Local development and CI use the same pinned engine.
|
||||
- Formatter/integration updates are reviewed through PRs and include any resulting
|
||||
formatting changes. Do not implicitly resolve the newest formatter at build time.
|
||||
- Include Palantir's import ordering and unused-import removal. Do not add
|
||||
separate import policies or unrelated code transformations.
|
||||
- Leave optional extra Javadoc reformatting disabled for the initial adoption.
|
||||
|
||||
## Maven behavior
|
||||
|
||||
### Local builds
|
||||
|
||||
Local builds apply formatting before compilation, so the compiled and tested
|
||||
sources are the formatted sources. Early lifecycle integration means ordinary
|
||||
`mvn compile`, `mvn test`, `mvn verify` and `mvn install` may format maintained
|
||||
Java files.
|
||||
|
||||
Binding only to `install` does not satisfy this specification: the existing CI
|
||||
verification uses `mvn clean verify` and would not reach that phase.
|
||||
|
||||
Provide standalone commands to:
|
||||
|
||||
- Apply formatting without performing the complete application build.
|
||||
- Check formatting without modifying maintained sources or performing the complete
|
||||
application build.
|
||||
|
||||
The concrete commands/profile names are implementation work and must be documented.
|
||||
|
||||
### CI
|
||||
|
||||
- CI runs the check-only mode before compilation and fails if formatting differs
|
||||
from the committed source.
|
||||
- CI must not repair or rewrite maintained Java source files automatically.
|
||||
- Use the same pinned Palantir engine, configuration and file scope locally and
|
||||
in CI; only apply versus check behavior differs.
|
||||
- Integrate the checking invocation into the existing Java-based CI orchestration.
|
||||
- Show actionable diagnostics identifying the files that need formatting and how
|
||||
to apply the formatter locally.
|
||||
- A formatting failure prevents successful verification and image publication.
|
||||
Demonstrate that the check leaves maintained source files unchanged on failure.
|
||||
|
||||
## Clean-checkout bootstrap
|
||||
|
||||
Normal Maven commands from the repository root must work from a clean checkout
|
||||
without first requiring a developer to compile or install a custom recipe artifact
|
||||
by hand.
|
||||
|
||||
The custom recipe/adapter must be available before it is needed to format the
|
||||
application sources. Placing it in ordinary backend source code and assuming that
|
||||
it has already been compiled is not a valid bootstrap solution.
|
||||
|
||||
Prove bootstrap behavior with no previously installed project-specific recipe
|
||||
artifact. Normal dependency resolution is allowed; any extra tooling module or
|
||||
bootstrap must be included in the implementation and documentation.
|
||||
|
||||
## Correctness and Java 25
|
||||
|
||||
- Demonstrate support for every Java construct actually used in the maintained
|
||||
backend, tests and CI helpers on the project's JDK 25.
|
||||
- Running the formatter on JDK 25 is not, by itself, proof that its parser supports
|
||||
every possible Java 25 construct. Record relevant limitations of the chosen
|
||||
pinned version.
|
||||
- An unprocessable file or formatter error fails the operation/build with its
|
||||
path and a concrete cause. Do not silently skip it or exclude it merely to
|
||||
obtain a successful build or faster measurement.
|
||||
- The adapter must preserve source paths and encoding and avoid corrupting files.
|
||||
- Formatting is deterministic and idempotent: applying it again produces no
|
||||
further source differences. Check-only and apply mode agree on the result.
|
||||
- Application behavior remains unchanged; builds and tests must pass after the
|
||||
initial formatting and subsequent formatter changes.
|
||||
|
||||
## Initial adoption and commit separation
|
||||
|
||||
Apply the chosen formatting to all existing maintained Java files in scope.
|
||||
Record this initial mass formatting in a separate **formatting-only commit**,
|
||||
without functional changes. Keep integration/configuration changes separate so
|
||||
reviewers can distinguish tooling changes from the mechanical source rewrite.
|
||||
|
||||
Native import ordering/removal is part of that formatting commit. Do not combine
|
||||
it with unrelated cleanup or refactoring.
|
||||
|
||||
## Performance requirements
|
||||
|
||||
The integration must be measured rather than selected on an unverified claim that
|
||||
one wrapper is faster than another.
|
||||
|
||||
- A repeated ordinary build with no Java-source changes may incur at most
|
||||
**three seconds of additional formatting-related overhead**.
|
||||
- Include the required integration/recipe/bootstrap overhead in that comparison;
|
||||
do not report only time spent inside the Palantir formatting function.
|
||||
- Compare otherwise equivalent builds with and without the formatting integration
|
||||
under the same environment/cache conditions.
|
||||
- Also measure a build after changing a maintained Java file and a `clean verify`
|
||||
run. Record these timings; the agreed three-second threshold specifically
|
||||
applies to the repeated unchanged-build case.
|
||||
- Report one-time dependency downloads separately, rather than disguising ongoing
|
||||
overhead as first-time setup or counting downloads as formatter execution.
|
||||
- Record the machine, JDK/Maven/tool versions, commands, file scope, cache state
|
||||
and results with the implementation evidence.
|
||||
|
||||
The time threshold is an acceptance criterion, not a hard interrupt that kills a
|
||||
formatter while it is writing source files. If the selected integration cannot
|
||||
meet the threshold, report the measurements and obtain agreement before choosing
|
||||
an alternative integration or relaxing the bound. Do not silently skip formatting,
|
||||
switch engines, choose Spotless or weaken the criterion.
|
||||
|
||||
## README and editor integration
|
||||
|
||||
Explain in the root `README.md`:
|
||||
|
||||
- The formatter, pinned versions/configuration and maintained file scope.
|
||||
- The standalone apply and check commands.
|
||||
- Which local Maven lifecycle commands can rewrite files and when that occurs.
|
||||
- The CI check-only invocation and how to reproduce and resolve a failure locally.
|
||||
- Clean-checkout bootstrap behavior and any included tooling artifact/module.
|
||||
- Available supported IDE integration and how to keep its result consistent with
|
||||
the project's pinned formatter.
|
||||
- The performance evidence and any relevant Java 25 syntax limitations.
|
||||
|
||||
Maven is the authoritative formatting path regardless of editor. Do not require
|
||||
format-on-save or an IDE plugin. An IDE integration must not redefine the agreed
|
||||
style or silently take precedence over the Maven result.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [x] The actual Palantir engine formats all maintained backend Java sources,
|
||||
Java tests and `ci/*.java`; generated code is excluded.
|
||||
- [x] OpenRewrite integration, custom adapter/recipe and bootstrap are implemented
|
||||
and reproducible from a clean checkout without manual recipe installation.
|
||||
- [x] Plugin, formatter and adapter dependencies are pinned, with matching local
|
||||
and CI configuration.
|
||||
- [x] Local Maven builds apply formatting before compilation; `compile`, `test`,
|
||||
`verify` and `install` reach the intended integration.
|
||||
- [x] Standalone apply and check commands work without the full application build.
|
||||
- [x] CI checks only, leaves maintained sources unchanged, reports formatting
|
||||
differences and fails before image publication.
|
||||
- [x] Import ordering and unused-import removal follow Palantir; optional extra
|
||||
Javadoc reformatting remains disabled and no unrelated refactoring is added.
|
||||
- [x] All currently used Java 25 syntax is handled, or causes an explicit failure
|
||||
requiring resolution rather than silent exclusion.
|
||||
- [x] Apply/check results agree and a second apply produces no differences.
|
||||
- [x] Initial formatting is isolated in a formatting-only commit; application
|
||||
builds and tests remain green.
|
||||
- [x] Equivalent repeated unchanged-build measurements demonstrate at most three
|
||||
seconds of additional integration overhead. Changed-file and clean-build
|
||||
measurements and one-time downloads are reported separately.
|
||||
- [x] Failure to meet the performance bound is reported before changing the route
|
||||
or bound; a writing formatter is not killed to force compliance.
|
||||
- [x] README instructions cover local and CI commands, bootstrap, optional IDE
|
||||
use, authoritative Maven formatting and verification evidence.
|
||||
|
||||
## Implementation handoff
|
||||
|
||||
This specification records agreed behavior. It does not install a formatter,
|
||||
create an adapter, change Maven/CI behavior or reformat source files. Recipe loading,
|
||||
Java 25 compatibility and performance must be demonstrated during implementation;
|
||||
there is no pre-existing project benchmark establishing the preferred route's
|
||||
performance.
|
||||
|
||||
Implementation and measured acceptance evidence: [S8-formatting-evidence.md](../S8-formatting-evidence.md).
|
||||
Reference in New Issue
Block a user