← back to Cli Printing Press
fix(cli): default empty version to 1.0.0 and normalize to semver
f07a795de84c2321989880400c6d60f4e0c9e8a5 · 2026-04-11 12:42:46 -0700 · Trevin Chow
The spec Validate() function now defaults empty versions to "1.0.0"
and normalizes non-semver versions: "4" → "4.0.0", "4.4" → "4.4.0".
Previously, a spec with no version field passed validation and the
template rendered `var version = ""`, making --version print nothing.
Specs from OpenAPI that only had major.minor (e.g., "4.4") produced
non-semver CLI versions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Files touched
M internal/spec/spec.goM internal/spec/spec_test.go
Diff
commit f07a795de84c2321989880400c6d60f4e0c9e8a5
Author: Trevin Chow <trevin@trevinchow.com>
Date: Sat Apr 11 12:42:46 2026 -0700
fix(cli): default empty version to 1.0.0 and normalize to semver
The spec Validate() function now defaults empty versions to "1.0.0"
and normalizes non-semver versions: "4" → "4.0.0", "4.4" → "4.4.0".
Previously, a spec with no version field passed validation and the
template rendered `var version = ""`, making --version print nothing.
Specs from OpenAPI that only had major.minor (e.g., "4.4") produced
non-semver CLI versions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---
internal/spec/spec.go | 10 ++++++++++
internal/spec/spec_test.go | 32 ++++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+)
diff --git a/internal/spec/spec.go b/internal/spec/spec.go
index 4963652d..e7abde8b 100644
--- a/internal/spec/spec.go
+++ b/internal/spec/spec.go
@@ -274,6 +274,16 @@ func (s *APISpec) Validate() error {
if s.Name == "" {
return fmt.Errorf("name is required")
}
+ // Default version to 1.0.0 if missing, and normalize to semver.
+ if s.Version == "" {
+ s.Version = "1.0.0"
+ } else if !strings.Contains(s.Version, ".") {
+ // Bare major: "4" → "4.0.0"
+ s.Version = s.Version + ".0.0"
+ } else if strings.Count(s.Version, ".") == 1 {
+ // Major.minor only: "4.4" → "4.4.0"
+ s.Version = s.Version + ".0"
+ }
// Parser fallback may supply a placeholder base_url when the source spec omits servers.
if s.BaseURL == "" && s.BasePath == "" {
return fmt.Errorf("base_url is required")
diff --git a/internal/spec/spec_test.go b/internal/spec/spec_test.go
index 619ea582..693320de 100644
--- a/internal/spec/spec_test.go
+++ b/internal/spec/spec_test.go
@@ -87,6 +87,38 @@ func TestValidation(t *testing.T) {
}
}
+func TestVersionDefaultAndNormalize(t *testing.T) {
+ base := func(v string) APISpec {
+ return APISpec{
+ Name: "x",
+ Version: v,
+ BaseURL: "http://x",
+ Resources: map[string]Resource{"a": {Endpoints: map[string]Endpoint{"b": {Method: "GET", Path: "/"}}}},
+ }
+ }
+
+ tests := []struct {
+ input string
+ expected string
+ }{
+ {"", "1.0.0"}, // empty → default
+ {"1.0.0", "1.0.0"}, // already semver
+ {"4", "4.0.0"}, // bare major
+ {"4.4", "4.4.0"}, // major.minor only
+ {"4.17.1", "4.17.1"}, // already semver
+ {"0.1.0", "0.1.0"}, // already semver
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.input, func(t *testing.T) {
+ s := base(tt.input)
+ err := s.Validate()
+ require.NoError(t, err)
+ assert.Equal(t, tt.expected, s.Version)
+ })
+ }
+}
+
func TestNewFields(t *testing.T) {
s := APISpec{
Name: "x",
← ad9e4aee fix(cli): movie-goat retro — generator param handling, write
·
back to Cli Printing Press
·
fix(cli): decouple CLI version from API version 68bc76f3 →