From 4962e6a2e91796f73ab9df4782fccd56fd8fcb95 Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Wed, 26 Feb 2025 13:54:36 +0000 Subject: [PATCH 01/14] update --- tools/cli/internal/cli/split/split.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cli/internal/cli/split/split.go b/tools/cli/internal/cli/split/split.go index df6e697fab..a1b3611327 100644 --- a/tools/cli/internal/cli/split/split.go +++ b/tools/cli/internal/cli/split/split.go @@ -91,7 +91,7 @@ func (o *Opts) saveVersionedOas(oas *openapi3.T, version string) error { } path = strings.Replace(path, "."+o.format, fmt.Sprintf("-%s.%s", version, o.format), 1) - return openapi.Save(path, oas, o.format, o.fs) + return openapi.SaveToFile(path, o.format, oas, o.fs) } func (o *Opts) PreRunE(_ []string) error { From 6cf0cf2073e6f2c093472b14bf22fd176bf48980 Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Thu, 27 Feb 2025 17:41:21 +0000 Subject: [PATCH 02/14] update --- tools/cli/internal/cli/split/split.go | 2 +- tools/cli/internal/openapi/file.go | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/cli/internal/cli/split/split.go b/tools/cli/internal/cli/split/split.go index a1b3611327..df6e697fab 100644 --- a/tools/cli/internal/cli/split/split.go +++ b/tools/cli/internal/cli/split/split.go @@ -91,7 +91,7 @@ func (o *Opts) saveVersionedOas(oas *openapi3.T, version string) error { } path = strings.Replace(path, "."+o.format, fmt.Sprintf("-%s.%s", version, o.format), 1) - return openapi.SaveToFile(path, o.format, oas, o.fs) + return openapi.Save(path, oas, o.format, o.fs) } func (o *Opts) PreRunE(_ []string) error { diff --git a/tools/cli/internal/openapi/file.go b/tools/cli/internal/openapi/file.go index edb6daf304..6db2133485 100644 --- a/tools/cli/internal/openapi/file.go +++ b/tools/cli/internal/openapi/file.go @@ -118,6 +118,8 @@ func SerializeToYAML(data []byte) ([]byte, error) { return yamlData, nil } +// Save saves the OpenAPI document to a file in the specified format. This is important for public +// OpenAPI documents as it ensures to follow the order of the Spec object. func Save(path string, oas *openapi3.T, format string, fs afero.Fs) error { return SaveToFile(path, format, newSpec(oas), fs) } From e2e11c027b9c4aaf0c4f11e6f28121811dfcb2ad Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Thu, 27 Feb 2025 17:44:13 +0000 Subject: [PATCH 03/14] Update --- tools/cli/internal/cli/usage/usage.go | 2 +- tools/cli/internal/openapi/file.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/cli/internal/cli/usage/usage.go b/tools/cli/internal/cli/usage/usage.go index 8dc166a582..5918454f07 100644 --- a/tools/cli/internal/cli/usage/usage.go +++ b/tools/cli/internal/cli/usage/usage.go @@ -18,7 +18,7 @@ const ( Base = "Base OAS. The command will merge other OASes into it." External = "OASes that will be merged into the base OAS." Output = "File name or path where the command will store the output." - Format = "Output format. Supported values are 'json' and 'yaml'." + Format = "Output format. Supported values are 'json', 'yaml' or 'all' which will generate one file for each supported format." Versions = "Boolean flag that defines wether to split the OAS into multiple versions." VersionsChangelog = "List of versions to consider when generating the changelog. (Format: YYYY-MM-DD)" Spec = "Path to the OAS file." diff --git a/tools/cli/internal/openapi/file.go b/tools/cli/internal/openapi/file.go index 6db2133485..649f1608d0 100644 --- a/tools/cli/internal/openapi/file.go +++ b/tools/cli/internal/openapi/file.go @@ -41,7 +41,7 @@ func SaveToFile[T any](path, format string, content T, fs afero.Fs) error { return err } - if format == JSON || format == "" { + if format == JSON || format == "" || format == "all" { jsonPath := newPathWithExtension(path, JSON) if errJSON := afero.WriteFile(fs, jsonPath, data, 0o600); errJSON != nil { return errJSON @@ -49,7 +49,7 @@ func SaveToFile[T any](path, format string, content T, fs afero.Fs) error { log.Printf("\nFile was saved in '%s'.\n\n", jsonPath) } - if format == YAML || format == "" { + if format == YAML || format == "" || format == "all" { dataYAML, err := SerializeToYAML(data) if err != nil { return err From 3d845927853eecfd9cecb18e113a57731d08aee5 Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Thu, 27 Feb 2025 17:49:41 +0000 Subject: [PATCH 04/14] update --- tools/cli/internal/cli/merge/merge.go | 4 ++-- tools/cli/internal/cli/split/split.go | 10 +++------- tools/cli/internal/openapi/file.go | 14 ++++++++++++-- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/tools/cli/internal/cli/merge/merge.go b/tools/cli/internal/cli/merge/merge.go index 44ba523df0..6c55ca5054 100644 --- a/tools/cli/internal/cli/merge/merge.go +++ b/tools/cli/internal/cli/merge/merge.go @@ -75,8 +75,8 @@ func (o *Opts) PreRunE(_ []string) error { return fmt.Errorf("output file must be either a JSON or YAML file, got %s", o.outputPath) } - if o.format != "json" && o.format != "yaml" { - return fmt.Errorf("output format must be either 'json' or 'yaml', got %s", o.format) + if err := openapi.ValidateFormat(o.format); err != nil { + return err } m, err := openapi.NewOasDiff(o.basePath, o.excludePrivatePaths) diff --git a/tools/cli/internal/cli/split/split.go b/tools/cli/internal/cli/split/split.go index df6e697fab..7e27f21800 100644 --- a/tools/cli/internal/cli/split/split.go +++ b/tools/cli/internal/cli/split/split.go @@ -103,12 +103,8 @@ func (o *Opts) PreRunE(_ []string) error { return fmt.Errorf("output file must be either a JSON or YAML file, got %s", o.outputPath) } - if o.format != openapi.JSON && o.format != openapi.YAML { - return fmt.Errorf("output format must be either 'json' or 'yaml', got %s", o.format) - } - - if strings.Contains(o.basePath, openapi.DotYAML) { - o.format = openapi.YAML + if err := openapi.ValidateFormat(o.format); err != nil { + return err } return nil @@ -136,7 +132,7 @@ func Builder() *cobra.Command { cmd.Flags().StringVarP(&opts.basePath, flag.Spec, flag.SpecShort, "-", usage.Spec) cmd.Flags().StringVar(&opts.env, flag.Environment, "", usage.Environment) cmd.Flags().StringVarP(&opts.outputPath, flag.Output, flag.OutputShort, "", usage.Output) - cmd.Flags().StringVarP(&opts.format, flag.Format, flag.FormatShort, openapi.JSON, usage.Format) + cmd.Flags().StringVarP(&opts.format, flag.Format, flag.FormatShort, openapi.ALL, usage.Format) cmd.Flags().StringVar(&opts.gitSha, flag.GitSha, "", usage.GitSha) _ = cmd.MarkFlagRequired(flag.Output) diff --git a/tools/cli/internal/openapi/file.go b/tools/cli/internal/openapi/file.go index 649f1608d0..e9c852f458 100644 --- a/tools/cli/internal/openapi/file.go +++ b/tools/cli/internal/openapi/file.go @@ -29,6 +29,7 @@ import ( const ( JSON = "json" YAML = "yaml" + ALL = "all" DotYAML = ".yaml" DotJSON = ".json" ) @@ -41,7 +42,7 @@ func SaveToFile[T any](path, format string, content T, fs afero.Fs) error { return err } - if format == JSON || format == "" || format == "all" { + if format == JSON || format == "" || format == ALL { jsonPath := newPathWithExtension(path, JSON) if errJSON := afero.WriteFile(fs, jsonPath, data, 0o600); errJSON != nil { return errJSON @@ -49,7 +50,7 @@ func SaveToFile[T any](path, format string, content T, fs afero.Fs) error { log.Printf("\nFile was saved in '%s'.\n\n", jsonPath) } - if format == YAML || format == "" || format == "all" { + if format == YAML || format == "" || format == ALL { dataYAML, err := SerializeToYAML(data) if err != nil { return err @@ -123,3 +124,12 @@ func SerializeToYAML(data []byte) ([]byte, error) { func Save(path string, oas *openapi3.T, format string, fs afero.Fs) error { return SaveToFile(path, format, newSpec(oas), fs) } + +// ValidateFormat validates the format of files supported. +func ValidateFormat(format string) error { + if format != JSON && format != YAML && format != ALL { + return fmt.Errorf("format must be either 'json', 'yaml' or 'all', got %s", format) + } + + return nil +} From 2079a7c7e1d5ef4da5787a2016d0640ca9503791 Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Wed, 5 Mar 2025 15:34:58 +0000 Subject: [PATCH 05/14] lint --- tools/cli/internal/cli/split/split.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/cli/internal/cli/split/split.go b/tools/cli/internal/cli/split/split.go index 7e27f21800..b74b0447ac 100644 --- a/tools/cli/internal/cli/split/split.go +++ b/tools/cli/internal/cli/split/split.go @@ -103,11 +103,7 @@ func (o *Opts) PreRunE(_ []string) error { return fmt.Errorf("output file must be either a JSON or YAML file, got %s", o.outputPath) } - if err := openapi.ValidateFormat(o.format); err != nil { - return err - } - - return nil + return openapi.ValidateFormat(o.format) } // Builder builds the split command with the following signature: From ac595048b403b09a6f6b71f605b00c2d60004d33 Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Wed, 5 Mar 2025 15:41:42 +0000 Subject: [PATCH 06/14] Fix unit tests --- tools/cli/internal/cli/merge/merge_test.go | 2 +- tools/cli/internal/cli/split/split_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/cli/internal/cli/merge/merge_test.go b/tools/cli/internal/cli/merge/merge_test.go index 69e5d0d0e6..c0770bfa06 100644 --- a/tools/cli/internal/cli/merge/merge_test.go +++ b/tools/cli/internal/cli/merge/merge_test.go @@ -150,7 +150,7 @@ func TestInvalidFormat_PreRun(t *testing.T) { err := opts.PreRunE(nil) require.Error(t, err) - require.EqualError(t, err, "output format must be either 'json' or 'yaml', got html") + require.EqualError(t, err, "output format must be either 'json', 'yaml' or 'all', got html") } func TestInvalidPath_PreRun(t *testing.T) { diff --git a/tools/cli/internal/cli/split/split_test.go b/tools/cli/internal/cli/split/split_test.go index 0597fd9305..82e7028c15 100644 --- a/tools/cli/internal/cli/split/split_test.go +++ b/tools/cli/internal/cli/split/split_test.go @@ -172,7 +172,7 @@ func TestInvalidFormat_PreRun(t *testing.T) { err := opts.PreRunE(nil) require.Error(t, err) - require.EqualError(t, err, "output format must be either 'json' or 'yaml', got html") + require.EqualError(t, err, "output format must be either 'json', 'yaml' or 'all', got html") } func TestInvalidPath_PreRun(t *testing.T) { From 7e09b406d0bec6a1e60649d8bd6decd2f64b4fa8 Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Wed, 5 Mar 2025 15:45:31 +0000 Subject: [PATCH 07/14] update --- tools/cli/internal/cli/merge/merge_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cli/internal/cli/merge/merge_test.go b/tools/cli/internal/cli/merge/merge_test.go index c0770bfa06..a85b080743 100644 --- a/tools/cli/internal/cli/merge/merge_test.go +++ b/tools/cli/internal/cli/merge/merge_test.go @@ -150,7 +150,7 @@ func TestInvalidFormat_PreRun(t *testing.T) { err := opts.PreRunE(nil) require.Error(t, err) - require.EqualError(t, err, "output format must be either 'json', 'yaml' or 'all', got html") + require.EqualError(t, err, "format must be either 'json', 'yaml' or 'all', got html") } func TestInvalidPath_PreRun(t *testing.T) { From ff39e8a0b5367e21bb49fb4b649cfbadc44fcc7d Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Wed, 5 Mar 2025 15:59:32 +0000 Subject: [PATCH 08/14] updatE --- tools/cli/internal/cli/merge/merge_test.go | 2 +- tools/cli/internal/cli/split/split_test.go | 2 +- tools/cli/internal/openapi/file.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/cli/internal/cli/merge/merge_test.go b/tools/cli/internal/cli/merge/merge_test.go index a85b080743..e7fc4700d2 100644 --- a/tools/cli/internal/cli/merge/merge_test.go +++ b/tools/cli/internal/cli/merge/merge_test.go @@ -150,7 +150,7 @@ func TestInvalidFormat_PreRun(t *testing.T) { err := opts.PreRunE(nil) require.Error(t, err) - require.EqualError(t, err, "format must be either 'json', 'yaml' or 'all', got html") + require.EqualError(t, err, "format must be either 'json', 'yaml' or 'all', got 'html'") } func TestInvalidPath_PreRun(t *testing.T) { diff --git a/tools/cli/internal/cli/split/split_test.go b/tools/cli/internal/cli/split/split_test.go index 82e7028c15..9ca6371739 100644 --- a/tools/cli/internal/cli/split/split_test.go +++ b/tools/cli/internal/cli/split/split_test.go @@ -172,7 +172,7 @@ func TestInvalidFormat_PreRun(t *testing.T) { err := opts.PreRunE(nil) require.Error(t, err) - require.EqualError(t, err, "output format must be either 'json', 'yaml' or 'all', got html") + require.EqualError(t, err, "format must be either 'json', 'yaml' or 'all', got 'html'") } func TestInvalidPath_PreRun(t *testing.T) { diff --git a/tools/cli/internal/openapi/file.go b/tools/cli/internal/openapi/file.go index e9c852f458..02a0dfedce 100644 --- a/tools/cli/internal/openapi/file.go +++ b/tools/cli/internal/openapi/file.go @@ -128,7 +128,7 @@ func Save(path string, oas *openapi3.T, format string, fs afero.Fs) error { // ValidateFormat validates the format of files supported. func ValidateFormat(format string) error { if format != JSON && format != YAML && format != ALL { - return fmt.Errorf("format must be either 'json', 'yaml' or 'all', got %s", format) + return fmt.Errorf("format must be either 'json', 'yaml' or 'all', got '%s'", format) } return nil From 1fae86e31b2ea66837fcbff73323db772c1ed11d Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Wed, 5 Mar 2025 16:04:35 +0000 Subject: [PATCH 09/14] fix default --- tools/cli/internal/cli/split/split.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cli/internal/cli/split/split.go b/tools/cli/internal/cli/split/split.go index b74b0447ac..9741fb42bc 100644 --- a/tools/cli/internal/cli/split/split.go +++ b/tools/cli/internal/cli/split/split.go @@ -128,7 +128,7 @@ func Builder() *cobra.Command { cmd.Flags().StringVarP(&opts.basePath, flag.Spec, flag.SpecShort, "-", usage.Spec) cmd.Flags().StringVar(&opts.env, flag.Environment, "", usage.Environment) cmd.Flags().StringVarP(&opts.outputPath, flag.Output, flag.OutputShort, "", usage.Output) - cmd.Flags().StringVarP(&opts.format, flag.Format, flag.FormatShort, openapi.ALL, usage.Format) + cmd.Flags().StringVarP(&opts.format, flag.Format, flag.FormatShort, openapi.JSON, usage.Format) cmd.Flags().StringVar(&opts.gitSha, flag.GitSha, "", usage.GitSha) _ = cmd.MarkFlagRequired(flag.Output) From 8c6b263aaa3e1b05678706a9c1593d1d11a17651 Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Wed, 5 Mar 2025 16:44:17 +0000 Subject: [PATCH 10/14] update --- tools/cli/internal/openapi/file.go | 8 +- tools/cli/internal/openapi/file_test.go | 112 +++++++++++++++++++----- 2 files changed, 95 insertions(+), 25 deletions(-) diff --git a/tools/cli/internal/openapi/file.go b/tools/cli/internal/openapi/file.go index 02a0dfedce..9c84b0d34c 100644 --- a/tools/cli/internal/openapi/file.go +++ b/tools/cli/internal/openapi/file.go @@ -35,13 +35,19 @@ const ( ) // SaveToFile saves the content to a file in the specified format. -// If format is empty, it saves the content in both JSON and YAML formats. +// If format is empty or set to 'all', it saves the content in both JSON and YAML formats. func SaveToFile[T any](path, format string, content T, fs afero.Fs) error { data, err := SerializeToJSON(content) if err != nil { return err } + if format == ALL || format == "" { + // strip . format from path + path = strings.TrimSuffix(path, DotJSON) + path = strings.TrimSuffix(path, DotYAML) + } + if format == JSON || format == "" || format == ALL { jsonPath := newPathWithExtension(path, JSON) if errJSON := afero.WriteFile(fs, jsonPath, data, 0o600); errJSON != nil { diff --git a/tools/cli/internal/openapi/file_test.go b/tools/cli/internal/openapi/file_test.go index e239599064..a7baae1d34 100644 --- a/tools/cli/internal/openapi/file_test.go +++ b/tools/cli/internal/openapi/file_test.go @@ -18,6 +18,7 @@ import ( "testing" "github.com/getkin/kin-openapi/openapi3" + "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -31,35 +32,15 @@ func TestNewArrayBytesFromOAS(t *testing.T) { expected string }{ { - name: "JSON with HTML characters", - spec: &Spec{ - Paths: openapi3.NewPaths( - openapi3.WithPath( - "/api/atlas/v2/groups/{groupId}/databaseUsers/{databaseName}/{username}", - &openapi3.PathItem{ - Delete: &openapi3.Operation{ - Description: "&", - }, - }, - )), - }, + name: "JSON with HTML characters", + spec: getTestSpecWithHtmlChars(), path: "test.json", format: "json", expected: "&", }, { - name: "YAML with HTML characters", - spec: &Spec{ - Paths: openapi3.NewPaths( - openapi3.WithPath( - "/api/atlas/v2/groups/{groupId}/databaseUsers/{databaseName}/{username}", - &openapi3.PathItem{ - Delete: &openapi3.Operation{ - Description: "&", - }, - }, - )), - }, + name: "YAML with HTML characters", + spec: getTestSpecWithHtmlChars(), path: "test.yaml", format: "yaml", expected: "&", @@ -109,3 +90,86 @@ func TestNewArrayBytesFromOAS(t *testing.T) { }) } } + +func TestSaveToFileFormats(t *testing.T) { + tests := []struct { + name string + spec *Spec + path string + format string + expected string + }{ + { + name: "JSON with HTML characters", + spec: getTestSpecWithHtmlChars(), + path: "test.json", + format: "json", + expected: "&", + }, + { + name: "YAML with HTML characters", + spec: getTestSpecWithHtmlChars(), + + path: "test.yaml", + format: "yaml", + expected: "&", + }, + { + name: "all with HTML characters", + spec: getTestSpecWithHtmlChars(), + path: "test.yaml", + format: "all", + expected: "&", + }, + { + name: "empty format with HTML characters", + spec: getTestSpecWithHtmlChars(), + path: "test.yaml", + format: "", + expected: "&", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + fs := afero.NewMemMapFs() + err := SaveToFile(tt.path, tt.format, tt.spec, fs) + require.NoError(t, err) + + data, err := afero.ReadFile(fs, tt.path) + require.NoError(t, err) + assert.Contains(t, string(data), tt.expected) + }) + } +} + +func TestSaveToFile_All(t *testing.T) { + fs := afero.NewMemMapFs() + err := SaveToFile("test.yaml", "all", getTestSpecWithHtmlChars(), fs) + require.NoError(t, err) + + // read yaml file + data, err := afero.ReadFile(fs, "test.yaml") + require.NoError(t, err) + assert.Contains(t, string(data), "&") + + // read json file + data, err = afero.ReadFile(fs, "test.json") + require.NoError(t, err) + assert.Contains(t, string(data), "&") +} + +func getTestSpecWithHtmlChars() *Spec { + return &Spec{ + Paths: openapi3.NewPaths( + openapi3.WithPath( + "/api/atlas/v2/groups/{groupId}/databaseUsers/{databaseName}/{username}", + &openapi3.PathItem{ + Delete: &openapi3.Operation{ + Description: "&", + }, + }, + ), + ), + } +} From bc20880eee04abb7ed799ff0df0585cf4fa29608 Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Wed, 5 Mar 2025 16:47:02 +0000 Subject: [PATCH 11/14] update --- tools/cli/internal/openapi/file_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/cli/internal/openapi/file_test.go b/tools/cli/internal/openapi/file_test.go index a7baae1d34..e81f445ce2 100644 --- a/tools/cli/internal/openapi/file_test.go +++ b/tools/cli/internal/openapi/file_test.go @@ -33,14 +33,14 @@ func TestNewArrayBytesFromOAS(t *testing.T) { }{ { name: "JSON with HTML characters", - spec: getTestSpecWithHtmlChars(), + spec: getTestSpecWithHTMLChars(), path: "test.json", format: "json", expected: "&", }, { name: "YAML with HTML characters", - spec: getTestSpecWithHtmlChars(), + spec: getTestSpecWithHTMLChars(), path: "test.yaml", format: "yaml", expected: "&", @@ -101,14 +101,14 @@ func TestSaveToFileFormats(t *testing.T) { }{ { name: "JSON with HTML characters", - spec: getTestSpecWithHtmlChars(), + spec: getTestSpecWithHTMLChars(), path: "test.json", format: "json", expected: "&", }, { name: "YAML with HTML characters", - spec: getTestSpecWithHtmlChars(), + spec: getTestSpecWithHTMLChars(), path: "test.yaml", format: "yaml", @@ -116,14 +116,14 @@ func TestSaveToFileFormats(t *testing.T) { }, { name: "all with HTML characters", - spec: getTestSpecWithHtmlChars(), + spec: getTestSpecWithHTMLChars(), path: "test.yaml", format: "all", expected: "&", }, { name: "empty format with HTML characters", - spec: getTestSpecWithHtmlChars(), + spec: getTestSpecWithHTMLChars(), path: "test.yaml", format: "", expected: "&", @@ -145,7 +145,7 @@ func TestSaveToFileFormats(t *testing.T) { func TestSaveToFile_All(t *testing.T) { fs := afero.NewMemMapFs() - err := SaveToFile("test.yaml", "all", getTestSpecWithHtmlChars(), fs) + err := SaveToFile("test.yaml", "all", getTestSpecWithHTMLChars(), fs) require.NoError(t, err) // read yaml file @@ -159,7 +159,7 @@ func TestSaveToFile_All(t *testing.T) { assert.Contains(t, string(data), "&") } -func getTestSpecWithHtmlChars() *Spec { +func getTestSpecWithHTMLChars() *Spec { return &Spec{ Paths: openapi3.NewPaths( openapi3.WithPath( From 3d53b560bbd92d24a40dae30cc0cd392402e489d Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Wed, 5 Mar 2025 18:02:10 +0000 Subject: [PATCH 12/14] Update --- .github/scripts/split_spec.sh | 11 ++++++-- tools/cli/internal/cli/split/split.go | 14 ++++++++-- tools/cli/test/e2e/cli/split_test.go | 40 +++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/.github/scripts/split_spec.sh b/.github/scripts/split_spec.sh index 153bd2361a..9ca934a2f0 100755 --- a/.github/scripts/split_spec.sh +++ b/.github/scripts/split_spec.sh @@ -1,16 +1,21 @@ #!/usr/bin/env bash set -eou pipefail +######################################################### +# Run foas cli to split the openapi file +# Variables: +# target_env - target environment to split the openapi file +######################################################### + echo "Running FOAS CLI versions command" foascli versions -s openapi-foas.json -o ./openapi/v2/versions.json --env "${target_env:?}" --stability-level stable --stability-level preview echo "Running FOAS CLI split command with the following --env=${target_env:?} and -o=./openapi/v2/openapi.json" -foascli split -s openapi-foas.json --env "${target_env:?}" -o ./openapi/v2/openapi.json +foascli split -s openapi-foas.json --env "${target_env:?}" -o ./openapi/v2/openapi.json --format all mv -f "openapi-foas.json" "./openapi/v2.json" - -foascli split -s openapi-foas.yaml --env "${target_env:?}" -o ./openapi/v2/openapi.yaml mv -f "openapi-foas.yaml" "./openapi/v2.yaml" + # Create folder if it does not exist mkdir -p ./openapi/v2/private diff --git a/tools/cli/internal/cli/split/split.go b/tools/cli/internal/cli/split/split.go index 9741fb42bc..79fa687bdc 100644 --- a/tools/cli/internal/cli/split/split.go +++ b/tools/cli/internal/cli/split/split.go @@ -90,10 +90,20 @@ func (o *Opts) saveVersionedOas(oas *openapi3.T, version string) error { path = o.outputPath } - path = strings.Replace(path, "."+o.format, fmt.Sprintf("-%s.%s", version, o.format), 1) + path = getVersionPath(path, version) return openapi.Save(path, oas, o.format, o.fs) } +// getVersionPath replaces file path from 'path/path.to.file/file.' +// to 'path/path.to.file/file-version.' +func getVersionPath(path, version string) string { + extIndex := strings.LastIndex(path, ".") + if extIndex == -1 { + return fmt.Sprintf("%s-%s", path, version) + } + return fmt.Sprintf("%s-%s%s", path[:extIndex], version, path[extIndex:]) +} + func (o *Opts) PreRunE(_ []string) error { if o.basePath == "" { return fmt.Errorf("no OAS detected. Please, use the flag %s to include the base OAS", flag.Base) @@ -128,7 +138,7 @@ func Builder() *cobra.Command { cmd.Flags().StringVarP(&opts.basePath, flag.Spec, flag.SpecShort, "-", usage.Spec) cmd.Flags().StringVar(&opts.env, flag.Environment, "", usage.Environment) cmd.Flags().StringVarP(&opts.outputPath, flag.Output, flag.OutputShort, "", usage.Output) - cmd.Flags().StringVarP(&opts.format, flag.Format, flag.FormatShort, openapi.JSON, usage.Format) + cmd.Flags().StringVarP(&opts.format, flag.Format, flag.FormatShort, openapi.ALL, usage.Format) cmd.Flags().StringVar(&opts.gitSha, flag.GitSha, "", usage.GitSha) _ = cmd.MarkFlagRequired(flag.Output) diff --git a/tools/cli/test/e2e/cli/split_test.go b/tools/cli/test/e2e/cli/split_test.go index 07a95146fb..dc6eec02d9 100755 --- a/tools/cli/test/e2e/cli/split_test.go +++ b/tools/cli/test/e2e/cli/split_test.go @@ -112,6 +112,46 @@ func versionInFuture(t *testing.T, version string) bool { return v.Date().After(time.Now()) } +func TestSplitVersionsFilteredOASes_All(t *testing.T) { + cliPath := NewBin(t) + env := "dev" + folder := env + base := getInputPath(t, "filtered", "json", folder) + jsonOutputPath := getOutputFolder(t, folder) + "/filtered-dev-output.json" + cmd := exec.Command(cliPath, + "split", + "-s", + base, + "-o", + jsonOutputPath, + "--env", + "dev", + "--format", + "all", + ) + + var o, e bytes.Buffer + cmd.Stdout = &o + cmd.Stderr = &e + require.NoError(t, cmd.Run(), e.String()) + + versions := getVersions(t, cliPath, base, folder) + for _, version := range versions { + if slices.Contains(skipVersions, version) { + continue + } + if env == "prod" && !versionInFuture(t, version) { + continue + } + fmt.Printf("Validating version: %s\n", version) + noExtensionOutputPath := strings.Replace(jsonOutputPath, ".json", "", 1) + versionedOutputPath := noExtensionOutputPath + "-" + version + ".json" + ValidateVersionedSpec(t, NewValidAtlasSpecPath(t, version, folder), versionedOutputPath) + versionedOutputPath = noExtensionOutputPath + "-" + version + ".yaml" + ValidateVersionedSpec(t, NewValidAtlasSpecPath(t, version, folder), versionedOutputPath) + } +} + func TestSplitVersionsForOASWithExternalReferences(t *testing.T) { folder := "dev" cliPath := NewBin(t) From 91881d93d1e5d520542e08993c72bd7a5ea36467 Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Wed, 5 Mar 2025 18:02:40 +0000 Subject: [PATCH 13/14] update --- .github/scripts/split_spec.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/scripts/split_spec.sh b/.github/scripts/split_spec.sh index 9ca934a2f0..3daa40ca52 100755 --- a/.github/scripts/split_spec.sh +++ b/.github/scripts/split_spec.sh @@ -1,12 +1,6 @@ #!/usr/bin/env bash set -eou pipefail -######################################################### -# Run foas cli to split the openapi file -# Variables: -# target_env - target environment to split the openapi file -######################################################### - echo "Running FOAS CLI versions command" foascli versions -s openapi-foas.json -o ./openapi/v2/versions.json --env "${target_env:?}" --stability-level stable --stability-level preview From a78f18715cc749095979082904a65d2d3d2efd79 Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Wed, 5 Mar 2025 18:04:29 +0000 Subject: [PATCH 14/14] lint --- tools/cli/internal/cli/split/split.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/cli/internal/cli/split/split.go b/tools/cli/internal/cli/split/split.go index 79fa687bdc..9cb9424554 100644 --- a/tools/cli/internal/cli/split/split.go +++ b/tools/cli/internal/cli/split/split.go @@ -94,8 +94,8 @@ func (o *Opts) saveVersionedOas(oas *openapi3.T, version string) error { return openapi.Save(path, oas, o.format, o.fs) } -// getVersionPath replaces file path from 'path/path.to.file/file.' -// to 'path/path.to.file/file-version.' +// getVersionPath replaces file path with version. +// Example: 'path/path.to.file/file.' to 'path/path.to.file/file-version.'. func getVersionPath(path, version string) string { extIndex := strings.LastIndex(path, ".") if extIndex == -1 {