Git hooks.

Git hooks are scripts that I can place in the hooks folder that resides in the hidden git folder of a project working tree. Because I use git as my system of source control this is an option that I can use to help automate tasks. However there are other options for task automation that I prefer, such as npm scripts. So for the most part I see hooks as a way to enforce compliance with certain standards before being allowed to make a commit to a git folder.

So a simple little hello world “pre-commit” node.js hook might look something like this.

1
2
3
#!/usr/bin/env node
console.log('Hey a commit was made.');

I will want to use the nodejs shebang at the top of my script to make it clear that the environment i am using is node. In addition I will want to name the file “pre-commit” in the hooks folder if I want a script to run every time I make a commit.

When it comes to writing a more useful pre-commit hook, I could write something that will check if everything is up to snuff before allowing a commit to be made. The basic idea here is to call a process.exit(1) if something does not look good, therefore keeping me from making a commit until it is resolved.

For an example of this say I want a simple little script that will check if a setting in a JSON file is set to a value that it should be set to every time I make a commit. Say it is a value that I would change while developing, but would want it to always be set to a certain other value every time I make a commit that will be merged into the master branch.

So the first thing I would want to do is check if my settings.json is even there at all. Yeah that would all ready be a pretty good reason the throw an error and stop the commit if this where a real project.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env node
var fs = require('fs');
fs.readFile('settings.json', 'utf8', function (err, data) {
if (err) {
console.log('Error reading settings.json');
console.log(err);
process.exit(1);
}
});

So far I have a script that is somewhat useful in that it will not allow for a commit to be made if my settings.json file is not present at all. To make it even more useful I just need to add more functionality to the script such as attempting to read the data in settings.json and throwing an error if there is a problem parsing the data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/usr/bin/env node
var fs = require('fs');
fs.readFile('settings.json', 'utf8', function (err, data) {
var settings;
if (err) {
console.log('Error: Problem reading settings.json');
console.log(err);
process.exit(1);
} else {
try {
settings = JSON.parse(data);
if(settings.mode){
if(settings.mode === 'production'){
console.log('Settings mode is production, looking good.');
process.exit(0);
}else{
console.log('Error: the settings mode is not set to production.');
process.exit(1);
}
}else{
console.log('Error: No mode property in settings!');
process.exit(1);
}
} catch (e) {
console.log('Error: Parsing JSON data');
process.exit(1);
}
}
});

This script will only allow a commit if there is a settings.json file, that will parse without issue, and has a mode property that has a value of production. So now you should get the idea, these kinds of scripts are useful for enforcing certain kinds of rules that must be met before a commit can be made. They could also be used to set things up for the next commit as well, saving some time.

Conclusion

For the most part I can not say that I ever use client side hooks in git projects. That may change at some point in the future, or it might not. Things like this will of course change from one project to the next, and there is often more that one way to do the same thing. As long as I am working with javaScript for many reasons I like to use Npm scripts as a way to automate tasks.