预提交无法在嵌套的 go 模块中发现任何 golang 文件

pre-commit not able to discover any golang files in nested go module

我有一个大型仓库,例如 github.com/myusername/myrepo

现在在该回购协议中(出于超出此问题范围的原因)我已经初始化了以下 go 模块:github.com/myusername/myrepo/eck-user-mgmt

这是我的 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

然而没有gofiles/modules/whatever被发现

▶ 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

这是 pre-commit-config.yaml 所在的 运行,即 ~/work/myrepo/eck-user-mgmt

这是为什么?

p.s。我知道这不是 go 模块管理方面的最佳实践,我只是想知道是否有办法在特定的上下文中使 pre-commitgo 一起工作设置

go 命令通常 运行s 在 main 模块及其依赖项的上下文中。它通过在当前工作目录及其父目录中查找 go.mod 文件来找到主模块。

如果您的预提交是 运行 在存储库的根目录中并且那里没有 go.mod 文件,则命令将 运行 在任何模块之外。例如,go mod tidygo test ./... 不会做任何事情。

您可能需要 运行 每个模块中的那些命令。您可以在 shell 脚本中找到包含 go.mod 文件的目录:

modfiles=($(find . -type f -name go.mod))
for f in "${modfiles[@]}"; do
  pushd "$(dirname "$f")"
  ### presubmit commands
  popd
done

(no files to check)Skipped 表示没有匹配特定钩子types / files / exclude 的集合

查看您的设置:

这些组合在一起,因此您的存储库中匹配的文件必须匹配 ^eck-user-mgmt/ .go[=24= 结尾]

如果你 运行 git ls-files | grep '^eck-user-mgmt' | grep '\.go$' 那应该~大致复制预提交对处理文件匹配的作用

另请注意,您 运行 pre-commit run -- 默认情况下 only processes staged files. when adding new hooks you probably want to run pre-commit run --all-files


免责声明:我是预提交的作者

只是添加@Jay Conrod 建议的方法。

由于似乎 pre-commit 情况与 monorepos 相处得不太好,并且考虑到 go 情况变得更加复杂,我选择了以下 .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

其中 gomodules 是 repo 根目录中的一个文件,逐行列出 repo 的所有 go 模块。