Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 51 additions & 18 deletions tools/cli/internal/apiversion/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"fmt"
"log"
"regexp"
"strings"
"time"

"github.com/getkin/kin-openapi/openapi3"
Expand All @@ -31,8 +32,8 @@ type APIVersion struct {

const (
dateFormat = "2006-01-02"
StableStabilityLevel = "STABLE"
PreviewStabilityLevel = "PREVIEW"
StableStabilityLevel = "stable"
PreviewStabilityLevel = "preview"
)

var contentPattern = regexp.MustCompile(`application/vnd\.atlas\.((\d{4})-(\d{2})-(\d{2})|preview)\+(.+)`)
Expand All @@ -51,6 +52,17 @@ func New(opts ...Option) (*APIVersion, error) {
return version, nil
}

func (v *APIVersion) newVersion(version string, date time.Time) {
v.version = version
v.stabilityVersion = StableStabilityLevel
v.versionDate = date

if IsPreviewSabilityLevel(version) {
v.versionDate = time.Now().AddDate(10, 0, 0) // set preview date to the future
v.stabilityVersion = PreviewStabilityLevel
}
}

// WithVersion sets the version on the APIVersion.
func WithVersion(version string) Option {
return func(v *APIVersion) error {
Expand All @@ -59,18 +71,15 @@ func WithVersion(version string) Option {
return err
}

v.version = version
v.versionDate = versionDate
v.newVersion(version, versionDate)
return nil
}
}

// WithDate sets the version on the APIVersion.
func WithDate(date time.Time) Option {
return func(v *APIVersion) error {
v.version = date.Format(dateFormat)
v.versionDate = date
v.stabilityVersion = StableStabilityLevel
v.newVersion(date.Format(dateFormat), date)
return nil
}
}
Expand All @@ -83,22 +92,20 @@ func WithContent(contentType string) Option {
return err
}

v.version = version
v.stabilityVersion = StableStabilityLevel
if version == PreviewStabilityLevel {
v.stabilityVersion = PreviewStabilityLevel
return nil
}

v.versionDate, err = DateFromVersion(version)
versionDate, err := DateFromVersion(version)
if err != nil {
return err
}

v.newVersion(version, versionDate)
return nil
}
}

func DateFromVersion(version string) (time.Time, error) {
if IsPreviewSabilityLevel(version) {
return time.Now(), nil
}
return time.Parse(dateFormat, version)
}

Expand Down Expand Up @@ -130,6 +137,26 @@ func (v *APIVersion) Date() time.Time {
return v.versionDate
}

func (v *APIVersion) StabilityLevel() string {
return v.stabilityVersion
}

func (v *APIVersion) ExactMatchOnly() bool {
return v.IsPreview()
}

func (v *APIVersion) IsPreview() bool {
return IsPreviewSabilityLevel(v.version)
}

func IsPreviewSabilityLevel(value string) bool {
return strings.EqualFold(value, PreviewStabilityLevel)
}

func IsStableSabilityLevel(value string) bool {
return strings.EqualFold(value, StableStabilityLevel)
}

func FindMatchesFromContentType(contentType string) []string {
return contentPattern.FindStringSubmatch(contentType)
}
Expand Down Expand Up @@ -160,6 +187,7 @@ func FindLatestContentVersionMatched(op *openapi3.Operation, requestedVersion *A
op response:
"200":
content: application/vnd.atlas.2023-01-01+json
content: application/vnd.atlas.preview+json
"201":
content: application/vnd.atlas.2023-12-01+json
content: application/vnd.atlas.2025-01-01+json
Expand All @@ -181,14 +209,19 @@ func FindLatestContentVersionMatched(op *openapi3.Operation, requestedVersion *A
log.Printf("Ignoring invalid content type: %q", contentType)
continue
}
if contentVersion.GreaterThan(requestedVersion) {
continue
}

if contentVersion.Equal(requestedVersion) {
return contentVersion
}

if contentVersion.ExactMatchOnly() || requestedVersion.ExactMatchOnly() {
continue
}

if contentVersion.GreaterThan(requestedVersion) {
continue
}

if latestVersionMatch == nil || contentVersion.GreaterThan(latestVersionMatch) {
latestVersionMatch = contentVersion
}
Expand Down
30 changes: 30 additions & 0 deletions tools/cli/internal/apiversion/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,24 @@ func TestParseVersion(t *testing.T) {
expectedMatch: "2030-02-20",
wantErr: false,
},
{
name: "preview_json",
contentType: "application/vnd.atlas.preview+json",
expectedMatch: "preview",
wantErr: false,
},
{
name: "preview_yaml",
contentType: "application/vnd.atlas.preview+yaml",
expectedMatch: "preview",
wantErr: false,
},
{
name: "preview_csv",
contentType: "application/vnd.atlas.preview+csv",
expectedMatch: "preview",
wantErr: false,
},
{
name: "invalid",
contentType: "application/vnd.test.2023-01-01",
Expand Down Expand Up @@ -94,6 +112,12 @@ func TestNewAPIVersionFromContentType(t *testing.T) {
expectedMatch: "2030-02-20",
wantErr: false,
},
{
name: "preview",
contentType: "application/vnd.atlas.preview+json",
expectedMatch: "preview",
wantErr: false,
},
{
name: "invalid",
contentType: "application/vnd.test.2023-01-01",
Expand Down Expand Up @@ -416,6 +440,11 @@ func TestFindLatestContentVersionMatched(t *testing.T) {
targetVersion: "2023-01-01",
expectedMatch: "2023-01-01",
},
{
name: "exact match preview",
targetVersion: "preview",
expectedMatch: "preview",
},
{
name: "exact match 2023-11-15",
targetVersion: "2023-11-15",
Expand Down Expand Up @@ -470,6 +499,7 @@ func oasOperationAllVersions() *openapi3.Operation {
responses.Set("200", &openapi3.ResponseRef{
Value: &openapi3.Response{
Content: map[string]*openapi3.MediaType{
"application/vnd.atlas.preview+json": {},
"application/vnd.atlas.2023-01-01+json": {},
"application/vnd.atlas.2023-01-01+csv": {},
"application/vnd.atlas.2023-02-01+json": {},
Expand Down
4 changes: 2 additions & 2 deletions tools/cli/internal/cli/versions/versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ func (o *Opts) filterStabilityLevelVersions(apiVersions []string) []string {

var out []string
for _, v := range apiVersions {
if o.stabilityLevel == apiversion.PreviewStabilityLevel && strings.Contains(v, "preview") {
if (apiversion.IsStableSabilityLevel(o.stabilityLevel)) && !apiversion.IsPreviewSabilityLevel(v) {
out = append(out, v)
}

if o.stabilityLevel == apiversion.StableStabilityLevel && !strings.Contains(v, "preview") {
if (apiversion.IsPreviewSabilityLevel(o.stabilityLevel)) && apiversion.IsPreviewSabilityLevel(v) {
out = append(out, v)
}
}
Expand Down
Loading