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;
This package is required but version
v0.8.1of it. If this module is updated in its remote git repo with the new version, go will not used it but
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 us
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/spf13/cobra is used. You can do the same locally by pointing the replacement to local path.
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,
If you look at the tagged repo, you can see the repo is missing go.mod and its on
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 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
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=