If you’re a TypeScript user and you’re reading this, then you’re using TSLint (most likely). Recently, a situation at work arose where even though TSLint warnings were being thrown in the editor as well as terminal output, some developers (tsk tsk) were still committing these warnings.
Naturally, a pre-commit Git hook is the right candidate for this. Being able to run TSLint to ensure that before a developer can even commit let alone push, only valid code conforming to the tslint.json
file can be pushed.
This poses another problem. You can’t automatically add pre-commit hooks into the repository and have everyone automatically pull them down. This is for security reasons, could you imagine if someone committed a hook that deleted a bunch of files/folders?
If you’re using a task runner like Gulp or Grunt, then you can create a clever task that copies a file to the .git/hooks
directory for you.
Firstly, let’s create a pre-commit hook. In the root of your application create a new folder called hooks
and a new file called pre-commit
(with no file extension):
#!/bin/bash
TSLINT="$(git rev-parse --show-toplevel)/node_modules/.bin/tslint"
for file in $(git diff --cached --name-only | grep -E '\.ts$')
do
git show ":$file" | "$TSLINT" "$file"
if [ $? -ne 0 ]; then
exit 1
fi
done
Git hooks are actually bash scripts and can be quite powerful. We are creating a path to TSLint in our local application (some Git clients like Github for Windows require this) and using that to call TSLint on our files.
Secondly, let’s create our task. I personally use Gulp, but you can easily adapt the following to any task runner:
var gulp = require('gulp');
gulp.task('install-pre-commit-hook', function() {
gulp.src('hooks/pre-commit')
.pipe(gulp.dest('.git/hooks'));
});
gulp.task('default', ['install-pre-commit-hook']);
Running gulp
or gulp install-pre-commit-hook
will copy over our pre-commit hook and put it into the .git/hooks
directory. It is possible on Unix based operating systems that you need to adjust the file permissions using chmod
which the fs
module offers a method for, but possibly not needed.
Now, throw that task into your Npm build script and anyone else who has the latest changes will get the pre-commit hook every time the task runs. No more warnings from code written by others clogging up your terminal or editor.
I tried to do stuff like that in the past, but it gets real fiddly real soon. Now I just use husky, which works like a dream AND gives me other hooks too.
This is where a tool like git-guppy comes in handy. Rather than having to have your own pre-commit hook, you can install one that just runs gulp tasks for you. Keeps everything in one place. https://www.npmjs.com/package/git-guppy