DEV Community

Thy Pham
Thy Pham

Posted on

Enforce coding style check and run tests before each code commit using Git hooks

Intro

Whenever we develop a new feature for our software, it's crucial to identify the problems in the code as soon as possible, ideally before committing the code to VCS. Because the later we discover bugs, the more expensive to fix them.

We can easily detect common problems like failing unit tests and wrong coding styles locally. We can even go further by enforcing it before every commit so that the code is clean and passes the tests before going to the Pull Request phase.

Sample project

Let's say I have a Node project with a function called sum() like below

const sum = (a: number, b: number): number => a + b;

export { sum };
Enter fullscreen mode Exit fullscreen mode

I wrote a unit test for this function using Jest:

import { sum } from './math';

test('sum of 2 + 3 is 5', () => {
  expect(sum(2, 3)).toBe(5);
});
Enter fullscreen mode Exit fullscreen mode

Furthermore, I have also set up ESLint and Prettier to check for coding style. (I will write a separate post to show you how to enable ESLint and Prettier in the Node project. This post mainly focuses on how to set up Git hook).

I added some scripts to my package.json file to run unit tests and check coding style with ESLint and Prettier

{
  "name": "sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "jest",
    "lint": "eslint ./src/**/*.ts",
    "prettier": " prettier --check ./src"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/jest": "^27.4.0",
    "@typescript-eslint/eslint-plugin": "^5.10.2",
    "@typescript-eslint/parser": "^5.10.2",
    "eslint": "^8.8.0",
    "eslint-config-airbnb-base": "^15.0.0",
    "eslint-plugin-import": "^2.25.4",
    "husky": "^7.0.4",
    "jest": "^27.4.7",
    "prettier": "2.5.1",
    "ts-jest": "^27.1.3"
  }
}
Enter fullscreen mode Exit fullscreen mode

The commands we want to use are:

To run unit tests:

> npm test 
Enter fullscreen mode Exit fullscreen mode

Checking code with ESLint:

> npm run lint
Enter fullscreen mode Exit fullscreen mode

Format code with Prettier

> npm run prettier
Enter fullscreen mode Exit fullscreen mode

Create Git hook

To enforce running the three commands above before every code commit, we will use Husky to set up a pre-commit hook:

> npm i -D husky
> npx husky install
> npx husky add .husky/pre-commit "npm run prettier"
Enter fullscreen mode Exit fullscreen mode

After running the commands above, you will see file .husky/pre-commit with command npm run prettier at the end. It meant, npm run prettier will run before every code commit.

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run prettier
Enter fullscreen mode Exit fullscreen mode

Append npm run lint and npm test to the end of the file

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run prettier
npm run lint
npm test
Enter fullscreen mode Exit fullscreen mode

Now we are done! Let's test our setup by creating our first commit:

> git add .
> git commit -m "my first commit."
Enter fullscreen mode Exit fullscreen mode

The output will look like below:

> sample@1.0.0 prettier
> prettier --check ./src

Checking formatting...
All matched files use Prettier code style!

> sample@1.0.0 lint
> eslint ./src/**/*.ts


> sample@1.0.0 test
> jest

 PASS  src/math.spec.ts
  ✓ sum of 2 + 3 is 5 (2 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.526 s, estimated 2 s
Ran all test suites.
[branch_1 ae6dfd0] my first commit.
 1 file changed, 1 insertion(+), 1 deletion(-)
Enter fullscreen mode Exit fullscreen mode

As you can see in the result above, the three commands are automatically run. If one of the commands fails, the code will not be committed.

Discussion (0)