怎么做go linters忽略供应商/?

时间:2016-11-10 15:59:47

标签: go

我们如何使go vetgofmt和其他Go linter工具忽略vendor/中的第三方文件,最好是具有准确的累积退出状态?

例如,find . -name vendor -prune -o -name '*.go' -exec gofmt -s -w {} \;会提出有意义的退出状态吗?

8 个答案:

答案 0 :(得分:5)

我经常做

go fmt $(go list ./... | grep -v /vendor/)
go test $(go list ./... | grep -v /vendor/)

但是自从我开始使用govendor发现后,我可以使用govendor进行更少的输入

govendor fmt +l // +l is shorthand for local

答案 1 :(得分:3)

通常go listfind更有用:

$ go list ./... 
arp242.net/trackwall
arp242.net/trackwall/cmdline
arp242.net/trackwall/vendor/arp242.net/sconfig
arp242.net/trackwall/vendor/bitbucket.org/pkg/inflect
[..trim..]

如您所见,这将列出当前目录中的所有包名称。要过滤vendor目录,我们可以使用grep

$ go list ./... | grep -v /vendor/
arp242.net/trackwall
arp242.net/trackwall/cmdline

如果您想运行多个短节,报告所有错误,并且仅在成功时返回0,您可以使用循环和状态变量:

#!/bin/sh

st=0
for pkg in $(go list ./... | grep -v /vendor/); do
    echo "==> $pkg"

    go vet "$pkg"
    [ $? -ne 0 ] && st=1

    golint "$pkg"
    [ $? -ne 0 ] && st=1

    # gofmt works on files, not packages
    gofmt -d "${f#arp242.net/trackwall}"*.go
    [ $? -ne 0 ] && st=1
done
exit $st

将输出如下内容:

==> arp242.net/trackwall
http.go:71: database/sql.NullString composite literal uses unkeyed fields
exit status 1
/home/martin/gocode/src/arp242.net/trackwall/http.go:70:2: don't use ALL_CAPS in Go names; use CamelCase
/home/martin/gocode/src/arp242.net/trackwall/http.go:75:9: if block ends with a return statement, so drop this else and outdent its block
==> arp242.net/trackwall/cmdline
Exit 1

当然,你不是第一个遇到这个问题的人,并且有一些工具基本上和上面一样,除了更好。 gometalinter可能是最知名的,我建议你使用它。它有用地包括一个--vendor开关来忽略供应商目录:

$ go get -u github.com/alecthomas/gometalinter

$ gometalinter --vendor ./...
helpers.go:25:1:warning: realpath is unused (deadcode)
http.go:32:1:warning: _list is unused (deadcode)
[..trim..]

答案 2 :(得分:2)

答案 3 :(得分:1)

您可以将所有源代码放入子目录(例如task CopyCommits() <<{ def grgit = org.ajoberstar.grgit.Grgit.open(dir: project.parent.projectDir) grgit.checkout(branch: 'B') 'git cherry-pick 2133467'.execute().text.trim() internal)。或者,您可以这样做:

lib

答案 4 :(得分:1)

使用Go 1.10(2018年第一季度),kind of tipsOP mcandre提及的answer将更加强大:

go list ./... | grep -v vendor | xargs go vet -v

carpetsmokeranswer所示,依赖于(但未编译的)已销售软件包的软件包上的go vet将失败:

==> arp242.net/trackwall
http.go:71: database/sql.NullString composite literal uses unkeyed fields

请注意,因为go issue 16086已解决!

请参阅this thread

  

去兽医

     

go vet”命令最适用于正在分析的包的完整类型信息。从历史上看,在各种情况下都存在问题:使用cgo的软件包,使用vendoring的软件包以及没有安装最新依赖项的软件包都会导致vet无法运行完整类型信息。

     

不再。 go vet”命令现在传递给vet有关所有这些内容的完整信息,根据需要构建新的.a文件(CL 74355和CL 74750)。<登记/>   现在,“go vet”保证在分析包时具有最新的类型信息,这将提高其分析的准确性。
  让build cache分摊构建这些.a文件的成本是实现这一目标所需的最后一块。

     

只有“go vet”才有此保证。不要使用“go tool vet”,这对vet工作的用户来说非常有用(就像您通常不会运行“go tool compile”)。   以前您需要使用“go tool vet”,如果您想要控制兽医标志,但“go vet”现在接受“go tool vet”所做的所有标志。 (参见“go help vet”。)

答案 5 :(得分:0)

以跨平台的方式,我这样做philea -s "666 go vet %s" "666 go-fmt-fail %s"

产量,

$ ls -alh | grep ven
drwxr-xr-x  5 mh-cbon mh-cbon 4,0K 14 juin  20:43 vendor
$ philea -s "666 go vet %s" "666 go-fmt-fail %s"
go-fmt-fail ./local/local.go
 ✔ Success
go-fmt-fail ./dl/index.go
 ✔ Success
go vet ./local/local.go
 ✔ Success
go-fmt-fail ./gh/gh.go
 ✔ Success
go vet ./main.go
 ✔ Success
go vet ./gh/gh.go
 ✔ Success
go vet ./dl/index.go
 ✔ Success
go-fmt-fail ./main.go
 ✔ Success

答案 6 :(得分:0)

这是我使用的:

golint $(ls -d1 */ | sed s/\\//\\/.../g | grep -v -E "^vendor/" | tr "\n" " ")

答案 7 :(得分:0)

在 Go 1.9 中,为 ./... 引入了 change 以不再匹配 vendor 目录 (release notes) 中的包,这是一个流行的 {{3} }.

这意味着对于大多数目的,最简单的方法是现在

go test ./...  # ignores vendor
go fmt ./...   # ignores vendor
go list ./...  # ignores vendor
# etc.

然而,特别是对于 gofmt(如果 go fmt 没有我们需要的选项,我们可能想使用它),情况并不那么明确:

  • gofmt 将路径作为参数,而不是包
  • 如果给定目录,它会递归地工作,所以似乎只有 gofmt . 应该工作 - 但这并不忽略 vendor

所以要么我们必须回到

gofmt -l . | grep -v vendor

但是对于一个不是实际供应商目录的目录,这将匹配 vendor,并且在丢弃它之前检查 vendor 中的所有内容感觉很浪费。 >

我们也不能用

gofmt -l $(go list -f '{{.Dir}}' ./...)

因为./...与当前目录的包匹配,导致gofmt下降到包括vendor在内的所有地方。

使用模板直接迭代文件的更强大的解决方案

gofmt -l $(go list -f '{{range .GoFiles}} {{$.Dir}}/{{.}}{{end}}' ./...)

在具有长路径的大型目录树中可能会遇到命令行长度限制,因此这也不完美。我倾向于尽可能使用 go fmt ./...