Git Hooks: pre-commit Hook for ESLint using Python

Introduction

What are Git Hooks?

Installing Hooks

Hooks are located in the ‘.git/hooksdirectory of a git repository. By default, git populates this directory with a bunch of .sample files, which are actually shell scripts.

To install a certain hook, remove its ‘.sample’ extension. There are default scripts provided for each script by git but you can write your own scripts in your preferred scripting language as per your standards.

Pre-commit Hook

Implementation

ESLint is a static code analysis tool for identifying problematic patterns found in JavaScript code, created by ‘Nicholas C. Zakas’. Rules in ESLint are configurable, and customized rules can be defined and loaded. ESLint covers both code quality and coding style issues.

1. Setup a Project :

  • Create a new directory for the project and navigate to that folder in command prompt or terminal.
  • Execute ‘npm init’ and fill in the options or press enter/return to choose default values.
Create a project using npm
  • Initialize git repository using ‘git init’ in Git Bash.
Initialize Git Repository
  • Create an app.js file in root directory and add some sample code.
// app.js
const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log('Listening on port 3001');
})

2. Install and Initialize the ESLint :

  • You can install ESLint using npm by executing the command:
npm install -g eslint
  • Initialize ESLint.

For a detailed explanation of coding standards and ESLint, you can visit this article.

  • I’ve added some rules to .eslintrc.json file but this is optional while using style guide like Airbnb.
{
"env": {
"browser": true,
"commonjs": true,
"es2021": true
},
"extends": "airbnb-base",
"overrides": [
],
"parserOptions": {
"ecmaVersion": "latest"
},
"rules": {
"no-console" : 0,
"camelcase": 1,
"eqeqeq" : 0,
"import/newline-after-import": "off",
"linebreak-style": 0
}
}

3. Install Pre-commit Hook

  • You’ll find pre-commit.sample file in ‘.git/hooks’ directory of your project.
  • In case you don’t see .git directory in your project folder, you might have to unhide it. If you are using VS Code as your text editor, you can unhide directory as follows :
    File -> Preferences -> Settings -> Text Editor -> Files -> Delete ‘**/.git’ from Exclude section.
  • Let’s install the hook by removing ‘.sample’ extension in ‘.git/hooks’.
  • You’ll see a default shell script on opening the pre-commit file. Let’s write some Python code to execute ESLint on files that are staged to commit.

pre-commit file :

#!/usr/bin/env python
import sys, os
if __name__ == '__main__':

display_errors = []

# Get all the files that are staged to commit.
# diff-filter: Used to filter files from the staged commit.
# A = Added files; C = Copied files; M = Modified files
staged_files = os.popen('git diff --cached --name-only --diff-filter=ACM')
# Loop through the files.
for file in staged_files.read().splitlines():
# To check for ESLint errors only in .js files.
# Remember if you push nodemodules to your repository you should add another condition:
# not file.startswith('node_modules/')
if file.endswith('.js'):
# Execute eslint for each file.
eslint_exec_result = os.popen('eslint '+ file)
# Add all the errors to display_errors array.
for error in eslint_exec_result.readlines():
display_errors.append(error)

if display_errors:
# Print all the errors
for error in display_errors:
print(error)
# Abort the commit(By returning a non-zero value)
sys.exit(1)
# Continue to commit.
sys.exit(0)

4. Commit Changes :

  • Let’s now try to add and commit the changes we’ve made so far.
  • The commit is aborted because we have some ESLint errors in our javascript files.
  • Let’s fix them and try to commit again.
// app.js
const express = require('express');
const app = express();

app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Listening on port 3000');
});
  • Now the commit is successful, which means we’ve passed the ESLint check.

Scope of Git Hooks

Conclusion

About the Author

About KBX Digital

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store