# Automatically format your Swift code when committing your work

I fell in love with  [SwiftFormat](https://github.com/nicklockwood/SwiftFormat) as code formatter for Swift sources as it offers various way to use the tool:
-  [Command-line tool](https://github.com/nicklockwood/SwiftFormat#command-line-tool) 
-  [Xcode Source Editor extension](https://github.com/nicklockwood/SwiftFormat#xcode-source-editor-extension) 
-  [Xcode build phase](https://github.com/nicklockwood/SwiftFormat#xcode-build-phase) 
-  [Git pre-commit hook](https://github.com/nicklockwood/SwiftFormat#git-pre-commit-hook) 
- ...

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](https://blog.eidinger.info/automatically-format-your-swift-code-when-committing-your-work ) but I'd like to give you some helpful tips & tricks in addition.

**Myth**: It is recommended that people install [git-format-staged](https://github.com/hallettj/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.

```bash
#!/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](https://www.npmjs.com/package/npx) .

**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`)

```bash
#!/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.

```bash
#!/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](https://github.com/nicklockwood/SwiftFormat#config-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**

```bash
#!/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/*'
```


