bud: Doesn't support GOPATH with multiple directories

I’ve just been attempting to try out bud, but ran into issues before I could get going. Granted, I’ve not got far into learning Go, I thought bud would help to give me a gentler start to creating a web app, so I may be missing something that is considered “basic Go knowledge”.

I’ve followed your example to get going:

and I get presented with the following:

~/code/go/src/github.com/techwilk/test-bud$ bud run
| Listening on http://127.0.0.1:3000
| conjure: generate "bud/.cli/program/program.go" > program: unable to wire > di: unable to find definition for param "github.com/livebud/bud/runtime/bud".*Flag within "github.com/techwilk/test-bud/bud/.cli/command".*CLI > stat /home/user/go:/home/user/code/go/pkg/mod/github.com/livebud/bud@v0.1.4: no such file or directory

I’ve previously had Go 1.17, but upgraded to 1.18.2 which didn’t change anything.

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Comments: 18 (13 by maintainers)

Most upvoted comments

Awesome, I also got some feedback from the Go community on Twitter:

I used to do this before Modules: “go get” would clone into my first GOPATH, and I would use the second to manually manage the projects I maintained.

IMHO there’s no point in a multi-directory GOPATH with Modules nowadays.

This makes total sense to me pre-modules, where you want to keep your maintained projects in a clean directory away from your downloaded modules. Nowadays, go modules are tucked away in $GOPATH/pkg/mod anyways, so not a huge reason to keep this. We certainly still want to support this behavior in Bud though.

@syke99 what are you encountering that leads you to believe there’s different solutions for 1.17 and 1.18?

At first glance, I was thinking this would be a fairly simple solution, split on :, and choose the first path to find the runtime. Alternatively, look in each path one by one until you find it or fail trying. This is probably closer to the correct behavior of $GOPATH if it resembles $PATH.

This makes total sense to me pre-modules, where you want to keep your maintained projects in a clean directory away from your downloaded modules. Nowadays, go modules are tucked away in $GOPATH/pkg/mod anyways, so not a huge reason to keep this. We certainly still want to support this behavior in Bud though.

Right, that makes a lot of sense. I must have been following a pre-modules guide. (bonus, I’ve now learned about modules!)

At first glance, I was thinking this would be a fairly simple solution, split on :, and choose the first path to find the runtime. Alternatively, look in each path one by one until you find it or fail trying. This is probably closer to the correct behavior of $GOPATH if it resembles $PATH.

According to one of the answers on @syke99’s SO link it’s worth noting that the delimiter in $GOPATH is OS-specific, so just splitting on : sounds like it wouldn’t be suitable for windows

$ go help gopath 
The Go path is used to resolve import statements.
It is implemented by and documented in the go/build package.

The GOPATH environment variable lists places to look for Go code.
On Unix, the value is a colon-separated string.
On Windows, the value is a semicolon-separated string.
On Plan 9, the value is a list.
...

Ope, yep. I must’ve missed your comment about os.PathListSeparator and didn’t know it was part of the std lib. I definitely agree to use it!!

so just splitting on : sounds like it wouldn’t be suitable for windows

Thanks for the heads up! I always wondered what os.PathListSeparator was good for 😄

1.17: gopath := os.GetEnv(“GOPATH”)

I’m pretty sure build.Default.GOPATH is available pre 1.18, since I’ve been using it since at least 2017: https://github.com/matthewmueller/joy/blob/e60ec6cf98bbbf7935742e6882fa3d33cadc6a78/internal/mains/mains.go#L32

I’d suggest we use that unless there’s good reason not to and then:

At first glance, I was thinking this would be a fairly simple solution, split on :, and choose the first path to find the runtime. Alternatively, look in each path one by one until you find it or fail trying. This is probably closer to the correct behavior of $GOPATH if it resembles $PATH.

It’s a bit old, but here is a a SO post that has some good links about multiple GOPATHs and why you’d use them.

I’m also really interested in this issue, so I’m currently researching solutions

Yes as far as I know that’s correct. There’s a bunch of stuff in there

$ ls -l /home/user/go/pkg/mod/ | wc -l
16

Thanks! GOPATH=/home/user/go bud run works great!

I don’t remember which guide off the top of my head. I’ll try and dig it out for you. It’s worth noting that I certainly don’t know enough at this point to be able to differentiate between if is in fact a good practice, or, like anything on the web, just a random opinionated person’s preference!

Woah, I had no idea this was possible! I guess it makes sense, $GOPATH being just like $PATH. I guess Go will install all your modules in the first path (e.g. /home/user/go/pkg/mod)? Do you have any packages in /home/user/code/go/pkg/mod?

I’m pretty sure this is the problem! I’ll try and come up with a solution.

In the meantime, does the following work for you?

GOPATH=/home/user/go bud run

One more thing, you do remember which getting started guide you used that recommended this? I’d like to learn more.