<commit_before># Proposal: Versioned Go Modules

Author: <NAME>\
Last Updated: March 20, 2018\
Discussion: https://golang.org/issue/24301

## Abstract

We propose to add awareness of package versions to the Go toolchain, especially the `go` command.

## Background

The first half of the blog post [Go += Package Versioning](https://research.swtch.com/vgo-intro) presents detailed background for this change.
In short, it is long past time to add versions to the working vocabulary of both Go developers and our tools,
and this proposal describes a way to do that.

[Semantic versioning](https://semver.org) is the name given to an established convention for assigning version numbers
to projects. 
In its simplest form, a version number is MAJOR.MINOR.PATCH, where MAJOR, MINOR, and PATCH
are decimal numbers. 
The syntax used in this proposal follows the widespread convention of 
adding a “v” prefix: vMAJOR.MINOR.PATCH.
Incrementing MAJOR indicates an expected breaking change.
Otherwise, a later version is expected to be backwards compatible
with earlier versions within the same MAJOR version sequence.
Incrementing MINOR indicates a significant change or new features.
Incrementing PATCH is meant to be reserved for very small, very safe changes,
such as small bug fixes or critical security patches.

The sequence of [vgo-related blog posts](https://research.swtch.com/vgo) presents more detail
about the proposal.

## Proposal

I propose to add versioning to Go using the following approach.

1. Introduce the concept of a _Go module_, which is a group of
   packages that share a common prefix, the _module path_, and are versioned together as a single unit.
   Most projects will adopt a workflow in which a version-control repository
   corresponds exactly to a single module.
   Larger projects may wish to adopt a workflow in which a
   version-control repository can hold multiple modules.
   Both workflows will be supported.

2. Assign version numbers to modules by tagging specific commits
   with [semantic versions](https://semver.org) such as `v1.2.0`.
   (See
   the [Defining Go Modules](https://research.swtch.com/vgo-modules) post
   for details, including how to tag multi-module repositories.)

3. Adopt [semantic import versioning](https://research.swtch.com/vgo-import),
   in which each major version has a distinct import path.
   Specifically, an import path contains a module path, a version number,
   and the the path to a specific package inside the module.
   If the major version is v0 or v1, then the version number element
   must be omitted; otherwise it must be included.
   
   <p style="text-align:center">
   <img width=343 height=167 src="24301/impver.png" srcset="24301/impver.png 1x, 24301/impver@1.5x.png 1.5x, 24301/impver@2x.png 2x, 24301/impver@3x.png 3x, 24301/impver@4x.png 4x">
   </p>
   
   The packages imported as `my/thing/sub/pkg`, `my/thing/v2/sub/pkg`, and `my/thing/v3/sub/pkg`
   come from major versions v1, v2, and v3 of the module `my/thing`,
   but the build treats them simply as three different packages.
   A program that imports all three will have all three linked into the final binary,
   just as if they were `my/red/pkg`, `my/green/pkg`, and `my/blue/pkg`
   or any other set of three different import paths.
   
   Note that only the major version appears in the import path: `my/thing/v1.2/sub/pkg` is not allowed.
   
   
4. Explicitly adopt the “import compatibility rule”:

   > _If an old package and a new package have the same import path,_\
   > _the new package must be backwards compatible with the old package._
   
   The Go project has encouraged this convention from the start
   of the project, but this proposal gives it more teeth:<commit_msg>design: fix broken link in vgo proposal<commit_after># Proposal: Versioned Go Modules

Author: <NAME>ox\
Last Updated: March 20, 2018\
Discussion: https://golang.org/issue/24301

## Abstract

We propose to add awareness of package versions to the Go toolchain, especially the `go` command.

## Background

The first half of the blog post [Go += Package Versioning](https://research.swtch.com/vgo-intro) presents detailed background for this change.
In short, it is long past time to add versions to the working vocabulary of both Go developers and our tools,
and this proposal describes a way to do that.

[Semantic versioning](https://semver.org) is the name given to an established convention for assigning version numbers
to projects. 
In its simplest form, a version number is MAJOR.MINOR.PATCH, where MAJOR, MINOR, and PATCH
are decimal numbers. 
The syntax used in this proposal follows the widespread convention of 
adding a “v” prefix: vMAJOR.MINOR.PATCH.
Incrementing MAJOR indicates an expected breaking change.
Otherwise, a later version is expected to be backwards compatible
with earlier versions within the same MAJOR version sequence.
Incrementing MINOR indicates a significant change or new features.
Incrementing PATCH is meant to be reserved for very small, very safe changes,
such as small bug fixes or critical security patches.

The sequence of [vgo-related blog posts](https://research.swtch.com/vgo) presents more detail
about the proposal.

## Proposal

I propose to add versioning to Go using the following approach.

1. Introduce the concept of a _Go module_, which is a group of
   packages that share a common prefix, the _module path_, and are versioned together as a single unit.
   Most projects will adopt a workflow in which a version-control repository
   corresponds exactly to a single module.
   Larger projects may wish to adopt a workflow in which a
   version-control repository can hold multiple modules.
   Both workflows will be supported.

2. Assign version numbers to modules by tagging specific commits
   with [semantic versions](https://semver.org) such as `v1.2.0`.
   (See
   the [Defining Go Modules](https://research.swtch.com/vgo-module) post
   for details, including how to tag multi-module repositories.)

3. Adopt [semantic import versioning](https://research.swtch.com/vgo-import),
   in which each major version has a distinct import path.
   Specifically, an import path contains a module path, a version number,
   and the the path to a specific package inside the module.
   If the major version is v0 or v1, then the version number element
   must be omitted; otherwise it must be included.
   
   <p style="text-align:center">
   <img width=343 height=167 src="24301/impver.png" srcset="24301/impver.png 1x, 24301/impver@1.5x.png 1.5x, 24301/impver@2x.png 2x, 24301/impver@3x.png 3x, 24301/impver@4x.png 4x">
   </p>
   
   The packages imported as `my/thing/sub/pkg`, `my/thing/v2/sub/pkg`, and `my/thing/v3/sub/pkg`
   come from major versions v1, v2, and v3 of the module `my/thing`,
   but the build treats them simply as three different packages.
   A program that imports all three will have all three linked into the final binary,
   just as if they were `my/red/pkg`, `my/green/pkg`, and `my/blue/pkg`
   or any other set of three different import paths.
   
   Note that only the major version appears in the import path: `my/thing/v1.2/sub/pkg` is not allowed.
   
   
4. Explicitly adopt the “import compatibility rule”:

   > _If an old package and a new package have the same import path,_\
   > _the new package must be backwards compatible with the old package._
   
   The Go project has encouraged this convention from the start
   of the project, but this proposal gives it more teeth:
{'fraction_non_alphanumeric': 0.06753696549886773, 'fraction_numerical': 0.01971493272945251, 'mean_word_length': 3.929743926460932, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, 'https://': 14, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 8, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7192997', 'n_tokens_mistral': 2205, 'n_tokens_neox': 2078, 'n_words': 1027}