0

I have a pre-commit hook that runs some linting like so:

./gradlew app:ktlint --daemon

status=$?

if [ "$status" = 0 ]
then
    echo "${green}Linting found no problems.${reset}"
    exit 0
else
    echo 1>&2 "${red}Linting found issues.${reset}"
    echo "${yellow}Attempting to fix automatically...${reset}"
    ./gradlew app:ktlintFormat --daemon
    if [ $? = 0 ]
    then
        echo "${green}Fixed all issues automatically. Committing automagically...! :)${reset}"
        git add .
        git commit -m "Automatic commit of linted files" --no-verify
        exit 0
    else
        echo "${red}Could not fix all issues automatically, please review. :( ${reset}"
        exit 1
    fi  
fi

The issue here is that if the ktlint task fails, but the automatic format manages to fix all the problems, i have no way of re-adding only the files that were included in the initial commit.

Perhaps this is best explained with an example:

  • I have 3 files, A,B,C
  • I commit A & B, but not C
  • ktlint fails the commit due to formatting
  • ktlintFormat manages to fix the issues
  • Current behaviour: Formatted files A & B but also C are added and committed automatically
  • Wanted behaviour: Only the formatted A & B files are added and committed automatically

Thanks in advance!

davy307
  • 309
  • 3
  • 16

2 Answers2

1

Pre-commit hooks run on the codebase right before the commit goes through. I'd suggest removing the git add/commit lines after the automatic fixes goes through, so the script exits with a zero (successful) status.

You lose the ability to add to the message but the pre-commit will act exactly as it should.

To compare to your example:

  • 3 files, A,B,C
  • Commit A & B, but not C
  • ktlint fails the commit due to formatting
  • ktlintFormat manages to fix the issues
  • The commit continues, with A & B.

✌️

jdrydn
  • 50
  • 1
  • 4
  • sadly the files that get modified by ktlintFormat don't get re-committed, so it would continue the commit with the files that are incorrect... – davy307 Nov 15 '18 at 16:15
0

The solution was to keep track of which files were committed beforehand and then add those manually after the automatic lint formatting took place.

echo "${yellow}Running linting...${reset}"

#store the result of the commit in a variable and split into array items with newline
committedFiles=$(git diff --name-only --cached)
files=$(echo $committedFiles | tr ";" "\\n")

[...]

#after ktlintFormat runs and succeeds
echo "${green}Fixed all issues automatically. Committing..! :)${reset}"

#replay items in the commits array and add only those files
for file in $files
do
    git add $file
done
git commit -m "Automatic commit of linted files" --no-verify
exit 0

[...]
davy307
  • 309
  • 3
  • 16