What are Git Hooks?
Git hooks are basically scripts fired before an important action occurs, eg: before a commit is made, before code is pushed to a repo after a commit is made, etc. You can learn more about Git Hooks and the different kinds of hooks over here
A pre-commit hook is a hook that is run before you make a commit.
TLDR
- Install Mocha and Chai for testing
- Install Eslint for Linting
- Install Pretty and Pretty-quick for formatting
- Install Husky to setup pre-commit hook
- Test the pre-commit hook
Current Project Setup
I have two files, the first file is called 'utils.js'. It has 4 basic arithmetic functions.
const add =
(a, b) => a + b
const subtract =
(a, b) => a - b
const multiply =
(a, b) => a * b
const divide =
(a, b) => a / b
module.exports = {
add,subtract,multiply,divide
}
As you can see it is weirdly formatted and is missing semi-colons. This is done intentionally.
The second file is index.js
. It simply imports the functions from utils.js and exports them.
const {add,
subtract,
divide,
multiply} = require('./utils')
module.exports = {add,subtract, divide, multiply}
This is also intentionally formatted in a weird manner.
The project also has a basic package.json file generated using npm init
Step 1 Setup Testing
We will use mocha and chai for testing. We will write a single test case for each of our functions. To learn more about mocha and chai in-depth, refer to this article.
First, let's install mocha and chai
npm install --save-dev mocha
Next, let's install chai
npm install --save-dev chai
Now, we will create a file 'tester.js', and add a few tests to it.
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-undef */
const {
add, subtract, divide, multiply,
} = require('.');
assert = require('chai').assert;
describe('Sum', () => {
context('Adding 1 and 1', () => {
it('should return 2', () => {
assert(add(1, 1) === 2);
});
});
});
describe('Subtract', () => {
context('Subtracting 1 from 1', () => {
it('should return 0', () => {
assert(subtract(1, 1) === 0);
});
});
});
I have not included the entire tester file, there are a couple more test cases for multiply and divide.
Inside your package.json, add the following under scripts
"test": "mocha --timeout 2000 tester.js"
If you do not have 'scripts' in your package.json, create one. It should look like this
"scripts": {
"test": "mocha --timeout 2000 tester.js"
}
Now you can go to the terminal and run the following command
npm test
Step 2 Setup Linter
We will use the package eslint. First, let's install the package
npm install eslint --save-dev
Now we will need to initialize our linter
./node_modules/.bin/eslint --init
You will get a bunch of questions, answer them based on your project.
Finally, we will add a new command inside 'scripts' in 'package.json' You can add this under the 'test' command we added in the previous section.
"lint": "eslint --fix *.js"
This will run the linter on all your javascript files and fix the linting errors wherever it can.
You can also disable some es-lint checks by adding comments to the top of the file or above certain lines. For example, I disabled a couple of checks in the 'tester.js' file
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-undef */
Step 3 Setup Prettier
We will have to install a couple of packages prettier and pretty-quick to format the code.
Install prettier using the following command
npm install prettier -save-dev
Install pretty-quick using the following command
npm install pretty-quick --save-dev
Now we will add another command to our 'scripts' section in 'package.json'
"pretty-quick": "pretty-quick"
Do not run the command right now. Let's set up the pre-commit hook and run the command automatically.
Step 4 Setup Husky
We will use husky to set up our pre-commit hook.
Install the package
npm install husky@4 --save-dev
If you install V5 of husky, you might need to do some additional work to set up the pre-commit hook.
After installation add the following inside your 'package.json'
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged && npm run lint && npm test"
}
}
Basically, we tell husky to run the above commands (pretty-quick, lint, and the tests) before our files can be committed.
The --staged
runs the formatter only on the staged files.
Step 5 Test Pre-commit hook
Now we can finally test our pre-commit hook.
First, add your files
git add .
Type the following command to commit your files
git commit -m "Test commit"
You should see husky running the prettier, linter and testing scripts. Below is a screenshot of the terminal.
If the linter returns an error or one of the test cases fails, the commit will be unsuccessful and your files will remain in the staging area and not be committed.