Skip to content

Run the native formatter from the Gradle plugin on Windows - #28

Merged
abashev merged 3 commits into
mainfrom
windows-native-gradle
Sep 22, 2026
Merged

abashev merged 3 commits into
mainfrom
windows-native-gradle

Conversation

@abashev

@abashev abashev commented Sep 22, 2026

Copy link
Copy Markdown
Collaborator

openjavaformat.native.formatter=true now takes effect on Windows on x86-64, with the Windows binary that 2.98.0.2 publishes (nativeImage-windows_x86-64.exe). Until now the plugin ignored the property there and ran the Java formatter.

  • ExecutableTransform skips POSIX permissions where the file system has none, and keeps an .exe name instead of appending .executable. That name also names the copy in the IntelliJ IDEA cache.
  • Tests can now run on Windows: paths in generated Groovy build scripts use forward slashes, the classpath is split on File.pathSeparator instead of ':', FormatDiffTest runs java.exe, and the test copy of the binary keeps .exe, the artifact type the plugin resolves on Windows.
  • CI runs the plugin tests against the native image on Windows too.

On macOS the native job's tests (8 in jdk-bootstrap, 31 in the Gradle plugin) and ./gradlew test pass. This PR's CI is the first run of these tests on Windows.

openjavaformat.native.formatter=true now takes effect on Windows on x86-64 too, where 2.98.0.2 published a binary, nativeImage-windows_x86-64.exe. Before, the plugin ignored the property on Windows and ran the Java formatter.

ExecutableTransform made that impossible: it asked for POSIX permissions, which a Windows file system does not have, so Files.getPosixFilePermissions would have thrown. It now skips them where the file system has no POSIX view; an .exe needs none to run. It also keeps an .exe name instead of appending .executable, and since the transformed name also names the copy in the IntelliJ IDEA cache, the binary ends in .exe everywhere the plugin hands it on.

The tests could not have run on Windows either. The generated build scripts took paths inside Groovy strings, where a Windows backslash starts an escape, so those paths are written with forward slashes. The classpath was split on ':', which cuts a Windows path after its drive letter, so it is split on File.pathSeparator. FormatDiffTest ran bin/java without .exe, where FormatterServicesTest already added it. And the copy of the binary the tests use was renamed to .bin, the artifact type of every other platform, while the plugin resolves the Windows binary as exe, so that copy keeps .exe. The native CI job on Windows now runs the plugin tests against the image, as on the other platforms.

On macOS the native job's tests, 8 in jdk-bootstrap and 31 in the Gradle plugin, and ./gradlew test pass. Windows is for CI to show.
The first Windows run of the plugin tests failed three cases, none of them in the native formatter. The Windows checkout gives example1.patch CRLF line endings, so parsing it as git output found no files; git itself prints a diff with LF, so the test now reads the fixture that way. And Spotless writes the platform's line endings, CRLF on Windows, which the Spotless test compared against a text block with LF; it now compares ignoring line endings.
With the fixture read as LF, the second Windows run parsed both files, and the test failed only on how it wrote the expected path: SingleFileDiff keeps a Path, which prints with backslashes on Windows. The expected string now builds that path with Path.of, so it prints the platform's way on every system.
@abashev
abashev merged commit a2c8970 into main Sep 22, 2026
10 checks passed
@abashev
abashev deleted the windows-native-gradle branch September 22, 2026 14:31
abashev added a commit to openjavaformat/docs that referenced this pull request Sep 22, 2026
The plugin now runs the native formatter on Windows x86-64 as well
(openjavaformat/open-java-format#28), so the Gradle page and the home page
list Windows next to Linux and macOS. The change ships with the next
release: until then the 2.98.0.2 plugin ignores the property on Windows.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant