|
12 | 12 | // See the License for the specific language governing permissions and
|
13 | 13 | // limitations under the License.
|
14 | 14 |
|
15 |
| -// Package version contains code related to deployer API versioning. |
| 15 | +// Package version contains the version of the weaver module and its |
| 16 | +// constituent APIs (e.g., the pipe API, the codegen API). |
16 | 17 | package version
|
17 | 18 |
|
18 | 19 | import (
|
19 | 20 | "fmt"
|
20 |
| - "regexp" |
21 |
| - "strconv" |
22 |
| - |
23 |
| - "github.com/ServiceWeaver/weaver/runtime/bin" |
24 | 21 | )
|
25 | 22 |
|
| 23 | +// TODO(mwhittaker): Write a doc explaining versioning in detail. Include |
| 24 | +// Srdjan's comments in PR #219. |
| 25 | + |
26 | 26 | const (
|
27 |
| - // The version of the deployer API---aka pipe API---in semantic version |
28 |
| - // format (Major.Minor.Patch). |
| 27 | + // The weaver module semantic version [1]. |
| 28 | + // |
| 29 | + // [1]: https://go.dev/doc/modules/version-numbers |
| 30 | + ModuleMajor = 0 |
| 31 | + ModuleMinor = 17 |
| 32 | + ModulePatch = 0 |
| 33 | + |
| 34 | + // Note that there is currently no way to programmatically get the version |
| 35 | + // of the current module [1], so we have to manually update the module |
| 36 | + // version here whenever we release a new version. |
29 | 37 | //
|
30 |
| - // Every time we make a change to deployer API, we assign it a new version. |
31 |
| - // When an envelope spawns a weavelet, the weavelet reports this version to |
32 |
| - // the envelope. The envelope then errors out if it is not compatible with |
33 |
| - // the reported version. |
| 38 | + // [1]: https://github.com/golang/go/issues/29228 |
| 39 | + |
| 40 | + // The version of the deployer API. |
34 | 41 | //
|
35 |
| - // We could assign the deployer API versions v1, v2, v3, and so on. |
36 |
| - // However, this makes it hard to understand the relationship between the |
37 |
| - // deployer API version and the version of the Service Weaver module. (What |
38 |
| - // version of Service Weaver do I need to install to get version 7 of the |
39 |
| - // pipe?) |
| 42 | + // Every time we make a change to the deployer API, we assign it a new |
| 43 | + // version. We could assign the deployer API versions v1, v2, v3, and so |
| 44 | + // on. However, this makes it hard to understand the relationship between |
| 45 | + // the deployer API version and the version of the Service Weaver module. |
40 | 46 | //
|
41 | 47 | // Instead, we use Service Weaver module versions as deployer API versions.
|
42 | 48 | // For example, if we change the deployer API in v0.12.0 of Service Weaver,
|
43 | 49 | // then we update the deployer API version to v0.12.0. If we don't change
|
44 | 50 | // the deployer API in v0.13.0 of Service Weaver, then we leave the
|
45 | 51 | // deployer API at v0.12.0.
|
46 |
| - // |
47 |
| - // TODO(mwhittaker): Write a doc explaining versioning in detail. Include |
48 |
| - // Srdjan's comments in PR #219. |
49 |
| - Major = 0 |
50 |
| - Minor = 14 |
51 |
| - Patch = 0 |
| 52 | + DeployerMajor = 0 |
| 53 | + DeployerMinor = 14 |
| 54 | + |
| 55 | + // The version of the codegen API. As with the deployer API, we assign a |
| 56 | + // new version every time we change how code is generated, and we use |
| 57 | + // weaver module versions. |
| 58 | + CodegenMajor = 0 |
| 59 | + CodegenMinor = 17 |
52 | 60 | )
|
53 | 61 |
|
54 |
| -// version exists to embed the deployer API version into a Service Weaver |
55 |
| -// binary. We split declaring and assigning version to prevent the compiler |
56 |
| -// from erasing it. |
57 |
| -// |
58 |
| -// NOTE that version should be initialized with a hardcoded string that should |
59 |
| -// reflect the values of Major, Minor and Patch. |
60 |
| -// |
61 |
| -//nolint:unused |
62 |
| -var version string |
| 62 | +var ( |
| 63 | + // The weaver module version. |
| 64 | + ModuleVersion = SemVer{ModuleMajor, ModuleMinor, ModulePatch} |
63 | 65 |
|
64 |
| -func init() { |
65 |
| - // Make sure that the hardcoded string reflects the values of Major, Minor and |
66 |
| - // Patch. |
67 |
| - version = "⟦wEaVeRvErSiOn:0.14.0⟧" |
68 |
| -} |
| 66 | + // The deployer API version. |
| 67 | + DeployerVersion = SemVer{DeployerMajor, DeployerMinor, 0} |
| 68 | + |
| 69 | + // The codegen API version. |
| 70 | + CodegenVersion = SemVer{CodegenMajor, CodegenMinor, 0} |
| 71 | +) |
69 | 72 |
|
70 |
| -// ReadVersion reads version (major, minor, patch) from the specified binary. |
71 |
| -func ReadVersion(filename string) (int, int, int, error) { |
72 |
| - data, err := bin.ROData(filename) |
73 |
| - if err != nil { |
74 |
| - return 0, 0, 0, err |
75 |
| - } |
76 |
| - return extractVersion(data) |
| 73 | +// SemVer is a semantic version. See https://go.dev/doc/modules/version-numbers |
| 74 | +// for details. |
| 75 | +type SemVer struct { |
| 76 | + Major int |
| 77 | + Minor int |
| 78 | + Patch int |
77 | 79 | }
|
78 | 80 |
|
79 |
| -// extractVersion returns the version (major, minor, patch) corresponding to |
80 |
| -// MakeVersionString() embedded in data. |
81 |
| -func extractVersion(data []byte) (int, int, int, error) { |
82 |
| - re := regexp.MustCompile(`⟦wEaVeRvErSiOn:([0-9]*?)\.([0-9]*?)\.([0-9]*?)⟧`) |
83 |
| - m := re.FindSubmatch(data) |
84 |
| - if m == nil { |
85 |
| - return 0, 0, 0, fmt.Errorf("version not found") |
86 |
| - } |
87 |
| - major, minor, patch := string(m[1]), string(m[2]), string(m[3]) |
88 |
| - ma, err := strconv.Atoi(major) |
89 |
| - if err != nil { |
90 |
| - return 0, 0, 0, fmt.Errorf("invalid major %q: %w", major, err) |
91 |
| - } |
92 |
| - mi, err := strconv.Atoi(minor) |
93 |
| - if err != nil { |
94 |
| - return 0, 0, 0, fmt.Errorf("invalid minor %q: %w", minor, err) |
95 |
| - } |
96 |
| - pa, err := strconv.Atoi(patch) |
97 |
| - if err != nil { |
98 |
| - return 0, 0, 0, fmt.Errorf("invalid patch %q: %w", patch, err) |
99 |
| - } |
100 |
| - return ma, mi, pa, nil |
| 81 | +func (s SemVer) String() string { |
| 82 | + return fmt.Sprintf("v%d.%d.%d", s.Major, s.Minor, s.Patch) |
101 | 83 | }
|
0 commit comments