1

I have a large repo in the likes of github.com/myusername/myrepo

Now within that repo (for reasons beyond the scope of this question) I have initialised the following go module: github.com/myusername/myrepo/eck-user-mgmt

Here is my github.com/myusername/myrepo/eck-user-mgmt/.pre-commit-config.yaml

---
files: ^eck-user-mgmt/
repos:
  - repo: git://github.com/dnephin/pre-commit-golang
    rev: v0.4.0
    hooks:
      - id: go-fmt
      - id: go-imports
      - id: go-unit-tests
      - id: go-mod-tidy
      - id: golangci-lint

However no go files/modules/whatever is discovered

▶ g add .pre-commit-config.yaml && pre-commit run
go fmt...............................................(no files to check)Skipped
go imports...........................................(no files to check)Skipped
go-unit-tests........................................(no files to check)Skipped
go-mod-tidy..........................................(no files to check)Skipped
golangci-lint........................................(no files to check)Skipped

This is run from where pre-commit-config.yaml resides, i.e. ~/work/myrepo/eck-user-mgmt

why is that?

p.s. I know this is not the best practice in terms of go module management, I just want to know if there is a way with the make pre-commit work with go in the context of the specific setup

anthony sottile
  • 61,815
  • 15
  • 148
  • 207
pkaramol
  • 16,451
  • 43
  • 149
  • 324
  • 1
    Does this answer your question? [Can the python pre-commit tool consider a subdirectory as a base of the project?](https://stackoverflow.com/questions/64773189/can-the-python-pre-commit-tool-consider-a-subdirectory-as-a-base-of-the-project) – anthony sottile Aug 24 '21 at 19:17

3 Answers3

2

The go command generally runs in the context of a main module and its dependencies. It finds the main module by looking for a go.mod file in the current working directory and its parent directories.

If your pre-commit is run in the root directory of the repository and there's no go.mod file there, commands will be run outside any module. So go mod tidy and go test ./... won't do anything for example.

You'll likely need to run those commands within each module. You can locate directories containing go.mod files in a shell script:

modfiles=($(find . -type f -name go.mod))
for f in "${modfiles[@]}"; do
  pushd "$(dirname "$f")"
  ### presubmit commands
  popd
done
Jay Conrod
  • 28,943
  • 19
  • 98
  • 110
2

Just adding up to the approach suggested by @Jay Conrod.

Since it seems pre-commit situations do not get along so well with monorepos and given that this becomes even more complex when it comes to go, I opted for the following .git/pre-commit

GOMODULESFILENAME="gomodules"

declare -a gomodarray

precommit() {
    go mod tidy
    go fmt
    go test ./... -coverprofile cover.out;
    go tool cover -func cover.out
    rm cover.out
}

while read -r line;
do  
    gomodarray+=("$(echo "$line")")
done<gomodules

for f in "${gomodarray[@]}"; do
        echo "Running golang pre-commit actions for project: $f"
        sleep 1
        pushd "$f"
        precommit
        popd
done

where gomodules is a file at the root of the repo listing line by line all go modules of the repo.

pkaramol
  • 16,451
  • 43
  • 149
  • 324
0

(no files to check)Skipped means that nothing is matching the set of types / files / exclude for the specific hooks

looking at your setup you have:

these get combined together, so your files that will be matched in your repository must match both ^eck-user-mgmt/ and end with .go

if you run git ls-files | grep '^eck-user-mgmt' | grep '\.go$' that should ~roughly replicate what pre-commit does to process file matching

note also that you ran pre-commit run -- by default this only processes staged files. when adding new hooks you probably want to run pre-commit run --all-files


disclaimer: I am the author of pre-commit

anthony sottile
  • 61,815
  • 15
  • 148
  • 207
  • Yes but running this command `git ls-files | grep '^eck-user-mgmt' | grep '\.go$'` does discover the `.go` files in my subdir. However `pre-commit run --all-files` still tries to execute from the parent (repo root) folder – pkaramol Aug 24 '21 at 18:54
  • that's an issue of the underlying tool itself then and not the framework (though I suspect that you're trying to make a monorepo setup work, which doesn't gel nicely with git hooks in general -- you may find this relevant: https://stackoverflow.com/q/64773189/812183) – anthony sottile Aug 24 '21 at 19:15
  • OK many thanks for the feedback! appreciated – pkaramol Aug 24 '21 at 19:20