Why Golang packages have to be v0 or v1 and not v2020
Asked Answered
M

2

6

I read everywhere that packages have to have a tag of v0 or v1. Why can't a tag be v2020 or something other than v0 or v1. I have tried this personal and is get the following error with I use v2020.

Scotts-Mac-mini:seeding syacko$ go mod tidy
go: errors parsing go.mod:
/Users/syacko/workspace/sotesoft/src/utils/seeding/go.mod:10: require gitlab.com/soteapps/packages: version "v2020.2.0" invalid: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2020
Scotts-Mac-mini:seeding syacko$ 
Miliaria answered 1/6, 2020 at 20:54 Comment(4)
With help from Icza (see comments below) the I found the following:Miliaria
After re-reading github.com/golang/go/wiki/…, I see the issue is not with the v2020.y.z, it is with the directory structure not matching the version number. path abc/def/v2020 v2020.y.z should work. Thank you for the various links. A good working example is github.com/jackc/pgx/v4Miliaria
Don't use a version number 2020 for packages/version control, since it implies the existence of many earlier versions. Like it or not Go uses SemVer not CalVer. Of course you can use "2020" or whatever for your API/GUI version numbers.Ose
Thank you for the reply. That doesn't answer the question. Where I use 2020 or 2 or 20000. There is an error message about it having to be 0 or 1. I understand everything you are saying and maybe it was a bad example. The point is that there is a requirement that is not clearly communicated. That is the need for a /v directory for a non-v0 or v1 to work.Miliaria
T
8

It's a convention, a convenience for everyone. Go modules chose to use the widely accepted Semantic Versioning v2.

Go Modules Wiki:

What happens if I create a go.mod but do not apply semver tags to my repository?

semver is a foundation of the modules system. In order to provide the best experience for consumers, module authors are encouraged to apply semver VCS tags (e.g., v0.1.0 or v1.2.3-rc.1), but semver VCS tags are not strictly required:

  1. Modules are required to follow the semver specification in order for the go command to behave as documented. This includes following the semver specification regarding how and when breaking changes are allowed.

  2. Modules that do not have semver VCS tags are recorded by consumers using a semver version in the form of a pseudo-version. Typically this will be a v0 major version, unless the module author constructed a v2+ module following the "Major Subdirectory" approach.

  3. Therefore, modules that do not apply semver VCS tags and have not created a "Major Subdirectory" are effectively declaring themselves to be in the semver v0 major version series, and a module-based consumer will treat them as having a semver v0 major version.

An interesting and relevant blog post from Dave Cheney that predates Go modules: Gophers, please tag your releases

What do we want? Version management for Go packages! When do we want it? Yesterday!

[...] We want our Go build tool of choice to fetch the latest stable version when you start using the package in your project.[...]

But as it stands, today, in 2016, there is no way for a human, or a tool, to look at an arbitrary git (or mercurial, or bzr, etc) repository of Go code and ask questions like:

  • What versions of this project have been released?
  • What is the latest stable release of this software?
  • If I have version 1.2.3, is there a bugfix or security update that I should apply?

The reason for this is Go projects (repositories of Go packages) do not have versions, at least not in the way that our friends in other languages use that word. Go projects do not have versions because there is no formalised release process.

[...] I recommend that Go projects adopt SemVer 2.0.0. It’s a sound standard, it is well understood by many, not just Go programmers, and semantic versioning will let people write tools to build a dependency management ecosystem on top of a minimal release process.

