golang/go

x/vgo: share local code inside custom $GOPATH

gobwas opened this issue · 3 comments

Hi!

I want to use $GOPATH as a root of git monorepo with several projects sharing some common library:

$ tree
├── Makefile
└── src
       ├── common
       ├── serviceA
       │   └── go.mod
       ├── serviceB 
       │   └── go.mod
       └── v

ServiceA and ServiceB are import some local common/stuff package inside their *.go files. They are also import, say, github.com/some/package with different versions (which are listed in their go.mod files).

How could I use vgo to build serviceA and serviceB separately, with same local code from src/common?

Im trying to compile with script like this:

$ (
  export GOPATH=$(pwd);
  cd src/serviceA;
  vgo build -o ../bin/serviceA;
)

Without any actions I get this error:

vgo: import "serviceA" ->
        import "common/stuff" [/usr/local/go/src/common/stuff]: open /usr/local/go/src/common/stuff: no such file or directory

If I change common to something like common.org:

vgo: import "serviceA" ->
        import "common.org": Get https://common.org?go-get=1: dial tcp: lookup common.org: no such host

Also, If I put something like this into serviceA/go.mod:

replace (
    "common.org" v1.0.0 => "../common"
)

The result is:

vgo: errors parsing go.mod:
<path to src>/src/serviceA/go.mod:6: invalid module version v1.0.0: Get https://common.org?go-get=1: dial tcp: lookup common.org: no such host

Am I doing something wrong, or is this know limitation, or any other suggestion?
Thanks.

Currently I've found the solution:

Inside the serviceA/go.mod:

module serviceA

replace (
    common v0.0.0 => ../common
)

require (
    common v0.0.0
)

Also, seems like common would not work if it will not look like url, so it must be common.org or something like this (in other way vgo will check $GOROOT dir for such package).

Any way, what is the convenient way to store the v folder in the project repository?

rsc commented

Sorry for missing this when it came in. The top-level domain problem was real and I believe was fixed. It sounds like you got everything working once you added the require statement. I filed #26241 to try to make that experience better.

Any way, what is the convenient way to store the v folder in the project repository?

I'm not sure what you mean by "the v folder". I see it in the tree output, but I don't know what is in it. If it's like common, then the way is to give it an import prefix.

I want to use $GOPATH as a root of git monorepo with several projects sharing some common library:

I think this is the mismatch. Typically instead of making the monorepo hold all of $GOPATH, you should make the root correspond to some directory like "$GOPATH/src/you.com/myrepo". Then "common" would be at the top level of the repo but imported as "you.com/myrepo/common", and similarly the go.mod would say "module you.com/myrepo/common". And then v would be the same: "module you.com/myrepo/v".

Thank you for reply! Will try to use your advice =)