Automatically format your Swift code when committing your work
I fell in love with SwiftFormat as code formatter for Swift sources as it offers various way to use the tool:
I prefer the Git pre-commit hook as it ensures that I don't forget to run the code formatter. Also by sharing the hook to teammates they won't forget :)
SwiftLint provides helpful information for setup but I'd like to give you some helpful tips & tricks in addition.
Myth: It is recommended that people install git-format-staged.
Truth: But you don't have to pre-install it. Simply use npx
as package runner to run on git-format-staged
on-demand. So you get rid by one more prerequiste.
#!/bin/bash
npx git-format-staged --formatter 'swiftformat stdin --stdinpath "{}"' '*.swift'
Note: npx
is bundled with npm and therefore it is very likely that uses already met this prerequisite. Even if that would not be the case then it is possible to install npx as a standalone package .
Challenge: It is true that git pre-commit hook in .git/hooks
won't be checked in to source control, and there's no way to guarantee that all users of the project will use them.
Solution: make hook installation easy
I check-in the above shell script in my repository in a custom folder structure scripts/githooks
.
To easily copy git hooks to .git/hooks
I normally have another shell script in my git repository (scripts/installGitHooks.sh
)
#!/bin/bash
# install git pre-commit hook
rm -f .git/hooks/pre-commit
ln -s ../../scripts/githooks/pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
Note: Installing git hooks is potentially only one step of many to setup tools for repository collaborators and therefore I provide a shell script in the git repository root folder (setupForCollaborators.sh
) as a single script to install tools.
#!/bin/bash
# install various git hooks
bash scripts/installGitHooks.sh
Challenge: using git-precommit hook and --exclude
SwiftFormat is highly configurable and it is possible to create a configuration file which can be added to your project and shared with other developers.
The --exclude
option takes a comma-delimited list of file or directory paths to exclude from formatting.
-exclude Pods
But there is a caveat when using this option with the above git hook. git-format-staged
will recognize your configuration file and therefore honors the rules but it will ignore your --exclude
option
Solution
#!/bin/bash
# pass information which files to be excluded to git-format-stages as --exclude option in .swiftformat config file is not honored by git-format-staged
npx git-format-staged --formatter 'swiftformat stdin --stdinpath "{}"' '*.swift' '!Pods/*'