Closed unmultimedio closed 4 hours ago
Update: I managed to pass both modules to doc2go
and generate docs correctly using a Go workspace:
go 1.22.2
use (
./module1
./module2
)
And now the command renders all docs for both modules:
$ doc2go -debug ./module1/... ./module2/...
35.061959ms for GOROOT= GOPATH= GO111MODULE=off GOPROXY= PWD=[redacted] go list -e -f {{context.ReleaseTags}} -- unsafe
68.102625ms for GOROOT= GOPATH= GO111MODULE= GOPROXY= PWD=[redacted] go list -tags -e -json=Name,ImportPath,Error,Dir,GoFiles,IgnoredGoFiles,IgnoredOtherFiles,CFiles,CgoFiles,CXXFiles,MFiles,HFiles,FFiles,SFiles,SwigFiles,SwigCXXFiles,SysoFiles,DepOnly,Imports,ImportMap -compiled=false -test=false -export=false -deps=true -find=false -pgo=off -tags -- ./module1/... ./module2/...
Rendering package ...
Rendering directory ...
But now the types are not linked correctly, e.g.: if I have
# in module1
package pkga
import pkgb "module2/some/pkgb"
type SomeType struct {
SomeField pkgb.OtherType
}
It renders pkga.SomeType.SomeField
linking to public docs instead of the locally available, just generated one:
- https://pkg.go.dev/module2/pkgB#OtherType // I get
+ ./module2/pkgB#OtherType // I want
Is there a way I can tell doc2go
I want the types that are available in other modules in the same generation to be linked locally, something like the Go replace
directive?
Hello!
I was just about to respond with the go.work trick:
Since doc2go depends on go/packages for package discovery, the patterns you give it must be go list
-able. So if go list ./module1/... ./module2/...
wouldn't work, doc2go's version won't work either.
I have a system where I needed this functionality and I've used:
go work init
go work use ./module1 ./module2
doc2go ./module1/... ./module2/...
(I suspect go work use -r .
would also work but an explicit list is needed for the doc2go invocation since go list
wouldn'5 do anything there.)
But now the types are not linked correctly, e.g.: if I have
Huh, that doesn't sound right. Cross-module links work correctly when I'm doing the same. Let me see if I can repro locally.
Yeah, confirmed. Given:
-- bar/bar.go --
package bar
import "foo"
func DoThings(foo.Foo) {}
-- bar/go.mod --
module bar
go 1.23.2
-- foo/foo.go --
package foo
type Foo struct{}
-- foo/go.mod --
module foo
go 1.23.2
-- go.work --
go 1.23.2
use (
./bar
./foo
)
I ran:
❯ doc2go foo/... bar/...
The link to foo.Foo
in bar is:
<a href="../foo#Foo">
@unmultimedio I see you're doing: doc2go ./module1/... ./module2/...
Try the import path for the modules instead of relative directory paths?
e.g. doc2go example.com/module1/... example.com/module2/...
If that works, my guess is that the relative import path handling logic doesn't necessarily handle workspaces correctly.
I just noticed this question:
Is there a way I can tell doc2go I want the types that are available in other modules in the same generation to be linked locally, something like the Go replace directive?
First: When operating correctly, all code that is part of the same code generation request will be interlinked locally automatically. So the above should just work.
However, if you do end up in a situation where you want control over these links, you can use the -pkg-doc
flag. Usage is documented here: https://abhinav.github.io/doc2go/docs/usage/links/.
Thanks for your fast response! Here's a repro:
-- go.work --
go 1.22.2
use (
./mod1
./mod2
)
-- mod1/go.mod --
module github.com/unmultimedio/mod1
go 1.22.2
-- mod1/pkga/a.go --
package pkga
type TypeA struct {
Field1 int
Field2 string
}
-- mod2/go.mod --
module github.com/unmultimedio/mod2
go 1.22.2
require (
github.com/unmultimedio/mod1 v1.2.3
google.golang.org/protobuf v1.34.2
)
require github.com/google/go-cmp v0.5.9 // indirect
-- mod2/pkgb/b.go --
package pkgb
import (
"github.com/unmultimedio/mod1"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
)
type TypeB struct {
FieldA mod1.TypeA
FieldB int
FieldExternal protoreflect.Message
}
Notes:
github.com/unmultimedio/(mod1|mod2)
exist, that's just dummy names. In my real example those modules exist in a remote go proxy, but it's private.mod2/go.mod
, the require github.com/unmultimedio/mod1 v1.2.3
is dummy, that version does not exist.FieldExternal protoreflect.Message
replace github.com/unmultimedio/mod1 v1.2.3 => ../mod1
, same resultNow, when I do:
$ doc2go ./mod1/... ./mod2/...
The generated docs in http://127.0.0.1:8080/github.com/unmultimedio/mod2/pkgb/#TypeB
link:
pkg.go.dev/...
link).Now, I assume the issue vs your example has to do with the fact that I have an actual import in my mod2/go.mod
, and my import uses the complete module name import "github.com/unmultimedio/mod1"
, and not a "local" import package as your example does: import "foo"
.
@unmultimedio I see you're doing:
doc2go ./module1/... ./module2/...
Try the import path for the modules instead of relative directory paths? e.g.doc2go example.com/module1/... example.com/module2/...
If that works, my guess is that the relative import path handling logic doesn't necessarily handle workspaces correctly.
Tried that too, same result 😞
Oh, I see the problem.
There's no such thing as mod1.TypeA.
The import path in pkgb/b.go is: github.com/unmultimedio/mod1
, but TypeA
is at github.com/unmultimedio/mod1/pkga
.
It works once I fix the import path:
import (
- "github.com/unmultimedio/mod1"
+ mod1 "github.com/unmultimedio/mod1/pkga"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
)
❯ rg -o '<a href="[^"]+?TypeA">' _site/github.com/unmultimedio/mod2
_site/github.com/unmultimedio/mod2/pkgb/index.html
28:<a href="../../mod1/pkga#TypeA">
I just realized it's a nit from my side, I manually crafted this example, so I was missing the pkg name in the import:
import (
- "github.com/unmultimedio/mod1"
+ "github.com/unmultimedio/mod1/pkga"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
)
type TypeB struct {
- FieldA mod1.TypeA
+ FieldA pkga.TypeA
FieldB int
FieldExternal protoreflect.Message
}
Just see that you found the same issue.
Thank you so much for all your help, I can work with this now. Btw, there's no need for a replace
directive, neither in go.mod
in any module, or in the go.work
file.
Have a nice weekend!
Hello, and thank you for this documentation project! I'm reading through the docs https://abhinav.github.io/doc2go/docs/usage/#specifying-the-input and it says we can send multiple inputs to generate a combined documentation for all those targets.
Assume I have a directory such as:
Where
module1
depends onmodule2
(via arequire
in itsgo.mod
file).When I try to run
doc2go
I get:And it doesn't render anything. It's different if I go on each directory and generate separatedly:
Am I missing something from the docs? Since
module1
depends onmodule2
, I'd like types to be correctly linked in the same docs, so when I navigate onmodule1.SomeTypeA
that contains a field of typemodule2.SomeOtherTypeB
, it takes me to those docs frommodule2
.