Pre-commit-Golang v1.0.0-beta.1 – Now with support for running custom go tools
Tags: showdev, go, git, github
Published: 2021-08-07 01:09:52

## About

pre-commit-golang is a set of [pre-commit](https://pre-commit.com) hooks for Golang with support for monorepos, the ability to pass arguments to all hooks, and the ability to invoke custom go tools.

Quick Links: [Project Page](https://github.com/TekWizely/pre-commit-golang) | [Available Hooks](https://github.com/TekWizely/pre-commit-golang#hooks) | [Installation](https://github.com/TekWizely/pre-commit-golang#installation) | [Releases](https://github.com/TekWizely/pre-commit-golang/releases)

## Release Announcement: v1.0.0-beta.1
I'm excited to announce that v1.0.0 is finally on the horizon !

This release accomplishes the two biggest things I wanted to reach v1.0.0:
* Invoking Custom Tools
* Removing Duplicate Code

Read below to learn more about both of these.

See the [project's readme](https://github.com/TekWizely/pre-commit-golang#readme) for more in-depth documentation.

**NOTE:** Due do the extent of new code in this release, I'm first releasing it as a `beta` until it has some time in the wild.

I've done a lot of local testing, but I don't have an automated test suite for the project yet, so please take a minute to report [issues](https://github.com/TekWizely/pre-commit-golang/issues) if you find any.

---
### Invoking Custom Tools
While this project includes builtin hooks for many popular go tools, it's not possible to include builtin hooks for every tool that users might want to use.

To help accommodate those users, this release introduces the ability to invoke custom go tools.

Using the `my-cmd-*` hooks, you can invoke custom go tools in various contexts.

| Hook ID           | Description
|-------------------|------------
| `my-cmd`          | Run `'$ARGS[0] [$ARGS[1:]] $FILE'` for each staged .go file
| `my-cmd-mod`      | Run `'cd $(mod_root $FILE); $ARGS[0] [$ARGS[1:]] ./...'` for each staged .go file
| `my-cmd-pkg`      | Run `'$ARGS[0] [$ARGS[1:]] ./$(dirname $FILE)'` for each staged .go file
| `my-cmd-repo`     | Run `'$ARGS[0] [$ARGS[1:]]'` in the repo root folder
| `my-cmd-repo-mod` | Run `'cd $(mod_root); $ARGS[0] [$ARGS[1:]] /...'` for each module in the repo
| `my-cmd-repo-pkg` | Run `'$ARGS[0] [$ARGS[1:]] ./...'` in repo root folder

#### Configuring the hooks

The my-cmd hooks are configured **entirely** through the pre-commit `args` attribute, including specifying which tool to run (ie `$ARGS[0]` above)

#### Examples

Here's an example of what it would look like to use the my-cmd hooks to invoke `go test` if it wasn't already included:

_.pre-commit-config.yaml_
```
# ...
      hooks:
            # Run 'cd $(mod_root $FILE); go test ./...' for each staged .go file
        -   id: my-cmd-mod
            name: go-test-mod
            alias: go-test-mod
            args: [ go, test ]
```


---
### Removing Duplicate Code
This release constitutes a huge re-factoring of the code, moving common logic into the lib/ folder, and removing as much code duplication as possible.

For example, here is the complete content of `go-lint.sh` :
```
#!/usr/bin/env bash
# shellcheck disable=SC2034  # vars used by sourced script
error_on_output=0
cmd=(golint -set_exit_status)
# shellcheck source=lib/cmd-files.bash
. "$(dirname "${0}")/lib/cmd-files.bash"
```

Thats it !

This should make it much easier to add new hooks, as well as all hooks being able to take advantage of future bug fixes and enhancements to the common code.