Go's No-Nonsense Self Documenting

February 8, 2022

Godoc is Awesome

Let’s start by saying in most cases documenting code is not the easiest thing to do. Go has solved this. It’s simple and has no-nonsense self documentation out of the box. Now lets learn how to write good Go code that will generate good docs.

Package Overview & License

// Package amazing does some amazing things!
// Copyright Nathan Rockhold.
// All Rights Reserved
// Here is where we explain how amazing this package is.
// Some additional info about this package.
package amazing

Package level documentation must be in a continuous comment immediately before the package statement and start with the word Package. No empty lines allowed. This is where you add all comments that should be included in the general package documentation.

The first sentence is automatically extracted as the brief overview for the package when listing all the packages.

Paragraphs

To make wrapping long continuing lines easier godoc will assume that all subsequent lines are part of the same paragraph. However, you can explicitly separate paragraphs with a blank comment line.

// Here is where we explain how amazing this package is.
//
// Some other info about this package.
package doc

Constants

If your pakcage has exported constants they need to be documented. Lets document some constants:

// Host is the hostname of my website.
const Host = "nathanrockhold.com"
// Port is the the listen port for my website.
const Port = 80

Here is how to document a single const declaration:

// This will be under the constants in the generated godoc.
const (
    // Foo is a very important constant.
    Foo = 1
    // Bar is even more important.
    Bar = 2
)

Methods/Functions

To document methods and functions add the comment immediately before it’s definition:

// Abs returns the absolute value of the passed float64.
func Abs(x float64) float64 {
}
// Sin returns the Sine value of the passed flaot64.
func Sin(x float64) float64 {
}

// Run starts the service.
func (s *Service) Run() error {
}

// do is also important to document however only exported methods are in the generated documentation.
func (s *Service) do() {
}

Headings & Sections

Godoc recognises a line that starts with a capital letter and does not end in a full period as a heading. This is why comments should be complete sentences ending with a period.

// Here is where we explain how amazing this package is.
//
// See Also
//
// Some other amazing stuff.
package amazing

Code Blocks

You can create code blocks in the documentation that allow you to add example code. They are identified by a line that starts with at least one extra space after the single space after the comment begins //:

// This is how to write Hello World:
//  fmt.Printf("Hello, World")
// Or:
//  name := "World"
//  fmt.Printf("Hello, " + name)

Godoc automagically recognizes url and renders links in the documentation.

Examples

Godoc allows you to create examples at the package level:

// Here is where we explain how amazing this package is.
package awesome

// Example is a example of how to use fmt.Printf.
func Example() {
    fmt.Printf("Howdy y'all!")
}

You can create examples for using types by adding a Example function or method:

package awesome

// AwesomeFloat is a a float64
type Awesome float64

// Use Awesome like a float64.
func ExampleAwesome() {
    var a Awesome = 3.14159265359
}

Install Godoc

$ go install golang.org/x/tools/...@latest

Handy zsh alias

This gdoc alias allows you to run the local godoc server and browse your current packages documentation. This alias can be added to your ~/.zshrc:

For Linux:

alias www='python2 -m SimpleHTTPServer'

alias gdoc=_godoc
function _godoc(){
    GOMOD=$( go env | grep GOMOD= | cut -d'"' -f2)
    PKG=$(sed 1q ${GOMOD} | awk '{print $2}')
    echo "===> Generating godoc for $PKG"
    godoc -http=:6060  > /dev/null 2>&1 &
    GODOC_PID=$!
    echo ""
    URL="http://localhost:6060/pkg/$PKG"
    echo "===> Opening go doc: $URL"
    echo ""
    xdg-open $URL
    echo "===> Type Q to kill godoc"
    while read -k1 key
    do
      if [ "$key" = "Q" ];
      then
      kill -9 $GODOC_PID
      break
      fi
    done
}

For MacOS:

alias www='python2 -m SimpleHTTPServer'

alias gdoc=_godoc
function _godoc(){
    GOMOD=$( go env | grep GOMOD= | cut -d'"' -f2)
    PKG=$(sed 1q ${GOMOD} | awk '{print $2}')
    echo "===> Generating godoc for $PKG"
    godoc -http=:6060  > /dev/null 2>&1 &
    GODOC_PID=$!
    echo ""
    URL="http://localhost:6060/pkg/$PKG"
    echo "===> Opening go doc: $URL"
    echo ""
    open $URL
    echo "===> Type Q to kill godoc"
    while read -k1 key
    do
      if [ "$key" = "Q" ];
      then
      kill -9 $GODOC_PID
      break
      fi
    done
}

I Repeat Godoc Is Awesome

I hope you have learned that go allows for easy documenting of your code out of the box.


comments powered by Disqus

Ⓒ 2020 Nathan Rockhold. All rights reserved.