Tied answered 1/6, 2020 at 20:56 Comment(10)
So rule 5 says, "Version 1.0.0 defines the public API. The way in which the version number is incremented after this release is dependent on this public API and how it changes." . It doesn't say that one 1 is usable. Also, rule 8 say"Major version X (X.y.z | X > 0) MUST be incremented if any backwards incompatible changes are introduced to the public API. It MAY also include minor and patch level changes. Patch and minor version MUST be reset to 0 when major version is incremented." which says, that values greater than 1 are allowed.Miliaria
Continued... So, how does "It's a convention, a convenience for everyone. Go modules chose to use the widely accepted Semantic Versioning v2." fit within the principles/guidance of Semantic Versioning. V2020.y.z is a valid Semantic Version.Miliaria
Using the semver convention allows the go tool to automatically detect latest version and tell if the current (local) version has updates that can be fetched without breaking the build, given the module owner follows the semver rules.Tied
If you use arbitrary version numbering, the go tool will not make much of it, and you teleport yourself and your dependency management back to the manual dependency management age.Tied
After rereading github.com/golang/go/wiki/…, I see the issue is not with the v2020.y.z, it is with the directory structure not matching the version number. path abc/def/v2020 v2020.y.z should work. Thank you for the various linksMiliaria
Here is an example of using a none v0.y.z or v1.y.z version that works with mod. github.com/jackc/pgx/v4 v4.6.0Miliaria
The version v4.6.0 is semver2 compatible.Tied
I don't see how v4.y.z is more or less semver2 than v2020.y.z. Is there a link to a section of the semver that calls out why this would be the case. Also, I don't see v2020.y.z being anymore arbittrary than v4.y.z. I'm trying to understand and I feel the answers provided are just sighting documents that are not supporting your statement. Again, just looking to understand. Everything you have posted, I have read many times. Thank you again for taking time to help out.Miliaria
v2020.0.0 is also semver2 compatible, just not v2020.Tied
I see you didn't know that v2020.y.z is Pseudocode. This is directly from the Semantic version link you provided. (semver.org). Either way, v2.y.z (v2.1.0 as examples) or v2020.y.z (v2020.4.2 as examples) will not work without the comment that I added above. So your help is great and didn't answer the question.Miliaria
M
5

After re-reading github.com/golang/go/wiki/…, I see the issue is not with the v2020.y.z, it is with the directory structure not matching the version number. path abc/def/v2020 v2020.y.z should work. Thank you for the various links. A good working example is github.com/jackc/pgx/v4

Here are the steps for the item you are going version: When you get to the point where you want to change the version to V2 or higher, these are the steps that need to be followed.

Sample go.mod file before version change
module gitlab.com/soteapps/packages

go 1.14

require (
    github.com/aws/aws-sdk-go v1.32.4
    github.com/jackc/pgconn v1.5.0
    github.com/jackc/pgx/v4 v4.6.0
    golang.org/x/net v0.0.0-20200602114024-627f9648deb9 // indirect
    golang.org/x/text v0.3.3 // indirect
)
Sample go.mod file after version change
module gitlab.com/soteapps/packages/v2100

go 1.14

require (
    github.com/aws/aws-sdk-go v1.32.4
    github.com/jackc/pgconn v1.5.0
    github.com/jackc/pgx/v4 v4.6.0
    golang.org/x/net v0.0.0-20200602114024-627f9648deb9 // indirect
    golang.org/x/text v0.3.3 // indirect
)
Sample Golang file import before change
package sDatabase

import (
    "context"
    "encoding/json"
    "fmt"
    "strings"

    "github.com/jackc/pgx/v4"
    "github.com/jackc/pgx/v4/pgxpool"
    "gitlab.com/soteapps/packages/sError"
    "gitlab.com/soteapps/packages/sLogger"
)

const (
Sample Golang file import after change
package sDatabase

import (
    "context"
    "encoding/json"
    "fmt"
    "strings"

    "github.com/jackc/pgx/v4"
    "github.com/jackc/pgx/v4/pgxpool"
    "gitlab.com/soteapps/packages/v2020/sError"
    "gitlab.com/soteapps/packages/v2020/sLogger"
)

const (
Item having a version v2+ number:
  1. Edit the go.mod module line to include the major version number at the end of the existing module path. So, the above module line module gitlab.com/soteapps/packages would change too module gitlab.com/soteapps/packages/v2100.
  2. All import references to gitlab.com/soteapps/packages in all the *.go files in the project must be updated to gitlab.com/soteapps/packages/{version}. In our example, this would the following, gitlab.com/soteapps/packages/v2100.
  3. Commit the change to source control.
    1. If you are using master, then commit to master.
      1. After you commit to master, create a branch from master with the version name. v2100 in the above example.
    2. If you are using branch, then commit to a branch with the version name. v2100 in the above example.
    3. The last step is to create a tag using semantic versioning format (vX.Y.Z) that point to the version branch. v2100.1.0 would be the tag for this example.
Miliaria answered 5/6, 2020 at 19:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.