gobin icon indicating copy to clipboard operation
gobin copied to clipboard

provide a way to set module-specific PATH

Open powerman opened this issue 3 years ago • 1 comments

There are a couple usability issues related to absence of gobin-installed binaries in PATH. First one is obvious: gobin -m -run github.com/golangci/golangci-lint/cmd/golangci-lint is a way harder to type than just golangci-lint. Second is a bit more subtle: protoc looks for installed plugins in PATH, so to let it find gobin-installed plugins we had to replace //go:generate protoc … with something like //go:generate sh -c "protoc $(gobin -m -p $(go list -tags=tools -f '{{range .Imports}}{{println .}}{{end}}' ../../third_party | grep protoc-gen) | sed -e s,^,--plugin=,) … (where ../../third-party is a directory containing tools.go).

Maybe it's worth to provide a way to run any command with PATH prepended with all directories with gobin-installed binaries in module-mode, e.g.:

# same as `export PATH=.gobincache/github.com/golangci/golangci-lint/@v/v1.31.0/cmd/golangci-lint:$PATH; golangci-lint`
$ gobin -m golangci-lint

# same as `export PATH=.gobincache/github.com/golangci/golangci-lint/@v/v1.31.0/cmd/golangci-lint:…other:installed:tools:here:…:$PATH; protoc …`
$ gobin -m protoc …

Of course we can set PATH right now using command shown below, but there are a couple issues with it:

  • it's slow (probably related to #97) - running /bin/true this way took 3.531 real 12.202 user 3.191 sys 43MB RAM
  • it has to be re-run when tools/versions change
  • there is no easy way to remove these dirs from PATH when switching to another project/directory
$ PATH=$(echo $(dirname $(gobin -m -p $(go list -tags=tools -f '{{range .Imports}}{{println .}}{{end}}' ./third_party))) | sed 's, ,:,g'):$PATH zsh

Here is tools.go used in examples above:

// +build tools

package third_party

import (
	_ "github.com/cheekybits/genny"
	_ "github.com/go-swagger/go-swagger/cmd/swagger"
	_ "github.com/golang/mock/mockgen"
	_ "github.com/golangci/golangci-lint/cmd/golangci-lint"
	_ "github.com/googleapis/api-linter/cmd/api-linter"
	_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway"
	_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2"
	_ "github.com/nilslice/protolock/cmd/protolock"
	_ "github.com/yoheimuta/protolint/cmd/protoc-gen-protolint"
	_ "github.com/yoheimuta/protolint/cmd/protolint"
	_ "google.golang.org/grpc/cmd/protoc-gen-go-grpc"
	_ "google.golang.org/protobuf/cmd/protoc-gen-go"
	_ "gotest.tools/gotestsum"
)

powerman avatar Oct 26 '20 07:10 powerman

First one is obvious: gobin -m -run github.com/golangci/golangci-lint/cmd/golangci-lint is a way harder to type than just golangci-lint.

Agreed. The generally accepted solution for humans is to use aliases. For scripts/go:generate directives, it doesn't really matter.

Second is a bit more subtle: protoc looks for installed plugins in PATH,

I think this is just a case of a PATH based tool running up against a non-PATH based tool. In this case I would probably drop down to using a script.

myitcv avatar Oct 27 '20 06:10 myitcv