How to prevent bad commits and test code with lefthook and integrate with Flutter
Tags: flutter, git
Published: 2022-06-17 19:20:35

Lefthook is a tool to give us more confidence in our commits, it work with a lot of programming languages and Frameworks such as Flutter, Go, Ruby, and many others, and even can execute some tasks like lint and test, with that said let's configure this to work with.

To get started it depends on your O.S, with Linux distributions like Ubuntu and Debian you have two different ways to do that

- using `curl`:

```
curl -1sLf 'https://dl.cloudsmith.io/public/evilmartians/lefthook/setup.deb.sh' | sudo -E bash
sudo apt install lefthook
```
If you don't have curl installed just type: `sudo apt install curl`

- using [Snap](https://snapcraft.io/docs/installing-snap-on-ubuntu):
you just have to type: `snap install --classic lefthook`

If you are using a macOS, you can try with [Homebrew](https://brew.sh/index_pt-br), to do that just: `brew install lefthook`

After this step, you should have the lefthook installed on your machine, let's see how to use it

To use in your project you have to go to the terminal and then move it to root, after that you have to type: `lefthook install` and a file named `lefthook.yml` has to be created in your project, in this example I created a Flutter project and execute the command, you can see the result below: 


![Lefthook created](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/55fm11scia593r8nb07e.png)

You can set some instructions at some moment of the commit process such as `pre-commit`, `pre-push`, and `commit-msg`, these instructions will be executed depending of what commit process they are inside, let me show an example:

```
pre-commit:
  parallel: true
  commands:
    tests:
      run: flutter test
    analyze:
      run: flutter analyze
```

In this code block above I'm executing some tasks in parallel before the commit process is done, in that case, I'm running the Flutter test and analyzing and the commit will be finished only if these tasks have been completed, let's have another example

```
pre-push:
  parallel: true
  commands:
    tests:
      run: flutter test
```

Now, with this code block above the task will run only when the push process has been started, in this case, I'm executing some Flutter test and the commit only will be done will all tests have been completed with success 

To finish, let's learn how to use the `commit-msg` block, in our case we will check the commit message using as a base the conventional commits spec, if you don't know about this concept you can [click here](https://gist.github.com/Zekfad/f51cb06ac76e2457f11c80ed705c95a3), so let's move, in this example, we have to create a folder called `bin` and inside then create a file called `commit_message.dart`, the result should be


![create folder and file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ofudszvsrrl7wqzrylf6.png)

Inside `bin/commit_message.dart` file, we can insert the below code

```
import 'dart:io';

dynamic main() {
  final rootDir = Directory.current;
  final commitFile = File("${rootDir.path}/.git/COMMIT_EDITMSG");
  final commitMessage = commitFile.readAsStringSync();

  final regExp = RegExp(
    r'(bugfix|feature|hotfix|none|chore|refactor|doc|style|test)(\(\w+\):\s?)(\[\w+-\d+])(.+)',
  );

  final valid = regExp.hasMatch(commitMessage);
  if (!valid) exitCode = 1;
}

```

This file basically gets the commit message and then passes a regex to check if they are in concern with the conventional commits, finally in our `lefthook.yml` file we can put

```
commit-msg:
  commands:
    validate:
      run: flutter pub run bin/commit_message.dart
```

With that, we execute the file created to check with lefthook if the message commit has matched with what was expected, in my case the final looks like

```
pre-commit:
  parallel: true
  commands:
    tests:
      run: flutter test
    analyze:
      run: flutter analyze
    lint_code:
      glob: '*.dart'
      run: dart fix --dry-run lib && git add .
    format_code:
      glob: '*.dart'
      run: flutter format {staged_files} && git add .       

commit-msg:
  commands:
    validate:
      run: flutter pub run bin/commit_message.dart  

```

For now, you've learned how to integrate this tool to keep your commits more safe and clean with clear messages, I hope that you liked it and see you in the next article.

[Lefthook repo](https://github.com/evilmartians/lefthook)