From a574235c0afba162e45fcaff8a24eac2771103f9 Mon Sep 17 00:00:00 2001 From: Reuven Harrison Date: Thu, 8 Jun 2023 19:14:44 +0300 Subject: [PATCH] Move open api spec info to load (#289) --- checker/checker.go | 12 --------- checker/checker_breaking_test.go | 8 +++--- checker/checker_deprecation_test.go | 4 +-- checker/composed_test.go | 16 +++++------ diff/diff.go | 10 +++---- diff/diff_test.go | 16 +++++------ diff/example_test.go | 8 +++--- internal/run.go | 5 ++-- lint/checker.go | 4 +-- lint/checker_test.go | 4 +-- lint/info.go | 2 +- lint/path_params.go | 2 +- lint/required_params.go | 2 +- lint/shcema_checker.go | 2 +- load/load.go | 24 ----------------- load/spec_info.go | 41 +++++++++++++++++++++++++++++ 16 files changed, 82 insertions(+), 78 deletions(-) create mode 100644 load/spec_info.go diff --git a/checker/checker.go b/checker/checker.go index ca46491d..d3b8db3f 100644 --- a/checker/checker.go +++ b/checker/checker.go @@ -11,7 +11,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/tufin/oasdiff/checker/localizations" "github.com/tufin/oasdiff/diff" - "github.com/tufin/oasdiff/load" ) type Level int @@ -390,14 +389,3 @@ func (diffBC *BCDiff) AddRequestPropertiesDiff(path string, operation string, me } return mediaTypeBCDiff.SchemaDiff.PropertiesDiff } - -// LoadOpenAPISpecInfoFromFile loads a LoadOpenAPISpecInfoFromFile from a local file path -func LoadOpenAPISpecInfoFromFile(loader load.Loader, location string) (*load.OpenAPISpecInfo, error) { - s, err := loader.LoadFromFile(location) - return &load.OpenAPISpecInfo{Spec: s, Url: location}, err -} - -func LoadOpenAPISpecInfo(loader load.Loader, location string) (*load.OpenAPISpecInfo, error) { - s, err := load.From(loader, location) - return &load.OpenAPISpecInfo{Spec: s, Url: location}, err -} diff --git a/checker/checker_breaking_test.go b/checker/checker_breaking_test.go index 6a4b5736..a1205217 100644 --- a/checker/checker_breaking_test.go +++ b/checker/checker_breaking_test.go @@ -18,12 +18,12 @@ const ( installCommandPath = "/api/{domain}/{project}/install-command" ) -func l(t *testing.T, v int) load.OpenAPISpecInfo { +func l(t *testing.T, v int) load.SpecInfo { t.Helper() loader := openapi3.NewLoader() oas, err := loader.LoadFromFile(fmt.Sprintf("../data/openapi-test%d.yaml", v)) require.NoError(t, err) - return load.OpenAPISpecInfo{Spec: oas, Url: fmt.Sprintf("../data/openapi-test%d.yaml", v)} + return load.SpecInfo{Spec: oas, Url: fmt.Sprintf("../data/openapi-test%d.yaml", v)} } func d(t *testing.T, config *diff.Config, v1, v2 int) []checker.BackwardCompatibilityError { @@ -143,8 +143,8 @@ func TestBreaking_PathParamRename(t *testing.T) { require.NoError(t, err) d, osm, err := diff.GetWithOperationsSourcesMap(getConfig(), - &load.OpenAPISpecInfo{Spec: s1}, - &load.OpenAPISpecInfo{Spec: s2}, + &load.SpecInfo{Spec: s1}, + &load.SpecInfo{Spec: s2}, ) require.NoError(t, err) errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) diff --git a/checker/checker_deprecation_test.go b/checker/checker_deprecation_test.go index 6ddb1abd..e32ccfad 100644 --- a/checker/checker_deprecation_test.go +++ b/checker/checker_deprecation_test.go @@ -15,8 +15,8 @@ import ( "github.com/tufin/oasdiff/load" ) -func open(file string) (*load.OpenAPISpecInfo, error) { - return checker.LoadOpenAPISpecInfoFromFile(openapi3.NewLoader(), file) +func open(file string) (*load.SpecInfo, error) { + return load.LoadSpecInfoFromFile(openapi3.NewLoader(), file) } func getDeprecationFile(file string) string { diff --git a/checker/composed_test.go b/checker/composed_test.go index 50632843..58fa0f3d 100644 --- a/checker/composed_test.go +++ b/checker/composed_test.go @@ -10,20 +10,20 @@ import ( "github.com/tufin/oasdiff/load" ) -func loadFrom(t *testing.T, prefix string, v int) load.OpenAPISpecInfo { +func loadFrom(t *testing.T, prefix string, v int) load.SpecInfo { path := fmt.Sprintf(prefix+"spec%d.yaml", v) loader := openapi3.NewLoader() oas, err := loader.LoadFromFile(path) require.NoError(t, err) - return load.OpenAPISpecInfo{Spec: oas, Url: path} + return load.SpecInfo{Spec: oas, Url: path} } func TestComposed_Empty(t *testing.T) { - s1 := []load.OpenAPISpecInfo{ + s1 := []load.SpecInfo{ loadFrom(t, "../data/composed/base/", 1), } - s2 := []load.OpenAPISpecInfo{ + s2 := []load.SpecInfo{ loadFrom(t, "../data/composed/base/", 1), } @@ -34,12 +34,12 @@ func TestComposed_Empty(t *testing.T) { } func TestComposed_Duplicate(t *testing.T) { - s1 := []load.OpenAPISpecInfo{ + s1 := []load.SpecInfo{ loadFrom(t, "../data/composed/base/", 1), loadFrom(t, "../data/composed/base/", 1), } - s2 := []load.OpenAPISpecInfo{} + s2 := []load.SpecInfo{} config := diff.NewConfig() _, _, err := diff.GetPathsDiff(config, s1, s2) @@ -47,12 +47,12 @@ func TestComposed_Duplicate(t *testing.T) { } func TestComposed_CompareMostRecent(t *testing.T) { - s1 := []load.OpenAPISpecInfo{ + s1 := []load.SpecInfo{ loadFrom(t, "../data/composed/base/", 1), loadFrom(t, "../data/composed/base/", 2), } - s2 := []load.OpenAPISpecInfo{ + s2 := []load.SpecInfo{ loadFrom(t, "../data/composed/revision/", 1), loadFrom(t, "../data/composed/revision/", 2), } diff --git a/diff/diff.go b/diff/diff.go index 1b22e6c6..78d11451 100644 --- a/diff/diff.go +++ b/diff/diff.go @@ -80,17 +80,17 @@ Note that GetWithOperationsSourcesMap expects OpenAPI References (https://swagge References are normally resolved automatically when you load the spec. In other cases you can resolve refs using https://pkg.go.dev/github.com/getkin/kin-openapi/openapi3#Loader.ResolveRefsIn. */ -func GetWithOperationsSourcesMap(config *Config, s1, s2 *load.OpenAPISpecInfo) (*Diff, *OperationsSourcesMap, error) { +func GetWithOperationsSourcesMap(config *Config, s1, s2 *load.SpecInfo) (*Diff, *OperationsSourcesMap, error) { diff, err := getDiff(config, newState(), s1.Spec, s2.Spec) if err != nil { return nil, nil, err } - _, operationsSources1, err := mergedPaths([]load.OpenAPISpecInfo{*s1}, config.MatchPathParams) + _, operationsSources1, err := mergedPaths([]load.SpecInfo{*s1}, config.MatchPathParams) if err != nil { return nil, nil, err } - _, operationsSources2, err := mergedPaths([]load.OpenAPISpecInfo{*s2}, config.MatchPathParams) + _, operationsSources2, err := mergedPaths([]load.SpecInfo{*s2}, config.MatchPathParams) if err != nil { return nil, nil, err } @@ -115,7 +115,7 @@ Note that Get expects OpenAPI References (https://swagger.io/docs/specification/ References are normally resolved automatically when you load the spec. In other cases you can resolve refs using https://pkg.go.dev/github.com/getkin/kin-openapi/openapi3#Loader.ResolveRefsIn. */ -func GetPathsDiff(config *Config, s1, s2 []load.OpenAPISpecInfo) (*Diff, *OperationsSourcesMap, error) { +func GetPathsDiff(config *Config, s1, s2 []load.SpecInfo) (*Diff, *OperationsSourcesMap, error) { state := newState() result := newDiff() var err error @@ -155,7 +155,7 @@ func getPathItem(paths openapi3.Paths, path string, matchPathParams bool) *opena return paths.Find(path) } -func mergedPaths(s1 []load.OpenAPISpecInfo, matchPathParams bool) (*openapi3.Paths, *OperationsSourcesMap, error) { +func mergedPaths(s1 []load.SpecInfo, matchPathParams bool) (*openapi3.Paths, *OperationsSourcesMap, error) { result := make(openapi3.Paths, 0) operationsSources := make(OperationsSourcesMap) for _, s := range s1 { diff --git a/diff/diff_test.go b/diff/diff_test.go index 8f910d89..e9e19bcb 100644 --- a/diff/diff_test.go +++ b/diff/diff_test.go @@ -736,10 +736,10 @@ func TestDiff_PathParamInMethodRenamed(t *testing.T) { require.NoError(t, err) d, _, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), - &load.OpenAPISpecInfo{ + &load.SpecInfo{ Spec: s1, }, - &load.OpenAPISpecInfo{ + &load.SpecInfo{ Spec: s2, }) require.NoError(t, err) @@ -759,10 +759,10 @@ func TestDiff_PathParamInOperationRenamed(t *testing.T) { require.NoError(t, err) d, _, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), - &load.OpenAPISpecInfo{ + &load.SpecInfo{ Spec: s1, }, - &load.OpenAPISpecInfo{ + &load.SpecInfo{ Spec: s2, }) require.NoError(t, err) @@ -782,10 +782,10 @@ func TestDiff_TwoPathParamsRenamed(t *testing.T) { require.NoError(t, err) d, _, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), - &load.OpenAPISpecInfo{ + &load.SpecInfo{ Spec: s1, }, - &load.OpenAPISpecInfo{ + &load.SpecInfo{ Spec: s2, }) require.NoError(t, err) @@ -809,10 +809,10 @@ func TestDiff_TwoPathParamsOneRenamed(t *testing.T) { require.NoError(t, err) d, _, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), - &load.OpenAPISpecInfo{ + &load.SpecInfo{ Spec: s1, }, - &load.OpenAPISpecInfo{ + &load.SpecInfo{ Spec: s2, }) require.NoError(t, err) diff --git a/diff/example_test.go b/diff/example_test.go index 9f895e1b..8aac3c0c 100644 --- a/diff/example_test.go +++ b/diff/example_test.go @@ -65,13 +65,13 @@ func ExampleGetPathsDiff() { loader := openapi3.NewLoader() loader.IsExternalRefsAllowed = true - s1, err := checker.LoadOpenAPISpecInfo(loader, "../data/openapi-test1.yaml") + s1, err := load.LoadSpecInfo(loader, "../data/openapi-test1.yaml") if err != nil { fmt.Fprintf(os.Stderr, "failed to load spec with %v", err) return } - s2, err := checker.LoadOpenAPISpecInfo(loader, "../data/openapi-test3.yaml") + s2, err := load.LoadSpecInfo(loader, "../data/openapi-test3.yaml") if err != nil { fmt.Fprintf(os.Stderr, "failed to load spec with %v", err) return @@ -80,8 +80,8 @@ func ExampleGetPathsDiff() { diffConfig := diff.NewConfig().WithCheckBreaking() diffRes, operationsSources, err := diff.GetPathsDiff(diffConfig, - []load.OpenAPISpecInfo{*s1}, - []load.OpenAPISpecInfo{*s2}, + []load.SpecInfo{*s1}, + []load.SpecInfo{*s2}, ) if err != nil { diff --git a/internal/run.go b/internal/run.go index dc162b53..2746109b 100644 --- a/internal/run.go +++ b/internal/run.go @@ -6,7 +6,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/tufin/oasdiff/build" - "github.com/tufin/oasdiff/checker" "github.com/tufin/oasdiff/diff" "github.com/tufin/oasdiff/load" ) @@ -84,11 +83,11 @@ func runInternal(args []string, stdout io.Writer, stderr io.Writer) (bool, *Retu } func normalDiff(loader load.Loader, base, revision string, config *diff.Config) (*diff.Diff, *diff.OperationsSourcesMap, *ReturnError) { - s1, err := checker.LoadOpenAPISpecInfo(loader, base) + s1, err := load.LoadSpecInfo(loader, base) if err != nil { return nil, nil, getErrFailedToLoadSpec("base", base, err) } - s2, err := checker.LoadOpenAPISpecInfo(loader, revision) + s2, err := load.LoadSpecInfo(loader, revision) if err != nil { return nil, nil, getErrFailedToLoadSpec("revision", revision, err) } diff --git a/lint/checker.go b/lint/checker.go index 9d4bb0d8..247b6838 100644 --- a/lint/checker.go +++ b/lint/checker.go @@ -11,7 +11,7 @@ const ( LEVEL_WARN = 1 ) -type Check func(string, *load.OpenAPISpecInfo) []*Error +type Check func(string, *load.SpecInfo) []*Error type Error struct { Id string `json:"id,omitempty" yaml:"id,omitempty"` @@ -48,7 +48,7 @@ func (e Errors) Swap(i, j int) { e[i], e[j] = e[j], e[i] } -func Run(config Config, source string, spec *load.OpenAPISpecInfo) Errors { +func Run(config Config, source string, spec *load.SpecInfo) Errors { result := make(Errors, 0) if spec == nil { diff --git a/lint/checker_test.go b/lint/checker_test.go index 13e83163..95de2e35 100644 --- a/lint/checker_test.go +++ b/lint/checker_test.go @@ -9,13 +9,13 @@ import ( "github.com/tufin/oasdiff/load" ) -func loadFrom(t *testing.T, path string) *load.OpenAPISpecInfo { +func loadFrom(t *testing.T, path string) *load.SpecInfo { t.Helper() loader := openapi3.NewLoader() oas, err := loader.LoadFromFile(path) require.NoError(t, err) - return &load.OpenAPISpecInfo{Spec: oas, Url: path} + return &load.SpecInfo{Spec: oas, Url: path} } func TestRun(t *testing.T) { diff --git a/lint/info.go b/lint/info.go index 04dff3b3..7aa8fce3 100644 --- a/lint/info.go +++ b/lint/info.go @@ -9,7 +9,7 @@ import ( // InfoCheck based on REQUIRED fields (Version and Info) from swagger docs, // see: https://swagger.io/docs/specification/api-general-info/ -func InfoCheck(source string, spec *load.OpenAPISpecInfo) []*Error { +func InfoCheck(source string, spec *load.SpecInfo) []*Error { result := make([]*Error, 0) diff --git a/lint/path_params.go b/lint/path_params.go index 90af4fd2..271f643b 100644 --- a/lint/path_params.go +++ b/lint/path_params.go @@ -8,7 +8,7 @@ import ( "github.com/tufin/oasdiff/utils" ) -func PathParamsCheck(source string, s *load.OpenAPISpecInfo) []*Error { +func PathParamsCheck(source string, s *load.SpecInfo) []*Error { result := make([]*Error, 0) if s == nil || s.Spec == nil { diff --git a/lint/required_params.go b/lint/required_params.go index 8f877afb..581d445c 100644 --- a/lint/required_params.go +++ b/lint/required_params.go @@ -7,7 +7,7 @@ import ( "github.com/tufin/oasdiff/load" ) -func RequiredParamsCheck(source string, s *load.OpenAPISpecInfo) []*Error { +func RequiredParamsCheck(source string, s *load.SpecInfo) []*Error { result := make([]*Error, 0) if s == nil || s.Spec == nil { diff --git a/lint/shcema_checker.go b/lint/shcema_checker.go index 7a3fa664..63b33da6 100644 --- a/lint/shcema_checker.go +++ b/lint/shcema_checker.go @@ -20,7 +20,7 @@ func newState(source string) *state { } } -func SchemaCheck(source string, spec *load.OpenAPISpecInfo) []*Error { +func SchemaCheck(source string, spec *load.SpecInfo) []*Error { result := make([]*Error, 0) if spec == nil || spec.Spec == nil { diff --git a/load/load.go b/load/load.go index 22ac8af8..7f1fe159 100644 --- a/load/load.go +++ b/load/load.go @@ -4,7 +4,6 @@ import ( "net/url" "github.com/getkin/kin-openapi/openapi3" - "github.com/yargevad/filepathx" ) // Loader interface includes the OAS load functions @@ -25,29 +24,6 @@ func From(loader Loader, path string) (*openapi3.T, error) { return loader.LoadFromFile(path) } -type OpenAPISpecInfo struct { - Url string - Spec *openapi3.T -} - -// FromGlob is a convenience function that opens OpenAPI specs from local files matching the specified glob parameter -func FromGlob(loader Loader, glob string) ([]OpenAPISpecInfo, error) { - files, err := filepathx.Glob(glob) - if err != nil { - return nil, err - } - result := make([]OpenAPISpecInfo, 0) - for _, file := range files { - spec, err := loader.LoadFromFile(file) - if err != nil { - return nil, err - } - result = append(result, OpenAPISpecInfo{Url: file, Spec: spec}) - } - - return result, nil -} - func loadFromURI(loader Loader, uri *url.URL) (*openapi3.T, error) { oas, err := loader.LoadFromURI(uri) if err != nil { diff --git a/load/spec_info.go b/load/spec_info.go new file mode 100644 index 00000000..4f08e456 --- /dev/null +++ b/load/spec_info.go @@ -0,0 +1,41 @@ +package load + +import ( + "github.com/getkin/kin-openapi/openapi3" + "github.com/yargevad/filepathx" +) + +type SpecInfo struct { + Url string + Spec *openapi3.T +} + +// LoadSpecInfoFromFile creates a SpecInfo from a local file path +func LoadSpecInfoFromFile(loader Loader, location string) (*SpecInfo, error) { + s, err := loader.LoadFromFile(location) + return &SpecInfo{Spec: s, Url: location}, err +} + +// LoadSpecInfo creates a SpecInfo from a local file path or a URL +func LoadSpecInfo(loader Loader, location string) (*SpecInfo, error) { + s, err := From(loader, location) + return &SpecInfo{Spec: s, Url: location}, err +} + +// FromGlob creates SpecInfo specs from local files matching the specified glob parameter +func FromGlob(loader Loader, glob string) ([]SpecInfo, error) { + files, err := filepathx.Glob(glob) + if err != nil { + return nil, err + } + result := make([]SpecInfo, 0) + for _, file := range files { + spec, err := loader.LoadFromFile(file) + if err != nil { + return nil, err + } + result = append(result, SpecInfo{Url: file, Spec: spec}) + } + + return result, nil +}