Skip to content

Commit 5e9df11

Browse files
authored
Windows Compatibility Fix for Git Pre-push Hook (#2562)
2 parents 94da761 + 24ca3bc commit 5e9df11

File tree

12 files changed

+346
-56
lines changed

12 files changed

+346
-56
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
on:
66
pull_request:
77
push:
8-
branches: [main]
8+
branches: [main, release]
99
workflow_dispatch:
1010

1111
concurrency:

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ This document is intended for Spotless developers.
1010
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).
1111

1212
## [Unreleased]
13+
### Fixed
14+
* `GitPrePushHookInstaller` didn't work on windows, now fixed. ([#2562](https://github.com/diffplug/spotless/pull/2562))
1315

1416
## [3.3.0] - 2025-07-20
1517
### Added

lib/src/main/java/com/diffplug/spotless/GitPrePushHookInstaller.java

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.io.FileWriter;
2323
import java.io.IOException;
2424
import java.nio.file.Files;
25+
import java.util.Locale;
2526

2627
/**
2728
* Abstract class responsible for installing a Git pre-push hook in a repository.
@@ -192,12 +193,12 @@ private void uninstall(File gitHookFile) throws Exception {
192193
* @param commandApply The command to apply corrections.
193194
* @return A string template representing the Spotless Git pre-push hook content.
194195
*/
195-
protected String preHookTemplate(String executor, String commandCheck, String commandApply) {
196+
protected String preHookTemplate(Executor executor, String commandCheck, String commandApply) {
196197
var spotlessHook = "";
197198

198199
spotlessHook += "\n";
199200
spotlessHook += "\n" + HOOK_HEADER;
200-
spotlessHook += "\nSPOTLESS_EXECUTOR=" + executor;
201+
spotlessHook += "\nSPOTLESS_EXECUTOR=" + executorPath(executor);
201202
spotlessHook += "\nif ! $SPOTLESS_EXECUTOR " + commandCheck + " ; then";
202203
spotlessHook += "\n echo 1>&2 \"spotless found problems, running " + commandApply + "; commit the result and re-push\"";
203204
spotlessHook += "\n $SPOTLESS_EXECUTOR " + commandApply;
@@ -209,6 +210,58 @@ protected String preHookTemplate(String executor, String commandCheck, String co
209210
return spotlessHook;
210211
}
211212

213+
/**
214+
* Determines the path to the build tool executor (Maven or Gradle).
215+
* This method first checks for the existence of a wrapper script in the project root.
216+
* If the wrapper exists, returns a relative path to it, otherwise returns the global command.
217+
*
218+
* @param executor The build tool executor (GRADLE or MAVEN)
219+
* @return The path to the executor - either the wrapper script path (e.g., "./gradlew")
220+
* or the global command (e.g., "gradle")
221+
*/
222+
private String executorPath(Executor executor) {
223+
final var wrapper = executorWrapperFile(executor);
224+
if (wrapper.exists()) {
225+
return "./" + wrapper.getName();
226+
}
227+
228+
logger.info("Local %s wrapper (%s) not found, falling back to global command '%s'",
229+
executor.name().toLowerCase(Locale.ROOT), executor.wrapper, executor.global);
230+
231+
return executor.global;
232+
}
233+
234+
/**
235+
* Resolves the wrapper script file for the specified build tool executor.
236+
* On Windows systems, checks for both .bat and .cmd extensions.
237+
* On non-Windows systems, uses the wrapper name without extension.
238+
*
239+
* @param executor The build tool executor (GRADLE or MAVEN)
240+
* @return The File object representing the wrapper script
241+
*/
242+
private File executorWrapperFile(Executor executor) {
243+
if (isWindows()) {
244+
final var bat = root.toPath().resolve(executor.wrapper + ".bat").toFile();
245+
if (bat.exists()) {
246+
return bat;
247+
}
248+
249+
return root.toPath().resolve(executor.wrapper + ".cmd").toFile();
250+
}
251+
252+
return root.toPath().resolve(executor.wrapper).toFile();
253+
}
254+
255+
/**
256+
* Checks if the current operating system is Windows.
257+
* This is determined by checking if the "os.name" system property contains "win".
258+
*
259+
* @return true if the current OS is Windows, false otherwise
260+
*/
261+
private boolean isWindows() {
262+
return System.getProperty("os.name").toLowerCase(Locale.ROOT).startsWith("win");
263+
}
264+
212265
/**
213266
* Checks if Git is installed by validating the existence of `.git/config` in the repository root.
214267
*
@@ -243,6 +296,18 @@ private void writeFile(File file, String content, boolean append) throws IOExcep
243296
}
244297
}
245298

299+
public enum Executor {
300+
GRADLE("gradlew", "gradle"), MAVEN("mvnw", "mvn"),;
301+
302+
public final String wrapper;
303+
public final String global;
304+
305+
Executor(String wrapper, String global) {
306+
this.wrapper = wrapper;
307+
this.global = global;
308+
}
309+
}
310+
246311
public interface GitPreHookLogger {
247312
void info(String format, Object... arguments);
248313

lib/src/main/java/com/diffplug/spotless/GitPrePushHookInstallerGradle.java

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package com.diffplug.spotless;
1717

18+
import static com.diffplug.spotless.GitPrePushHookInstaller.Executor.GRADLE;
19+
1820
import java.io.File;
1921

2022
/**
@@ -23,30 +25,15 @@
2325
*/
2426
public class GitPrePushHookInstallerGradle extends GitPrePushHookInstaller {
2527

26-
/**
27-
* The Gradle wrapper file (`gradlew`) located in the root directory of the project.
28-
*/
29-
private final File gradlew;
30-
3128
public GitPrePushHookInstallerGradle(GitPreHookLogger logger, File root) {
3229
super(logger, root);
33-
this.gradlew = root.toPath().resolve("gradlew").toFile();
3430
}
3531

3632
/**
3733
* {@inheritDoc}
3834
*/
3935
@Override
4036
protected String preHookContent() {
41-
return preHookTemplate(executorPath(), "spotlessCheck", "spotlessApply");
42-
}
43-
44-
private String executorPath() {
45-
if (gradlew.exists()) {
46-
return gradlew.getAbsolutePath();
47-
}
48-
49-
logger.info("Gradle wrapper is not installed, using global gradle");
50-
return "gradle";
37+
return preHookTemplate(GRADLE, "spotlessCheck", "spotlessApply");
5138
}
5239
}

lib/src/main/java/com/diffplug/spotless/GitPrePushHookInstallerMaven.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package com.diffplug.spotless;
1717

18+
import static com.diffplug.spotless.GitPrePushHookInstaller.Executor.MAVEN;
19+
1820
import java.io.File;
1921

2022
/**
@@ -23,27 +25,15 @@
2325
*/
2426
public class GitPrePushHookInstallerMaven extends GitPrePushHookInstaller {
2527

26-
private final File mvnw;
27-
2828
public GitPrePushHookInstallerMaven(GitPreHookLogger logger, File root) {
2929
super(logger, root);
30-
this.mvnw = root.toPath().resolve("mvnw").toFile();
3130
}
3231

3332
/**
3433
* {@inheritDoc}
3534
*/
3635
@Override
3736
protected String preHookContent() {
38-
return preHookTemplate(executorPath(), "spotless:check", "spotless:apply");
39-
}
40-
41-
private String executorPath() {
42-
if (mvnw.exists()) {
43-
return mvnw.getAbsolutePath();
44-
}
45-
46-
logger.info("Maven wrapper is not installed, using global maven");
47-
return "mvn";
37+
return preHookTemplate(MAVEN, "spotless:check", "spotless:apply");
4838
}
4939
}

plugin-gradle/CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`).
44

55
## [Unreleased]
6+
### Fixed
7+
* `spotlessInstallGitPrePushHook` didn't work on windows, now fixed. ([#2562](https://github.com/diffplug/spotless/pull/2562))
68

79
## [7.2.0] - 2025-07-20
810
### Added

plugin-maven/CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).
44

55
## [Unreleased]
6+
### Fixed
7+
* `spotless:install-git-pre-push-hook` didn't work on windows, now fixed. ([#2562](https://github.com/diffplug/spotless/pull/2562))
68

79
## [2.46.0] - 2025-07-20
810
### Added

plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ public MavenRunner withArguments(String... args) {
5656
return this;
5757
}
5858

59+
public MavenRunner withEnvironment(String key, String value) {
60+
environment.put(key, value);
61+
return this;
62+
}
63+
5964
public MavenRunner withRunner(ProcessRunner runner) {
6065
this.runner = runner;
6166
return this;

0 commit comments

Comments
 (0)