Large repo switched to new go1.19 doc comments
Tags: godoc, gotestdeep, go
Published: 2022-08-07 19:08:33

go 1.19 introduces new doc comments formatting features, allowing to easily insert links and lists.

Details are described here → https://go.dev/doc/comment

## Links & lists

Links are probably the most interesting feature as they permit to enhance the documentation by providing users hints without inserting full URL as one needs before:

```go
// The allowed shortcut operators follow:
//   - [Empty]    → $^Empty
//   - [Ignore]   → $^Ignore
//   - [NaN]      → $^NaN
//   - [Nil]      → $^Nil
//   - [NotEmpty] → $^NotEmpty
//   - [NotNaN]   → $^NotNaN
//   - [NotNil]   → $^NotNil
//   - [NotZero]  → $^NotZero
//   - [Zero]     → $^Zero
//
// TypeBehind method returns the [reflect.Type] of the expectedJSON
// once JSON unmarshaled. So it can be bool, string, float64, []any,
// map[string]any or any in case expectedJSON is "null".
//
// See also [JSONPointer], [SubJSONOf] and [SuperJSONOf].
```
produces:

![Screenshot of result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cs6egeix6o7n3d080waw.png)

The listing feature is also used above. Before go 1.19, indented bullets were detected as a simple code block and were displayed with a monospaced font.

Links can reference local exported identifiers (like `JSONPointer` or `SubJSONOf`) as well as identifiers in other packages (like `reflect.Type`).

To produce links to other resources, one can now define links using the [Markdown shortcut reference link format](https://spec.commonmark.org/0.30/#shortcut-reference-link) (without the optional title text) as in:

```go
// MultipartBody is a body of a multipart/form-data HTTP request (by
// default, or any other multipart/… body, see MediaType field) as
// defined in [RFC 2046] to be used as a [io.Reader] body of
// [http.Request] and so compliant with [RFC 2388]. It implements
// [io.Reader] and can only be read once. See [PostMultipartFormData]
// and [TestAPI.PostMultipartFormData] for examples of use.
//
// [RFC 2046]: https://tools.ietf.org/html/rfc2046
// [RFC 2388]: https://tools.ietf.org/html/rfc2388
```
producing:

![Screenshot of result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sn75dtw270p7v42513aa.png)

Note that these shortcuts are scoped to the comment they are declared in.

## Full example

To see the result on a large repository, I adapted the comments of [go-testdeep](https://go-testdeep.zetta.rocks/) to fully take advantage of these new features.

You can see the result for each impacted package:
- https://pkg.go.dev/github.com/maxatome/go-testdeep/td
- https://pkg.go.dev/github.com/maxatome/go-testdeep/helpers/tdhttp
- https://pkg.go.dev/github.com/maxatome/go-testdeep/helpers/tdsuite
- https://pkg.go.dev/github.com/maxatome/go-testdeep/helpers/tdutil

## A few remarks

It seems that `pkg.go.dev` hasn't handled `[links]` in lists yet. I say "yet", because the last version of [godoc](https://pkg.go.dev/golang.org/x/tools/godoc) handles them properly. So I suppose it will be fixed soon.

Struct fields links work for standard packages, but not for local/current one. For example `[http.Cookie.Raw]` produces a link to the `Raw` field of `Cookie` in `net/http` package ([example](https://pkg.go.dev/net/http#Cookie.Raw)), but in go-testdeep [td](https://pkg.go.dev/github.com/maxatome/go-testdeep/td) package `[ContextConfig.RootName]` remains intact and so is not changed into a link, even when using the last version of `godoc`.

Links are not handled in `var` or `const` comments when a single keyword groups several declarations:
```go
// DefaultContextConfig is the default configuration used to render
// tests failures. If overridden, new settings will impact all Cmp*
// functions and [*T] methods (if not specifically configured.)
var DefaultContextConfig = ContextConfig{…}
```
is OK, but:
```go
var (
  // DefaultContextConfig is the default configuration used to render
  // tests failures. If overridden, new settings will impact all Cmp*
  // functions and [*T] methods (if not specifically configured.)
  DefaultContextConfig = ContextConfig{
)
```
does not work, `[*T]` remains intact in generated godoc. It is too bad.

## Some ideas

`[x]` could be a builtin pointing to `https://pkg.go.dev/builtin#x`, like [`error`](https://pkg.go.dev/builtin#error) for example, for all native types, as we see them in signatures.

It could be cool to have shortcut reference links global to the package, perhaps in the package doc itself. It would avoid to declare in each comment the same shortcut again and again.

It can be interesting that the shortcut reference links accept indirect URLs. For example, in [td](https://pkg.go.dev/github.com/maxatome/go-testdeep/td) I often talk about `Cmp*` functions. Each time, I would like to reference [`Cmp`](https://pkg.go.dev/github.com/maxatome/go-testdeep/td#Cmp) function (the first one of the `Cmp*` serie). To do it, I have to set the full URL in the shortcut:
```go
// [Cmp*]: https://pkg.go.dev/github.com/maxatome/go-testdeep/td#Cmp
```
while simply using:
```go
// [Cmp*]: Cmp
```
would avoid referencing `pkg.go.dev` as `[Cmp]` does elsewhere.

## Conclusion

The result of using these new features is pretty cool. Let's hope that package authors will enhance their docs to help their users to easily discover their APIs, in a more friendly way.