Lint staged files on commit
How to run linting on staged files when committing code with no dependency: no (lint-staged | husky | pre-commit) needed.
Motivation
On most of my projects I want to run some checks on the code before it is committed.
This is usually done with tools like lint-staged
, husky
or pre-commit
.
You do not need those dependencies, it can be done easily with custom code.
Prepare
Of course the file names below are just examples, you can easily adapt them to your project structure.
Let’s create a scripts/prepare.js that will create the git hook when you run npm install
.
import { chmod, copyFile } from 'node:fs/promises'
// Install Git pre-commit hook.
const preCommitHook = '.git/hooks/pre-commit'
await copyFile('scripts/pre-commit.sh', preCommitHook)
await chmod(preCommitHook, 0o755)
And add a prepare
script to your package.json:
{
"scripts": {
+ "prepare": "node scripts/prepare.js"
}
}
Pre-commit hook
Now create the scripts/pre-commit.sh file that will be executed by git when you commit code.
This is just a starting point, you may add more logic. For now it just runs tests and ESLint on staged files. Notice that it greps only extensions
js
, ts
and tsx
, you may want to add more.
#!/bin/bash
npm test
[ $? -ne 0 ] && exit 1
EXIT_CODE=0
git diff --name-only --cached | grep -E '\.(js|ts|tsx)$' | while read FILE
do
[ -f "$FILE" ] || continue
./node_modules/.bin/eslint --fix "$FILE"
git add "$FILE"
[ $? -ne 0 ] && EXIT_CODE=1
done
exit $EXIT_CODE