Author: Manlio Perillo manlio.perillo@gmail.com
Last updated: 26 Novemberr 2015
Discussion at https://golang.org/issue/XXXXX.
TODO
TODO
This proposal describes how to assign a version
to a package, and how to
require a specific version
of a package using a Go tool.
Version numbers follow the Semantic Versioning 2.0 standard (SemVer) standard.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
- repository: TODO
- revision: TODO
- tag: TODO
- branch: TODO
- version: TODO
- SemVer: for this specification purpose, a SemVer is defined by
MAJOR.MINOR.PATCH
.
Go packages live inside a source code repository
(like git
or mercurial
).
All packages inside a repository
share the same version
.
A version
is assigned by using the source control system native method to
create a tag for a revision
.
A tagged version
has a 'v'
character before the actual SemVer
. The 'v'
prefix is REQUIRED.
When the full SemVer
is used to tag a revision
, that revision
MUST be
considered immutable, that is, a package source code at the specified
revision
MUST never be changed by the package author (this is also specified
by SemVer
). The tag
, once created, SHOULD never be deleted.
A full SemVer
is assigned by using the source control system native method to
create an immutable tag (called tag
) for a revision
. As an example:
git tag -a v1.2.3
It is also possible to tag a revision
using a partial SemVer
. In this case
it is possible to add more revisions to the source code, as long as the
SemVer
specification is followed (TODO: this is probably confusing).
A partial SemVer
is assigned by using the source control system native method
to create a tag (called branch
) for a revision
. The branch
, once created,
SHOULD never be deleted.
In a partial SemVer
both PATCH
and MINOR
are optional. As an example:
git branch v1.2
git branch v1
A full SemVer
MUST not be used to create a branch
.
A partial SemVer
MUST not be used to create a tag
.
RATIONALE:
- Enabling support for creating partial
versions
using abranch
is a very useful (and required, by some people) feature, but it is also required in order to keep compatibility with many packages that follow the current advice, by the Go tools, to change theimport path
when a new incompatible version is released. An example of code hosting that follows this convention is gopkg.in(gopkg.in). The service maps packages to branches in the underlying source coderepository
, using thego get
protocol.
ISSUES:
- Should this specification recommend the use of signed
tags
, if available? How should signedtags
verified? Will this require a Go specific CA? A centralized authority (of any sort) is against Go tool principles, but without an authority signingtags
may be useless.
In this section go get
is used as the reference tool.
When using go get
, the version
is specified in the remote import path
by
appending the character @
followed by the SemVer
after the package
import path
. As an example:
go get golang.org/x/text@1.2.3
Note that no 'v'
character is prepended to the version
.
TODO:
should the syntax be golang.org/x/text.v1.2.3
, instead? This has
the advantage to be compatible with gopkg.in
.
NOTE:
the proposed change to how a remote import path
must be interpreted by
go get
does not break compatibility, since the new syntax is a valid
import path
as recognized by the current go get
. Using the alternate
syntax will make current tools able to handle some packages following this
specification. As an example:
go get gopkg.in/xmlpath.v2
NOTE:
to be precise, gopkg.in
is not strictly compatible with this
specification, since a version
is mapped to either a tag
or branch
,
while this specification forbids the creation of a tag
using a partial
SemVer
and the creation of a branch
using a full SemVer
.
When downloading a package from a specified remote import path
, the following
rules MUST be followed:
-
If the
version
is not specified, thengo get
will search for the latestrevision
in therepository
. Note the use ofrevision
instead ofversion
. This is the current behavior. -
If a partial
SemVer
is specified, thengo get
will first search for abranch
having the specifiedversion
. If thebranch
does not exists,go get
will search for the most recenttag
matching the partialSemVer
. It must report an error if no matchingtag
exists. -
If a full
SemVer
is specified, thengo get
will search for atag
having the specifiedversion
. It must report an error if thetag
does not exists. -
The special
latest
identifier is equivalent to specify, as theversion
, the most recentversion
in therepository
. Usinglatest
will allow users to only install released packages.
This specification is designed to be compatible with go get
. However go get
has a concept of version
that is not compatible with the one proposed
here. In the following text from go help get
:
If no such version exists it retrieves the most recent version of the
package.
version
should be replaced with revision
.
Another issue is how to support multiple, incompatible, versions
of the Go
compiler when a package version
is also specified in a remote import path
.
The proposed solution is to append the @go<ver>
string to the searched
repository
tag
or branch
. As an example:
go get golang.org/x/text@1.2.3
will first try the tag
v1.2.3@go1
, then the tag v1.2.3
. Note that the
'@'
character is not allowed in SemVer
, so it is safe to use.
-
go version
should gain the ability to report the version of an installed package, specified using animport path
(so,std
,all
and recursive packages SHOULD be supported) -
go api
should gain the ability to check API compatibility (and reporting a diff) between a currently installed package and a remoteversion
. The package is specified using animport path
(so,std
,all
and recursive packages SHOULD be supported) -
A new
go tool release
should be implemented. The tool will be used to automatically create a newversion
for the currentrevision
of the current (in the current directory) package.The syntax SHOULD be:
go tool release [
version
]version
MUST be a fullSemVer
.If
version
is omitted, the tool SHOULD create atag
using the following rules:-
If there is no previous
version
, it MUST report an error. -
If the previous
version
hasMAJOR
number equal to 0, it MUST NOT advance theMAJOR
number, under no circumstances. Instead it SHOULD increaseMINOR
number if the API is not compatible with the previous one, and it SHOULD increasePATCH
number if new compatible API is implemented. -
Otherwise, the new
version
MUST followSemVer
If
version
is specified, the tool SHOULD check that it followsSemVer
. -
TODO: go tool vendor
Thank you for suggesting this. I think you should follow the full proposal process to get an issue number and people can comment on your proposals.
I also have some questions
Where is this repository checked out inside
$GOPATH
?How do programs import this package, what is their
import
declaration ?How does go get deal with the transitive dependencies of
x/text
? Will it try to check out their v1.2.3 tag ?