Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
on:
pull_request:
push:
branches: [main]
branches: [main, release]
workflow_dispatch:

concurrency:
Expand Down
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ This document is intended for Spotless developers.
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).

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

## [3.3.0] - 2025-07-20
### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Locale;

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

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

/**
* Determines the path to the build tool executor (Maven or Gradle).
* This method first checks for the existence of a wrapper script in the project root.
* If the wrapper exists, returns a relative path to it, otherwise returns the global command.
*
* @param executor The build tool executor (GRADLE or MAVEN)
* @return The path to the executor - either the wrapper script path (e.g., "./gradlew")
* or the global command (e.g., "gradle")
*/
private String executorPath(Executor executor) {
final var wrapper = executorWrapperFile(executor);
if (wrapper.exists()) {
return "./" + wrapper.getName();
}

logger.info("Local %s wrapper (%s) not found, falling back to global command '%s'",
executor.name().toLowerCase(Locale.ROOT), executor.wrapper, executor.global);

return executor.global;
}

/**
* Resolves the wrapper script file for the specified build tool executor.
* On Windows systems, checks for both .bat and .cmd extensions.
* On non-Windows systems, uses the wrapper name without extension.
*
* @param executor The build tool executor (GRADLE or MAVEN)
* @return The File object representing the wrapper script
*/
private File executorWrapperFile(Executor executor) {
if (isWindows()) {
final var bat = root.toPath().resolve(executor.wrapper + ".bat").toFile();
if (bat.exists()) {
return bat;
}

return root.toPath().resolve(executor.wrapper + ".cmd").toFile();
}

return root.toPath().resolve(executor.wrapper).toFile();
}

/**
* Checks if the current operating system is Windows.
* This is determined by checking if the "os.name" system property contains "win".
*
* @return true if the current OS is Windows, false otherwise
*/
private boolean isWindows() {
return System.getProperty("os.name").toLowerCase(Locale.ROOT).startsWith("win");
}

/**
* Checks if Git is installed by validating the existence of `.git/config` in the repository root.
*
Expand Down Expand Up @@ -243,6 +296,18 @@ private void writeFile(File file, String content, boolean append) throws IOExcep
}
}

public enum Executor {
GRADLE("gradlew", "gradle"), MAVEN("mvnw", "mvn"),;

public final String wrapper;
public final String global;

Executor(String wrapper, String global) {
this.wrapper = wrapper;
this.global = global;
}
}

public interface GitPreHookLogger {
void info(String format, Object... arguments);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package com.diffplug.spotless;

import static com.diffplug.spotless.GitPrePushHookInstaller.Executor.GRADLE;

import java.io.File;

/**
Expand All @@ -23,30 +25,15 @@
*/
public class GitPrePushHookInstallerGradle extends GitPrePushHookInstaller {

/**
* The Gradle wrapper file (`gradlew`) located in the root directory of the project.
*/
private final File gradlew;

public GitPrePushHookInstallerGradle(GitPreHookLogger logger, File root) {
super(logger, root);
this.gradlew = root.toPath().resolve("gradlew").toFile();
}

/**
* {@inheritDoc}
*/
@Override
protected String preHookContent() {
return preHookTemplate(executorPath(), "spotlessCheck", "spotlessApply");
}

private String executorPath() {
if (gradlew.exists()) {
return gradlew.getAbsolutePath();
}

logger.info("Gradle wrapper is not installed, using global gradle");
return "gradle";
return preHookTemplate(GRADLE, "spotlessCheck", "spotlessApply");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package com.diffplug.spotless;

import static com.diffplug.spotless.GitPrePushHookInstaller.Executor.MAVEN;

import java.io.File;

/**
Expand All @@ -23,27 +25,15 @@
*/
public class GitPrePushHookInstallerMaven extends GitPrePushHookInstaller {

private final File mvnw;

public GitPrePushHookInstallerMaven(GitPreHookLogger logger, File root) {
super(logger, root);
this.mvnw = root.toPath().resolve("mvnw").toFile();
}

/**
* {@inheritDoc}
*/
@Override
protected String preHookContent() {
return preHookTemplate(executorPath(), "spotless:check", "spotless:apply");
}

private String executorPath() {
if (mvnw.exists()) {
return mvnw.getAbsolutePath();
}

logger.info("Maven wrapper is not installed, using global maven");
return "mvn";
return preHookTemplate(MAVEN, "spotless:check", "spotless:apply");
}
}
2 changes: 2 additions & 0 deletions plugin-gradle/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`).

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

## [7.2.0] - 2025-07-20
### Added
Expand Down
2 changes: 2 additions & 0 deletions plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).

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

## [2.46.0] - 2025-07-20
### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ public MavenRunner withArguments(String... args) {
return this;
}

public MavenRunner withEnvironment(String key, String value) {
environment.put(key, value);
return this;
}

public MavenRunner withRunner(ProcessRunner runner) {
this.runner = runner;
return this;
Expand Down
Loading
Loading