Editing local copies of multiple unpublished Go Modules
Asked Answered
A

2

3

Is it just me or is working with unpublished go modules insanely painful?

https://go.dev/doc/modules/managing-dependencies#tmp_9

https://groups.google.com/g/golang-nuts/c/9MfGXLmRu8w/m/D2gm_viYBAAJ

From these two links, I figured out the replace directive. But now here's where I'm having a hard time.

Let's say I have packages example.com/p1, example.com/p2 and example.com/p3. p1 uses p2 and p2 uses p3.

I added the replace directive with:

  • the path to p3 in go.mod for p2
  • the path to p2 in go.mod for p1

But now it seems like I also need to add a replace directive in p1's go.mod for p3. With the number of unpublished packages I have, this is becoming quite painful.

Is this expected or am I doing something wrong?

Archduke answered 9/1, 2022 at 14:53 Comment(2)
If these are unpublished, why have them in multiple modules? It may be easier to just combine them together since there’s no published location to fetch them from. Otherwise you must use replace in the main package’s moduleFloweret
@Floweret combining them together is the approach I've gone with and it's okay for now. Thanks!Archduke
M
2

As others had said, it can be much easier to just place everything in a single unpublished module rather than breaking things apart into multiple modules. This makes it much easier to stay on the "happy path", and for your situation it sounds like that would work.

That said, if you upgrade to Go 1.18, the new workspace feature makes it much easier to work with editing multiple local modules simultaneously:

With multi-module workspaces, you can tell the Go command that you’re writing code in multiple modules at the same time and easily build and run code in those modules.

For example, from a parent directory that contains multiple module directories underneath (each with their own go.mod files), you can create a go.work file and recursively add the modules underneath by doing:

$ go work init
$ go work use -r .

If for example you have two modules and let's say module foo imports module bar, the resulting go.work file could then look like:

$ cat go.work
go 1.18

use (
        ./foo
        ./bar
)

If you then cd to the foo directory, commands like go build will use the local copies of both foo and bar.

The mechanics are that the go command checks to see if it is inside of a directory tree with a go.work file, and by default it consults any go.work file found to help resolve where a dependency is located.

For more information on workspaces, there is a good tutorial here: https://go.dev/doc/tutorial/workspaces

Alternatively, you can use the older technique of adding replace directives to your individual go.mod files, but that is not as nice as the new go.work feature.

Finally, even taking into account the new go.work capabilities, it is worth reiterating that your life is simpler if you are only working with one module at a time, so don't needlessly cut up what could be a single module.

Miscible answered 25/3, 2022 at 20:33 Comment(1)
HOLY BALLS thank youMeir
J
0

I cannot reply to a response (because not enough karma) but I tried the go work pathway and it did not... work

The problem is circular, in order to be able use go.work you are required to publish the repo to be in your go.mod, and your go.mod cannot fetch the unpublished repo.

So, I took the replace directive pathway, and it's fairly easy

module github.com/obfuscated/unpublished

go 1.18

replace github.com/obfuscated/unpublished => ./

Johnsson answered 8/10, 2022 at 22:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.