What on earth is Go Mod?
Tunde Oladipupo
Posted on February 19, 2020
Go mod is the recommended way to manage packages and their dependencies in go. Go can look at your imported packages and add them to its go.mod for management. For example, in this project;
module knative.dev/client
require (
contrib.go.opencensus.io/exporter/ocagent v0.6.0 // indirect
contrib.go.opencensus.io/exporter/prometheus v0.1.0 // indirect
contrib.go.opencensus.io/exporter/stackdriver v0.12.9 // indirect
github.com/google/go-containerregistry v0.0.0-20200131185320-aec8da010de2 // indirect
...
github.com/openzipkin/zipkin-go v0.2.2 // indirect
github.com/pkg/errors v0.8.1
github.com/robfig/cron v1.2.0 // indirect
...
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413
gotest.tools v2.2.0+incompatible
...
sigs.k8s.io/yaml v1.1.0
)
// Temporary pinning certain libraries. Please check periodically, whether these are still needed
// ----------------------------------------------------------------------------------------------
// Fix for `[` in help messages and shell completion code
// See https://github.com/spf13/cobra/pull/899
replace github.com/spf13/cobra => github.com/chmouel/cobra v0.0.0-20191021105835-a78788917390
go 1.13
The go.mod has the required modules for this module as well as their specific version. Talking about version, you can see we have different version as well as comment. Lets take a look;
-
Semvars
github.com/pkg/errors v0.8.1
This package is required but version
v0.8.1
of it. If this module is updated in its remote git repo with the new version, go will not used it butv0.8.1
instead -
Pseudo-versions
knative.dev/eventing v0.12.1-0.20200206203632-b0a7d8a77cc7
This is the same as semvar but with weird version generated by go in form of
last_tag-date-commit_hash
. This is done when you import a package without specifying the version to use. Go simply update with the last tagged version(v0.12.1 in the case of knative.dev/eventing), then calculate the time of last commit as well as hash of last commit in the git repo to generate its version tag to give usv0.12.1-0.20200206203632-b0a7d8a77cc7
replace
So you have an external dependency in your project that you want to make some local changes to or replace temporarily with another source for testing or specific purpose. How do you do that? You can use replace
. This means instead of using the external dependency source, it will use the replacement instead.
replace github.com/spf13/cobra => github.com/chmouel/cobra v0.0.0-20191021105835-a78788917390
This will make go mod use github.com/chmouel/cobra
anywhere github.com/spf13/cobra
is used. You can do the same locally by pointing the replacement to local path.
incompatible
Let's talk incompatible. If a repo does not have go.mod
and it has semver that is >= 2
,it will tagged with the semver as well as incompatible to indicate this is not a go mod repo. For our case,
gotest.tools v2.2.0+incompatible
If you look at the tagged repo, you can see the repo is missing go.mod and its on >=2
tag.
go version directive
This simply answers the question of which golang version and features should I use? I will quote one of the authority on this for better explanation.
The basic guideline is fairly simple: a "go" directive 1.N means that the code in that module is permitted to use language features that existed in 1.N even if those features were removed in later releases of the language.
In other words, if the code compiles successfully at version 1.N, then it will continue to compile for all later versions of the language, even if it happens to use language features that were later removed.
To a first approximation, nobody should ever have to worry about the "go" directive. The only likely time you might need to set it manually is if you are copying some existing code to a new module, that code uses some obsolete language feature, and you don't have time to rewrite it. In that case you might want to set the "go" directive (using
go mod edit -go
) to the version used by the original module, thus permitting your new module to use the obsolete features. When writing new code you will presumably simply avoid the obsolete language features.
go sum
This go.sum
is way for go to keep cryptographic hash of the modules version in go.mod
. It keeps a cache copy of this hashes and verifies them during run. Make sure to check in the go.sum
file.
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
Posted on February 19, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 29, 2024