Skip to content

Commit

Permalink
abstract path/stdin behind source
Browse files Browse the repository at this point in the history
  • Loading branch information
Reuven committed Oct 7, 2023
1 parent 36582ab commit 8db77c6
Show file tree
Hide file tree
Showing 17 changed files with 96 additions and 56 deletions.
2 changes: 1 addition & 1 deletion checker/checker_deprecation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
)

func open(file string) (*load.SpecInfo, error) {
return load.LoadSpecInfo(openapi3.NewLoader(), file)
return load.LoadSpecInfo(openapi3.NewLoader(), load.GetSource(file))
}

func getDeprecationFile(file string) string {
Expand Down
4 changes: 2 additions & 2 deletions diff/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ func ExampleGetPathsDiff() {
loader := openapi3.NewLoader()
loader.IsExternalRefsAllowed = true

s1, err := load.LoadSpecInfo(loader, "../data/openapi-test1.yaml")
s1, err := load.LoadSpecInfo(loader, load.GetSource("../data/openapi-test1.yaml"))
if err != nil {
fmt.Fprintf(os.Stderr, "failed to load spec with %v", err)
return
}

s2, err := load.LoadSpecInfo(loader, "../data/openapi-test3.yaml")
s2, err := load.LoadSpecInfo(loader, load.GetSource("../data/openapi-test3.yaml"))
if err != nil {
fmt.Fprintf(os.Stderr, "failed to load spec with %v", err)
return
Expand Down
5 changes: 3 additions & 2 deletions internal/breaking_changes.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/spf13/cobra"
"github.com/tufin/oasdiff/checker"
"github.com/tufin/oasdiff/diff"
"github.com/tufin/oasdiff/load"
)

func getBreakingChangesCmd() *cobra.Command {
Expand All @@ -22,8 +23,8 @@ In 'composed' mode, base and revision can be a glob and oasdiff will compare mat
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {

flags.base = args[0]
flags.revision = args[1]
flags.base = load.GetSource(args[0])
flags.revision = load.GetSource(args[1])

// by now flags have been parsed successfully so we don't need to show usage on any errors
cmd.Root().SilenceUsage = true
Expand Down
5 changes: 3 additions & 2 deletions internal/changelog.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/spf13/cobra"
"github.com/tufin/oasdiff/checker"
"github.com/tufin/oasdiff/diff"
"github.com/tufin/oasdiff/load"
)

func getChangelogCmd() *cobra.Command {
Expand All @@ -24,8 +25,8 @@ In 'composed' mode, base and revision can be a glob and oasdiff will compare mat
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {

flags.base = args[0]
flags.revision = args[1]
flags.base = load.GetSource(args[0])
flags.revision = load.GetSource(args[1])

// by now flags have been parsed successfully so we don't need to show usage on any errors
cmd.Root().SilenceUsage = true
Expand Down
9 changes: 5 additions & 4 deletions internal/changelog_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package internal

import (
"github.com/tufin/oasdiff/diff"
"github.com/tufin/oasdiff/load"
)

type ChangelogFlags struct {
base string
revision string
base load.Source
revision load.Source
composed bool
prefixBase string
prefixRevision string
Expand Down Expand Up @@ -45,11 +46,11 @@ func (flags *ChangelogFlags) getComposed() bool {
return flags.composed
}

func (flags *ChangelogFlags) getBase() string {
func (flags *ChangelogFlags) getBase() load.Source {
return flags.base
}

func (flags *ChangelogFlags) getRevision() string {
func (flags *ChangelogFlags) getRevision() load.Source {
return flags.revision
}

Expand Down
26 changes: 13 additions & 13 deletions internal/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ In 'composed' mode, base and revision can be a glob and oasdiff will compare mat
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {

flags.base = args[0]
flags.revision = args[1]
flags.base = load.GetSource(args[0])
flags.revision = load.GetSource(args[1])

// by now flags have been parsed successfully so we don't need to show usage on any errors
cmd.Root().SilenceUsage = true
Expand Down Expand Up @@ -131,17 +131,17 @@ func normalDiff(loader load.Loader, flags Flags) (*diff.Diff, *diff.OperationsSo
return nil, nil, getErrFailedToLoadSpec("revision", flags.getRevision(), err)
}

if flags.getBase() == "-" && flags.getRevision() == "-" {
if flags.getBase().Stdin && flags.getRevision().Stdin {
// io.ReadAll can only read stdin once, so in this edge case, we copy base into revision
s2.Spec = s1.Spec
}

if flags.getFlatten() {
if err := mergeAllOf("base", []*load.SpecInfo{s1}); err != nil {
if err := mergeAllOf("base", []*load.SpecInfo{s1}, flags.getBase()); err != nil {
return nil, nil, err
}

if err := mergeAllOf("revision", []*load.SpecInfo{s2}); err != nil {
if err := mergeAllOf("revision", []*load.SpecInfo{s2}, flags.getRevision()); err != nil {
return nil, nil, err
}
}
Expand All @@ -155,22 +155,22 @@ func normalDiff(loader load.Loader, flags Flags) (*diff.Diff, *diff.OperationsSo
}

func composedDiff(loader load.Loader, flags Flags) (*diff.Diff, *diff.OperationsSourcesMap, *ReturnError) {
s1, err := load.FromGlob(loader, flags.getBase())
s1, err := load.FromGlob(loader, flags.getBase().Path)
if err != nil {
return nil, nil, getErrFailedToLoadSpecs("base", flags.getBase(), err)
return nil, nil, getErrFailedToLoadSpecs("base", flags.getBase().Path, err)
}

s2, err := load.FromGlob(loader, flags.getRevision())
s2, err := load.FromGlob(loader, flags.getRevision().Path)
if err != nil {
return nil, nil, getErrFailedToLoadSpecs("revision", flags.getRevision(), err)
return nil, nil, getErrFailedToLoadSpecs("revision", flags.getRevision().Path, err)
}

if flags.getFlatten() {
if err := mergeAllOf("base", s1); err != nil {
if err := mergeAllOf("base", s1, flags.getBase()); err != nil {
return nil, nil, err
}

if err := mergeAllOf("revision", s2); err != nil {
if err := mergeAllOf("revision", s2, flags.getRevision()); err != nil {
return nil, nil, err
}
}
Expand All @@ -183,13 +183,13 @@ func composedDiff(loader load.Loader, flags Flags) (*diff.Diff, *diff.Operations
return diffReport, operationsSources, nil
}

func mergeAllOf(title string, specInfos []*load.SpecInfo) *ReturnError {
func mergeAllOf(title string, specInfos []*load.SpecInfo, source load.Source) *ReturnError {

var err error

for _, specInfo := range specInfos {
if specInfo.Spec, err = flatten.MergeSpec(specInfo.Spec); err != nil {
return getErrFailedToFlattenSpec(title, specInfo.Url, err)
return getErrFailedToFlattenSpec(title, source, err)
}
}

Expand Down
9 changes: 5 additions & 4 deletions internal/diff_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package internal

import (
"github.com/tufin/oasdiff/diff"
"github.com/tufin/oasdiff/load"
)

type DiffFlags struct {
base string
revision string
base load.Source
revision load.Source
composed bool
prefixBase string
prefixRevision string
Expand Down Expand Up @@ -39,11 +40,11 @@ func (flags *DiffFlags) getComposed() bool {
return flags.composed
}

func (flags *DiffFlags) getBase() string {
func (flags *DiffFlags) getBase() load.Source {
return flags.base
}

func (flags *DiffFlags) getRevision() string {
func (flags *DiffFlags) getRevision() load.Source {
return flags.revision
}

Expand Down
20 changes: 16 additions & 4 deletions internal/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package internal

import (
"fmt"

"github.com/tufin/oasdiff/load"
)

type ReturnError struct {
Expand All @@ -16,9 +18,14 @@ func getErrInvalidFlags(err error) *ReturnError {
}
}

func getErrFailedToLoadSpec(what string, path string, err error) *ReturnError {
func getErrFailedToLoadSpec(what string, source load.Source, err error) *ReturnError {
pathStr := source.Path
if !source.Stdin {
pathStr = fmt.Sprintf("%q", source.Path)
}

return &ReturnError{
error: fmt.Errorf("failed to load %s spec from %q with %v", what, path, err),
error: fmt.Errorf("failed to load %s spec from %s with %v", what, pathStr, err),
Code: 102,
}
}
Expand Down Expand Up @@ -65,9 +72,14 @@ func getErrCantProcessIgnoreFile(what string, err error) *ReturnError {
}
}

func getErrFailedToFlattenSpec(what string, path string, err error) *ReturnError {
func getErrFailedToFlattenSpec(what string, source load.Source, err error) *ReturnError {
pathStr := source.Path
if !source.Stdin {
pathStr = fmt.Sprintf("%q", source.Path)
}

return &ReturnError{
error: fmt.Errorf("failed to flatten %s spec from %q with %v", what, path, err),
error: fmt.Errorf("failed to flatten %s spec from %s with %v", what, pathStr, err),
Code: 102,
}
}
9 changes: 6 additions & 3 deletions internal/flags.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package internal

import "github.com/tufin/oasdiff/diff"
import (
"github.com/tufin/oasdiff/diff"
"github.com/tufin/oasdiff/load"
)

type Flags interface {
toConfig() *diff.Config

getComposed() bool
getBase() string
getRevision() string
getBase() load.Source
getRevision() load.Source
getFlatten() bool
}
8 changes: 4 additions & 4 deletions internal/flatten.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Spec can be a path to a file, a URL or '-' to read standard input.
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {

flags.spec = args[0]
flags.source = load.GetSource(args[0])

// by now flags have been parsed successfully so we don't need to show usage on any errors
cmd.Root().SilenceUsage = true
Expand All @@ -49,17 +49,17 @@ func runFlatten(flags *FlattenFlags, stdout io.Writer) *ReturnError {

loader := openapi3.NewLoader()
loader.IsExternalRefsAllowed = true
spec, err := load.LoadSpecInfo(loader, flags.spec)
spec, err := load.LoadSpecInfo(loader, flags.source)
if err != nil {
return getErrFailedToLoadSpec("original", flags.spec, err)
return getErrFailedToLoadSpec("original", flags.source, err)
}

// TODO: get the original format of the spec
format := flags.format

flatSpec, err := flatten.MergeSpec(spec.Spec)
if err != nil {
return getErrFailedToFlattenSpec("original", flags.spec, err)
return getErrFailedToFlattenSpec("original", flags.source, err)
}

if returnErr := outputFlattenedSpec(format, stdout, flatSpec); returnErr != nil {
Expand Down
4 changes: 3 additions & 1 deletion internal/flatten_flags.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package internal

import "github.com/tufin/oasdiff/load"

type FlattenFlags struct {
spec string
source load.Source
format string
circularReferenceCounter int
}
5 changes: 3 additions & 2 deletions internal/summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/getkin/kin-openapi/openapi3"
"github.com/spf13/cobra"
"github.com/tufin/oasdiff/diff"
"github.com/tufin/oasdiff/load"
)

func getSummaryCmd() *cobra.Command {
Expand All @@ -21,8 +22,8 @@ In 'composed' mode, base and revision can be a glob and oasdiff will compare mat
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {

flags.base = args[0]
flags.revision = args[1]
flags.base = load.GetSource(args[0])
flags.revision = load.GetSource(args[1])

// by now flags have been parsed successfully so we don't need to show usage on any errors
cmd.Root().SilenceUsage = true
Expand Down
9 changes: 4 additions & 5 deletions load/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,18 @@ type Loader interface {
}

// From is a convenience function that opens an OpenAPI spec from a URL or a local path based on the format of the path parameter
func From(loader Loader, path string) (*openapi3.T, error) {
func From(loader Loader, source Source) (*openapi3.T, error) {

if path == "-" {
if source.Stdin {
return loader.LoadFromStdin()
}

uri, err := url.ParseRequestURI(path)
uri, err := url.ParseRequestURI(source.Path)
if err == nil {
return loadFromURI(loader, uri)
}

// return loader.LoadFromURI(&url.URL{Path: filepath.ToSlash(path)})
return loader.LoadFromFile(path)
return loader.LoadFromFile(source.Path)
}

func loadFromURI(loader Loader, uri *url.URL) (*openapi3.T, error) {
Expand Down
8 changes: 4 additions & 4 deletions load/load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ func (mockLoader MockLoader) LoadFromStdin() (*openapi3.T, error) {
type MockLoader struct{}

func TestLoad_File(t *testing.T) {
_, err := load.From(MockLoader{}, "openapi-test1.yaml")
_, err := load.From(MockLoader{}, load.GetSource("openapi-test1.yaml"))
require.NoError(t, err)
}

func TestLoad_URI(t *testing.T) {
_, err := load.From(MockLoader{}, "http://localhost/openapi-test1.yaml")
_, err := load.From(MockLoader{}, load.GetSource("http://localhost/openapi-test1.yaml"))
require.NoError(t, err)
}

func TestLoad_URIError(t *testing.T) {
_, err := load.From(MockLoader{}, "http://localhost/null")
_, err := load.From(MockLoader{}, load.GetSource("http://localhost/null"))
require.Error(t, err)
}

Expand Down Expand Up @@ -74,6 +74,6 @@ paths:
defer func() { os.Stdin = oldStdin }() // Restore original Stdin

os.Stdin = tmpfile
_, err = load.From(MockLoader{}, "-")
_, err = load.From(MockLoader{}, load.GetSource("-"))
require.NoError(t, err)
}
19 changes: 19 additions & 0 deletions load/source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package load

type Source struct {
Path string
Stdin bool
}

func GetSource(path string) Source {
stdin := path == "-"
if stdin {
path = "stdin"
}

return Source{
Path: path,
Stdin: stdin,
}

}
Loading

0 comments on commit 8db77c6

Please sign in to comment.