coming from a Node
environment I used to install a specific version of a vendor lib into the project folder (node_modules
) by telling npm
to install that version of that lib from the package.json
or even directly from the console, like so:
$ npm install express@4.0.0
Then I used to import that version of that package in my project just with:
var express = require('express');
Now, I want to do the same thing with go
. How can I do that?
Is it possible to install a specific version of a package? If so, using a centralized $GOPATH
, how can I import one version instead of another?
I would do something like this:
$ go get github.com/wilk/uuid@0.0.1
$ go get github.com/wilk/uuid@0.0.2
But then, how can I make a difference during the import?
The approach I've found workable is git's submodule system. Using that you can submodule in a given version of the code and upgrading/downgrading is explicit and recorded - never haphazard.
The folder structure I've taken with this is:
go get is the Go package manager. It works in a completely decentralized way and how package discovery still possible without a central package hosting repository.
Besides locating and downloading packages, the other big role of a package manager is handling multiple versions of the same package. Go takes the most minimal and pragmatic approach of any package manager. There is no such thing as multiple versions of a Go package.
go get always pulls from the HEAD of the default branch in the repository. Always. This has two important implications:
As a package author, you must adhere to the stable HEAD philosophy. Your default branch must always be the stable, released version of your package. You must do work in feature branches and only merge when ready to release.
New major versions of your package must have their own repository. Put simply, each major version of your package (following semantic versioning) would have its own repository and thus its own import path.
e.g. github.com/jpoehls/gophermail-v1 and github.com/jpoehls/gophermail-v2.
As someone building an application in Go, the above philosophy really doesn't have a downside. Every import path is a stable API. There are no version numbers to worry about. Awesome!
For more details : http://zduck.com/2014/go-and-package-versioning/
Really surprised nobody has mentioned gopkg.in.
gopkg.in is a service that provides a wrapper (redirect) that lets you express versions as repo urls, without actually creating repos. eg gopkg.in/yaml.v1 vs gopkg.in/yaml.v2, even though they both live at https://github.com/go-yaml/yaml
This isn't perfect if the author is not following proper versioning practices (by incrementing the version number when breaking backwards compatibility), but it does work with branches and tags.
You can set version by offical dep
Update 18-11-23: From Go 1.11 mod is official experiment. Please see @krish answer.
You can use
git checkout
to get an specific version and build your program using this version.Example:
dep
is the official experiment for dependency management for Go language. It requires Go 1.8 or newer to compile.To start managing dependencies using
dep
, run the following command from your project's root directory:After execution two files will be generated:
Gopkg.toml
("manifest"),Gopkg.lock
and necessary packages will be downloaded intovendor
directory.Let's assume that you have the project which uses
github.com/gorilla/websocket
package.dep
will generate following files:Gopkg.toml
Gopkg.lock
There are commands which help you to update/delete/etc packages, please find more info on official github repo of
dep
(dependency management tool for Go).