Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a common way to add metadata to a Go project?

Tags:

go

In Node.js, there is a package.json file which contains several metadata on a module, such as its name, its version, its author(s), …

How do you do this in Go?

E.g., I would like to store the authors of a Go module somewhere with the code. Is there a common way of how to do this?

like image 594
Golo Roden Avatar asked Nov 08 '15 17:11

Golo Roden


Video Answer


1 Answers

If a Go package has extensive documentation, by convention it should be placed in its own file, doc.go.

Quoting from blog post Godoc: documenting Go code:

That package uses another convention for packages that need large amounts of introductory documentation: the package comment is placed in its own file, doc.go, which contains only those comments and a package clause.

You may place any metadata in the package doc itself.

If you want these "metadata" to also be available from code, you may store them in constants, e.g.:

const (
    Author      = "Joe Big"
    Version     = "0.1.2.3"
    ReleaseDate = "2015-11-08"
)

Note that exported constants will also be included in the godoc, besides them being available from code too.

You may also comment the lines, the comments will also be included in the godoc. These comments can make it obvious what they are, for example:

const (
    Author      = "Joe Big"    // Package author: first name - last name
    Version     = "0.1.2.3"    // Package version: major.minor.maintenance.revision
    ReleaseDate = "2015-11-08" // Release date: year-month-day
)

Metadata of metadata

If you include a date or time related constant (like ReleaseDate in my example), it is often useful to also provide a layout that can be used by the time.Parse() function to convert your string date/time to a value of time.Time. For the above example, it could look like this:

const ReleaseDateLayout = "2006-01-02" // Release date layout (for time.Parse())

Using this layout, obtaining a time.Time:

releaseDate, err := time.Parse(ReleaseDateLayout, ReleaseDate)

Another option is to provide exported utility functions which process the metadata and provide other info about them or present them in another format. For example:

// GetReleaseDate returns the release date as a value of time.Time.
func GetReleaseDate() time.Time {
    t, err := time.Parse(ReleaseDateLayout, ReleaseDate)
    if err != nil {
        panic(err)
    }
    return t
}

And one for the Version:

// GetVersion returns the parts of the Version as a slice:
//     {major, minor, maintenance, revision}
func GetVersion() []int {
    vs := []int{}
    for _, s := range strings.Split(Version, ".") {
        if v, err := strconv.Atoi(s); err != nil {
            panic(err)
        } else {
            vs = append(vs, v)
        }
    }
    return vs
}

Private metadata

These constants are exported, so they can be reached from other packages that import and use this. If you don't want that, just start them with lower case letter and so they will not be reachable from the "outside" (they will not be exported), e.g.:

// This constant will not be in godoc and is unreachable from other packages
const codeReviewer = "Jane Small" // Last code reviewer: first name - last name
like image 184
icza Avatar answered Oct 03 '22 06:10

icza