Last active
April 12, 2023 15:09
-
-
Save tmelz/76e655a3d8f2878fc9a4 to your computer and use it in GitHub Desktop.
auto format java files with google-java-format
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Auto format changed java files using google-java-format. | |
# To install, copy this file into $repo/.git/hooks and remove the .sh extension. | |
# Download the google-java-format JAR from | |
# https://github.com/google/google-java-format | |
# A more mature implementation of this would be a plugin for Yelp's pre-commit library: | |
# http://pre-commit.com/ | |
echo "Running auto-formatter for any changed Java files" | |
echo "(formatting changes will be automatically added to your commit)" | |
# Grab root directory to help with creating an absolute path for changed files. | |
root_dir="$(git rev-parse --show-toplevel)" | |
[ -d "${root_dir}" ] || exit 1 | |
# TODO add your path here. | |
jar_base_dir="jar/" | |
# To avoid any unexpected behavior, we need to "stash" any unstaged changes. | |
# We could use "git stash" but the situation gets complicated because we | |
# need to make additional changes with the formatter. | |
# Here's how we could do this if we didn't need to make additional changes: | |
# http://stackoverflow.com/a/20480591 | |
# But since we do, we follow the same general pattern as the "pre-commit" lib: | |
# https://github.com/pre-commit/pre-commit/blob/master/pre_commit/staged_files_only.py#L15 | |
# Basically we just diff the unstaged changes, store the patch, and apply it later. | |
# In the future, we should consider migrating to using that library. | |
staged_changes_diff=$(mktemp -t format_patch) | |
git diff --ignore-submodules --binary --exit-code --no-color > $staged_changes_diff | |
if [ $? -eq 1 ]; then | |
echo "Found unstaged changes, storing in ${staged_changes_diff}" | |
echo "Clearing unstaged changes for formatting, will restore after formatting." | |
git checkout -- ${root_dir} | |
stored_staged_changes=true | |
else | |
stored_staged_changes=false | |
fi | |
formatter_jar="${root_dir}/${jar_base_dir}/google-java-format-0.1-alpha.jar" | |
formatter_cmd="java -jar ${formatter_jar}" | |
# Format file in-place and use 4-space style (AOSP). | |
# TODO remove --aosp flag if you want 2-space style. | |
formatter_args="--replace --aosp" | |
# filter=ACMR shows only added, changed, modified, or renamed files. | |
# Get only java files and prepend the root directory to make the paths absolute. | |
changed_java_files=($(git diff --cached --name-only --diff-filter=ACMR \ | |
| grep ".*java$" \ | |
| sed "s:^:${root_dir}/:")) | |
# If we have changed java files, format them! | |
if [ ${#changed_java_files[@]} -gt 0 ]; then | |
# Do the formatting, stage the changes, and print out which files were changed. | |
eval ${formatter_cmd} ${formatter_args} "${changed_java_files[@]}" | |
git add "${changed_java_files[@]}" | |
echo "${changed_java_files[@]}" | xargs basename | sed "s/^/ Formatting: /" | |
fi | |
echo "Finished formatting." | |
if $stored_staged_changes ; then | |
echo "Restoring unstaged changes" | |
git apply "${staged_changes_diff}" | |
if [ $? -eq 1 ]; then | |
echo "Shoot! We failed to re-apply your unstaged changes." | |
echo "The patch for these changes is preserved at ${staged_changes_diff}" | |
fi | |
fi |
Does it work if I use IntelliJ's changelist feature to commit?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There is a problem using this script under Linux.
Although OSX works, the above can be fixed on Linux by changing the line to read.