Skip to content

Commit 358b7bc

Browse files
CLOUDP-301830: Separate private and public preview stability levels in version command for granularity (#434)
Co-authored-by: Andrea Angiolillo <[email protected]>
1 parent 6bde71a commit 358b7bc

File tree

5 files changed

+93
-34
lines changed

5 files changed

+93
-34
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2025 MongoDB Inc
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package apiversion
16+
17+
import (
18+
"fmt"
19+
"strings"
20+
)
21+
22+
const (
23+
StableStabilityLevel = "stable"
24+
PreviewStabilityLevel = "preview"
25+
PrivatePreviewStabilityLevel = "private-preview"
26+
PublicPreviewSabilityLevel = "public-preview"
27+
)
28+
29+
var supportedValues = []string{StableStabilityLevel, PublicPreviewSabilityLevel, PrivatePreviewStabilityLevel}
30+
31+
// IsPreviewSabilityLevel checks if the version is a preview version, public or private.
32+
func IsPreviewSabilityLevel(value string) bool {
33+
return IsPrivatePreviewSabilityLevel(value) || IsPublicPreviewSabilityLevel(value)
34+
}
35+
36+
// IsPrivatePreviewSabilityLevel checks if the version is a private preview version.
37+
func IsPrivatePreviewSabilityLevel(value string) bool {
38+
return strings.Contains(strings.ToLower(value), PrivatePreviewStabilityLevel)
39+
}
40+
41+
// IsPublicPreviewSabilityLevel checks if the version is a public preview version.
42+
func IsPublicPreviewSabilityLevel(value string) bool {
43+
return strings.EqualFold(value, PublicPreviewSabilityLevel) || strings.EqualFold(value, PreviewStabilityLevel)
44+
}
45+
46+
// IsStableSabilityLevel checks if the version is a stable version.
47+
func IsStableSabilityLevel(value string) bool {
48+
return strings.EqualFold(value, StableStabilityLevel)
49+
}
50+
51+
// IsValidStabilityLevel checks if the version is a valid stability level.
52+
// ValidateStabilityLevel checks if the version is a valid stability level.
53+
func ValidateStabilityLevel(value string) error {
54+
if IsStableSabilityLevel(value) || IsPreviewSabilityLevel(value) {
55+
return nil
56+
}
57+
58+
return fmt.Errorf("invalid stability level value must be in %q, got %q", supportedValues, value)
59+
}

tools/cli/internal/apiversion/version.go

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,7 @@ type APIVersion struct {
3232
}
3333

3434
const (
35-
dateFormat = "2006-01-02"
36-
StableStabilityLevel = "stable"
37-
PreviewStabilityLevel = "preview"
38-
PrivatePreviewStabilityLevel = "private-preview"
35+
dateFormat = "2006-01-02"
3936
)
4037

4138
var contentPattern = regexp.MustCompile(`application/vnd\.atlas\.((\d{4})-(\d{2})-(\d{2})|preview)\+(.+)`)
@@ -107,7 +104,7 @@ func withContent(contentType string) Option {
107104
// WithFullContent returns an Option to generate a new APIVersion given the contentType and contentValue.
108105
func WithFullContent(contentType string, contentValue *openapi3.MediaType) Option {
109106
return func(v *APIVersion) error {
110-
if !IsPreviewSabilityLevel(contentType) {
107+
if !strings.Contains(contentType, PreviewStabilityLevel) {
111108
return withContent(contentType)(v)
112109
}
113110

@@ -175,15 +172,6 @@ func (v *APIVersion) IsPublicPreview() bool {
175172
return v.IsPreview() && !v.IsPrivatePreview()
176173
}
177174

178-
func IsPreviewSabilityLevel(value string) bool {
179-
// we also need string match given private preview versions like "private-preview-<name>"
180-
return strings.EqualFold(value, PreviewStabilityLevel) || strings.Contains(value, PreviewStabilityLevel)
181-
}
182-
183-
func IsStableSabilityLevel(value string) bool {
184-
return strings.EqualFold(value, StableStabilityLevel)
185-
}
186-
187175
func FindMatchesFromContentType(contentType string) []string {
188176
return contentPattern.FindStringSubmatch(contentType)
189177
}

tools/cli/internal/cli/usage/usage.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,5 @@ const (
3737
SlackChannelID = "Slack Channel ID."
3838
From = "Date in the format YYYY-MM-DD that indicates the start of a date range"
3939
To = "Date in the format YYYY-MM-DD that indicates the end of a date range"
40-
StabilityLevel = "Stability level related to the API Version. Valid values: [STABLE, PREVIEW]"
40+
StabilityLevel = "Stability level related to the API Version. Valid values: [STABLE, PUBLIC-PREVIEW, PRIVATE-PREVIEW]"
4141
)

tools/cli/internal/cli/versions/versions.go

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type Opts struct {
3535
outputPath string
3636
format string
3737
env string
38-
stabilityLevel string
38+
stabilityLevel []string
3939
}
4040

4141
func (o *Opts) Run() error {
@@ -70,21 +70,30 @@ func (o *Opts) Run() error {
7070
}
7171

7272
func (o *Opts) filterStabilityLevelVersions(apiVersions []string) []string {
73-
if o.stabilityLevel == "" || apiVersions == nil {
73+
if len(o.stabilityLevel) == 0 || apiVersions == nil {
7474
return apiVersions
7575
}
7676

7777
var out []string
7878
for _, v := range apiVersions {
79-
if (apiversion.IsStableSabilityLevel(o.stabilityLevel)) && !apiversion.IsPreviewSabilityLevel(v) {
80-
out = append(out, v)
81-
}
82-
83-
if (apiversion.IsPreviewSabilityLevel(o.stabilityLevel)) && apiversion.IsPreviewSabilityLevel(v) {
84-
out = append(out, v)
79+
for _, stabilityLevel := range o.stabilityLevel {
80+
if (apiversion.IsStableSabilityLevel(stabilityLevel)) && !apiversion.IsPreviewSabilityLevel(v) {
81+
out = append(out, v)
82+
}
83+
84+
if (apiversion.IsPrivatePreviewSabilityLevel(stabilityLevel)) && apiversion.IsPrivatePreviewSabilityLevel(v) {
85+
out = append(out, v)
86+
}
87+
88+
if (apiversion.IsPublicPreviewSabilityLevel(stabilityLevel)) && apiversion.IsPublicPreviewSabilityLevel(v) {
89+
out = append(out, v)
90+
}
8591
}
8692
}
8793

94+
if len(out) == 0 {
95+
return []string{}
96+
}
8897
return out
8998
}
9099

@@ -112,9 +121,12 @@ func (o *Opts) versionsAsBytes(versions []string) ([]byte, error) {
112121
}
113122

114123
func (o *Opts) PreRunE(_ []string) error {
115-
o.stabilityLevel = strings.ToLower(o.stabilityLevel)
116-
if o.stabilityLevel != "" && o.stabilityLevel != apiversion.PreviewStabilityLevel && o.stabilityLevel != apiversion.StableStabilityLevel {
117-
return fmt.Errorf("stability level must be %q or %q, got %q", apiversion.PreviewStabilityLevel, apiversion.StableStabilityLevel, o.stabilityLevel)
124+
for i, v := range o.stabilityLevel {
125+
o.stabilityLevel[i] = strings.ToLower(v)
126+
127+
if err := apiversion.ValidateStabilityLevel(o.stabilityLevel[i]); err != nil {
128+
return err
129+
}
118130
}
119131

120132
if o.basePath == "" {
@@ -154,7 +166,7 @@ func Builder() *cobra.Command {
154166

155167
cmd.Flags().StringVarP(&opts.basePath, flag.Spec, flag.SpecShort, "", usage.Spec)
156168
cmd.Flags().StringVar(&opts.env, flag.Environment, "", usage.Environment)
157-
cmd.Flags().StringVarP(&opts.stabilityLevel, flag.StabilityLevel, flag.StabilityLevelShort, "", usage.StabilityLevel)
169+
cmd.Flags().StringArrayVar(&opts.stabilityLevel, flag.StabilityLevel, nil, usage.StabilityLevel)
158170
cmd.Flags().StringVarP(&opts.outputPath, flag.Output, flag.OutputShort, "", usage.Output)
159171
cmd.Flags().StringVarP(&opts.format, flag.Format, flag.FormatShort, "json", usage.Format)
160172
return cmd

tools/cli/internal/cli/versions/versions_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func TestVersion_RunStabilityLevelPreviewAndPrivatePreview(t *testing.T) {
8282
outputPath: "foas.json",
8383
fs: fs,
8484
env: "staging",
85-
stabilityLevel: "PREVIEW",
85+
stabilityLevel: []string{"private-preview"},
8686
}
8787

8888
require.NoError(t, opts.Run())
@@ -102,7 +102,7 @@ func TestVersion_PreviewAndPublicPreview(t *testing.T) {
102102
outputPath: "foas.json",
103103
fs: fs,
104104
env: "staging",
105-
stabilityLevel: "PREVIEW",
105+
stabilityLevel: []string{"public-preview"},
106106
}
107107

108108
require.NoError(t, opts.Run())
@@ -122,7 +122,7 @@ func TestVersion_RunStabilityLevelStable(t *testing.T) {
122122
outputPath: "foas.json",
123123
fs: fs,
124124
env: "staging",
125-
stabilityLevel: "STABLE",
125+
stabilityLevel: []string{"STABLE"},
126126
}
127127

128128
require.NoError(t, opts.Run())
@@ -189,18 +189,18 @@ func TestVersion_PreRun(t *testing.T) {
189189
basePath: "base",
190190
outputPath: "output.yaml",
191191
format: "yaml",
192-
stabilityLevel: "invalid",
192+
stabilityLevel: []string{"invalid"},
193193
}
194194
err := opts.PreRunE(nil)
195195
require.Error(t, err)
196-
assert.Contains(t, err.Error(), "stability level must be")
196+
assert.Contains(t, err.Error(), "invalid stability level value m")
197197
})
198198
t.Run("ValidStabilityLevelPreview", func(t *testing.T) {
199199
opts := &Opts{
200200
basePath: "base",
201201
outputPath: "output.yaml",
202202
format: "yaml",
203-
stabilityLevel: "preview",
203+
stabilityLevel: []string{"PREVIEW"},
204204
}
205205
err := opts.PreRunE(nil)
206206
require.NoError(t, err)
@@ -211,7 +211,7 @@ func TestVersion_PreRun(t *testing.T) {
211211
basePath: "base",
212212
outputPath: "output.yaml",
213213
format: "yaml",
214-
stabilityLevel: "PREVIEW",
214+
stabilityLevel: []string{"PREVIEW"},
215215
}
216216
err := opts.PreRunE(nil)
217217
require.NoError(t, err)

0 commit comments

Comments
 (0)