英文:
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
然而,没有发现任何go
文件/模块/其他内容:
▶ 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
。
为什么会这样?
附注:我知道这在go
模块管理方面不是最佳实践,我只想知道在特定设置的情况下,是否有办法让pre-commit
与go
一起工作。
英文:
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
答案1
得分: 2
go命令通常在main模块及其依赖项的上下文中运行。它通过在当前工作目录及其父目录中查找go.mod
文件来找到主模块。
如果您的pre-commit在存储库的根目录中运行,并且那里没有go.mod
文件,那么命令将在任何模块之外运行。例如,go mod tidy
和go test ./...
将不起作用。
您可能需要在每个模块中运行这些命令。您可以在shell脚本中找到包含go.mod
文件的目录:
modfiles=($(find . -type f -name go.mod))
for f in "${modfiles[@]}"; do
pushd "$(dirname "$f")"
### presubmit commands
popd
done
英文:
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
答案2
得分: 2
只是在@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
是位于仓库根目录的文件,逐行列出了仓库中的所有go模块。
英文:
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.
答案3
得分: 0
(no files to check)Skipped
表示没有任何文件与特定的钩子的 types
/ files
/ exclude
集合匹配。
根据你的设置,你有:
- 顶层:
files: ^eck-user-mgmt/
- 在每个钩子中(有一些是
files: \.go$
和types:
的混合)
这些被组合在一起,所以你的仓库中将匹配的文件必须同时满足 ^eck-user-mgmt/
和 以 .go
结尾。
如果你运行 git ls-files | grep '^eck-user-mgmt' | grep '\.go$'
,这应该大致复制了 pre-commit 处理文件匹配的过程。
还要注意,你运行了 pre-commit run
-- 默认情况下,这个命令只处理已暂存的文件。当添加新的钩子时,你可能想要运行 pre-commit run --all-files
。
免责声明:我是 pre-commit 的作者。
英文:
(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:
- ** top level **:
files: ^eck-user-mgmt/
- at each hook (there's a mix of
files: \.go$
andtypes:
)
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论