Working through windows support

This commit is contained in:
quobix
2024-01-14 17:36:39 -05:00
parent f4647af7b4
commit e699968768
11 changed files with 424 additions and 158 deletions

View File

@@ -8,6 +8,7 @@ import (
"fmt" "fmt"
"net/url" "net/url"
"path/filepath" "path/filepath"
"regexp"
"strings" "strings"
"github.com/pb33f/libopenapi/utils" "github.com/pb33f/libopenapi/utils"
@@ -15,6 +16,8 @@ import (
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
var windowsDriveDetector = regexp.MustCompile(`^([a-zA-Z]:)`)
// ExtractRefs will return a deduplicated slice of references for every unique ref found in the document. // ExtractRefs will return a deduplicated slice of references for every unique ref found in the document.
// The total number of refs, will generally be much higher, you can extract those from GetRawReferenceCount() // The total number of refs, will generally be much higher, you can extract those from GetRawReferenceCount()
func (index *SpecIndex) ExtractRefs(node, parent *yaml.Node, seenPath []string, level int, poly bool, pName string) []*Reference { func (index *SpecIndex) ExtractRefs(node, parent *yaml.Node, seenPath []string, level int, poly bool, pName string) []*Reference {
@@ -236,9 +239,16 @@ func (index *SpecIndex) ExtractRefs(node, parent *yaml.Node, seenPath []string,
} else { } else {
// if the index has a base URL, use that to resolve the path. // if the index has a base URL, use that to resolve the path.
if index.config.BaseURL != nil && !filepath.IsAbs(defRoot) { if index.config.BaseURL != nil && !filepath.IsAbs(defRoot) {
u := *index.config.BaseURL var u url.URL
if strings.HasPrefix(defRoot, "http") {
up, _ := url.Parse(defRoot)
up.Path = utils.ReplaceWindowsDriveWithLinuxPath(filepath.Dir(up.Path))
u = *up
} else {
u = *index.config.BaseURL
}
abs, _ := filepath.Abs(filepath.Join(u.Path, uri[0])) abs, _ := filepath.Abs(filepath.Join(u.Path, uri[0]))
u.Path = abs u.Path = utils.ReplaceWindowsDriveWithLinuxPath(abs)
fullDefinitionPath = fmt.Sprintf("%s#/%s", u.String(), uri[1]) fullDefinitionPath = fmt.Sprintf("%s#/%s", u.String(), uri[1])
componentName = fmt.Sprintf("#/%s", uri[1]) componentName = fmt.Sprintf("#/%s", uri[1])
@@ -265,6 +275,7 @@ func (index *SpecIndex) ExtractRefs(node, parent *yaml.Node, seenPath []string,
u, _ := url.Parse(defRoot) u, _ := url.Parse(defRoot)
pathDir := filepath.Dir(u.Path) pathDir := filepath.Dir(u.Path)
pathAbs, _ := filepath.Abs(filepath.Join(pathDir, uri[0])) pathAbs, _ := filepath.Abs(filepath.Join(pathDir, uri[0]))
pathAbs = utils.ReplaceWindowsDriveWithLinuxPath(pathAbs)
u.Path = pathAbs u.Path = pathAbs
fullDefinitionPath = u.String() fullDefinitionPath = u.String()
} }
@@ -284,6 +295,7 @@ func (index *SpecIndex) ExtractRefs(node, parent *yaml.Node, seenPath []string,
u := *index.config.BaseURL u := *index.config.BaseURL
abs := filepath.Join(u.Path, uri[0]) abs := filepath.Join(u.Path, uri[0])
abs = utils.ReplaceWindowsDriveWithLinuxPath(abs)
u.Path = abs u.Path = abs
fullDefinitionPath = u.String() fullDefinitionPath = u.String()
componentName = uri[0] componentName = uri[0]

View File

@@ -501,6 +501,7 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
} }
value := node.Content[i+1].Value value := node.Content[i+1].Value
value = strings.ReplaceAll(value, "\\\\", "\\")
var locatedRef *Reference var locatedRef *Reference
var fullDef string var fullDef string
var definition string var definition string
@@ -523,7 +524,7 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
u, _ := url.Parse(httpExp[0]) u, _ := url.Parse(httpExp[0])
abs, _ := filepath.Abs(filepath.Join(filepath.Dir(u.Path), exp[0])) abs, _ := filepath.Abs(filepath.Join(filepath.Dir(u.Path), exp[0]))
u.Path = abs u.Path = utils.ReplaceWindowsDriveWithLinuxPath(abs)
u.Fragment = "" u.Fragment = ""
fullDef = fmt.Sprintf("%s#/%s", u.String(), exp[1]) fullDef = fmt.Sprintf("%s#/%s", u.String(), exp[1])
@@ -534,6 +535,7 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
// extract the location of the ref and build a full def path. // extract the location of the ref and build a full def path.
abs, _ := filepath.Abs(filepath.Join(filepath.Dir(fileDef[0]), exp[0])) abs, _ := filepath.Abs(filepath.Join(filepath.Dir(fileDef[0]), exp[0]))
//abs = utils.ReplaceWindowsDriveWithLinuxPath(abs)
fullDef = fmt.Sprintf("%s#/%s", abs, exp[1]) fullDef = fmt.Sprintf("%s#/%s", abs, exp[1])
} }
@@ -577,7 +579,7 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
if strings.HasPrefix(fileDef[0], "http") { if strings.HasPrefix(fileDef[0], "http") {
u, _ := url.Parse(fileDef[0]) u, _ := url.Parse(fileDef[0])
path, _ := filepath.Abs(filepath.Join(filepath.Dir(u.Path), exp[0])) path, _ := filepath.Abs(filepath.Join(filepath.Dir(u.Path), exp[0]))
u.Path = path u.Path = utils.ReplaceWindowsDriveWithLinuxPath(path)
fullDef = u.String() fullDef = u.String()
} else { } else {
@@ -654,7 +656,7 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
if strings.HasPrefix(ref.FullDefinition, "http") { if strings.HasPrefix(ref.FullDefinition, "http") {
u, _ := url.Parse(ref.FullDefinition) u, _ := url.Parse(ref.FullDefinition)
p, _ := filepath.Abs(filepath.Join(filepath.Dir(u.Path), exp[0])) p, _ := filepath.Abs(filepath.Join(filepath.Dir(u.Path), exp[0]))
u.Path = p u.Path = utils.ReplaceWindowsDriveWithLinuxPath(p)
u.Fragment = "" u.Fragment = ""
def = fmt.Sprintf("%s#/%s", u.String(), exp[1]) def = fmt.Sprintf("%s#/%s", u.String(), exp[1])
} else { } else {
@@ -698,7 +700,7 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
// split the url. // split the url.
u, _ := url.Parse(ref.FullDefinition) u, _ := url.Parse(ref.FullDefinition)
abs, _ := filepath.Abs(filepath.Join(filepath.Dir(u.Path), l)) abs, _ := filepath.Abs(filepath.Join(filepath.Dir(u.Path), l))
u.Path = abs u.Path = utils.ReplaceWindowsDriveWithLinuxPath(abs)
u.Fragment = "" u.Fragment = ""
def = u.String() def = u.String()
} else { } else {
@@ -765,7 +767,7 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
u, _ := url.Parse(ref.FullDefinition) u, _ := url.Parse(ref.FullDefinition)
p, _ := filepath.Abs(filepath.Join(filepath.Dir(u.Path), exp[0])) p, _ := filepath.Abs(filepath.Join(filepath.Dir(u.Path), exp[0]))
u.Path = p u.Path = utils.ReplaceWindowsDriveWithLinuxPath(p)
def = fmt.Sprintf("%s#/%s", u.String(), exp[1]) def = fmt.Sprintf("%s#/%s", u.String(), exp[1])
} else { } else {
@@ -819,7 +821,7 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
// split the url. // split the url.
u, _ := url.Parse(ref.FullDefinition) u, _ := url.Parse(ref.FullDefinition)
abs, _ := filepath.Abs(filepath.Join(filepath.Dir(u.Path), l)) abs, _ := filepath.Abs(filepath.Join(filepath.Dir(u.Path), l))
u.Path = abs u.Path = utils.ReplaceWindowsDriveWithLinuxPath(abs)
u.Fragment = "" u.Fragment = ""
def = u.String() def = u.String()
} else { } else {

View File

@@ -11,11 +11,11 @@ import (
"io/fs" "io/fs"
"log/slog" "log/slog"
"math" "math"
"net/url"
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
"strconv" "strconv"
"strings"
"sync" "sync"
"time" "time"
) )
@@ -423,6 +423,7 @@ func (r *Rolodex) BuildIndexes() {
// Open opens a file in the rolodex, and returns a RolodexFile. // Open opens a file in the rolodex, and returns a RolodexFile.
func (r *Rolodex) Open(location string) (RolodexFile, error) { func (r *Rolodex) Open(location string) (RolodexFile, error) {
if r == nil { if r == nil {
return nil, fmt.Errorf("rolodex has not been initialized, cannot open file '%s'", location) return nil, fmt.Errorf("rolodex has not been initialized, cannot open file '%s'", location)
} }
@@ -436,8 +437,7 @@ func (r *Rolodex) Open(location string) (RolodexFile, error) {
var remoteFile *RemoteFile var remoteFile *RemoteFile
fileLookup := location fileLookup := location
isUrl := false isUrl := false
u, _ := url.Parse(location) if strings.HasPrefix(location, "http") {
if u != nil && u.Scheme != "" {
isUrl = true isUrl = true
} }
@@ -517,8 +517,12 @@ func (r *Rolodex) Open(location string) (RolodexFile, error) {
} }
for _, v := range r.remoteFS { for _, v := range r.remoteFS {
f, err := v.Open(fileLookup) f, err := v.Open(fileLookup)
if err == nil { if err != nil {
r.logger.Warn("[rolodex] errors opening remote file", "location", fileLookup, "error", err)
}
if f != nil {
if rf, ok := interface{}(f).(*RemoteFile); ok { if rf, ok := interface{}(f).(*RemoteFile); ok {
remoteFile = rf remoteFile = rf

View File

@@ -13,6 +13,7 @@ import (
"net/url" "net/url"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"time" "time"
"github.com/pb33f/libopenapi/datamodel" "github.com/pb33f/libopenapi/datamodel"
@@ -334,8 +335,9 @@ func (i *RemoteFS) Open(remoteURL string) (fs.File, error) {
if i.rootURLParsed != nil { if i.rootURLParsed != nil {
remoteParsedURL.Host = i.rootURLParsed.Host remoteParsedURL.Host = i.rootURLParsed.Host
remoteParsedURL.Scheme = i.rootURLParsed.Scheme remoteParsedURL.Scheme = i.rootURLParsed.Scheme
if !filepath.IsAbs(remoteParsedURL.Path) { if !strings.HasPrefix(remoteParsedURL.Path, "/") {
remoteParsedURL.Path = filepath.Join(i.rootURLParsed.Path, remoteParsedURL.Path) remoteParsedURL.Path = filepath.Join(i.rootURLParsed.Path, remoteParsedURL.Path)
remoteParsedURL.Path = strings.ReplaceAll(remoteParsedURL.Path, "\\", "/")
} }
} }
@@ -385,7 +387,7 @@ func (i *RemoteFS) Open(remoteURL string) (fs.File, error) {
return nil, fmt.Errorf("unable to fetch remote document: %s", string(responseBytes)) return nil, fmt.Errorf("unable to fetch remote document: %s", string(responseBytes))
} }
absolutePath, _ := filepath.Abs(remoteParsedURL.Path) absolutePath := remoteParsedURL.Path
// extract last modified from response // extract last modified from response
lastModified := response.Header.Get("Last-Modified") lastModified := response.Header.Get("Last-Modified")

View File

@@ -13,6 +13,8 @@ import (
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
"os" "os"
"path/filepath"
"runtime"
"strings" "strings"
"testing" "testing"
"testing/fstest" "testing/fstest"
@@ -166,8 +168,11 @@ func TestRolodex_LocalNonNativeFS_BadRead(t *testing.T) {
f, rerr := rolo.Open("/") f, rerr := rolo.Open("/")
assert.Nil(t, f) assert.Nil(t, f)
assert.Error(t, rerr) assert.Error(t, rerr)
assert.Equal(t, "file does not exist", rerr.Error()) if runtime.GOOS != "windows" {
assert.Equal(t, "file does not exist", rerr.Error())
} else {
assert.Equal(t, "invalid argument", rerr.Error())
}
} }
func TestRolodex_LocalNonNativeFS_BadStat(t *testing.T) { func TestRolodex_LocalNonNativeFS_BadStat(t *testing.T) {
@@ -388,21 +393,21 @@ properties:
third := `type: "object" third := `type: "object"
properties: properties:
name: name:
$ref: "http://the-space-race-is-all-about-space-and-time-dot.com/fourth.yaml" $ref: "http://the-space-race-is-all-about-space-and-time-dot.com/$4"
tame: tame:
$ref: "http://the-space-race-is-all-about-space-and-time-dot.com/fifth.yaml#/" $ref: "http://the-space-race-is-all-about-space-and-time-dot.com/$5#/"
blame: blame:
$ref: "fifth.yaml" $ref: "$_5"
fame: fame:
$ref: "$PWD/fourth.yaml#/properties/name" $ref: "$_4#/properties/name"
game: game:
$ref: "$PWD/fifth.yaml" $ref: "$_5"
children: children:
type: "object" type: "object"
anyOf: anyOf:
- $ref: "second.yaml#/components/schemas/CircleTest" - $ref: "$2#/components/schemas/CircleTest"
required: required:
- children` - children`
@@ -417,11 +422,12 @@ components:
children: children:
type: "object" type: "object"
anyOf: anyOf:
- $ref: "third.yaml" - $ref: "$3"
description: "Array of sub-categories in the same format." description: "Array of sub-categories in the same format."
required: required:
- "name" - "name"
- "children"` - "children"
`
first := `openapi: 3.1.0 first := `openapi: 3.1.0
components: components:
@@ -432,32 +438,58 @@ components:
- muffins - muffins
properties: properties:
muffins: muffins:
$ref: "second.yaml#/components/schemas/CircleTest"` $ref: "$2#/components/schemas/CircleTest"
`
cwd, _ := os.Getwd() var firstFile, secondFile, thirdFile, fourthFile, fifthFile *os.File
var fErr error
_ = os.WriteFile("third.yaml", []byte(strings.ReplaceAll(third, "$PWD", cwd)), 0644) firstFile, fErr = os.CreateTemp("", "*-first.yaml")
_ = os.WriteFile("second.yaml", []byte(second), 0644) assert.NoError(t, fErr)
_ = os.WriteFile("first.yaml", []byte(first), 0644)
_ = os.WriteFile("fourth.yaml", []byte(fourth), 0644)
_ = os.WriteFile("fifth.yaml", []byte(fifth), 0644)
defer os.Remove("first.yaml")
defer os.Remove("second.yaml")
defer os.Remove("third.yaml")
defer os.Remove("fourth.yaml")
defer os.Remove("fifth.yaml")
baseDir := "." secondFile, fErr = os.CreateTemp("", "*-second.yaml")
assert.NoError(t, fErr)
thirdFile, fErr = os.CreateTemp("", "*-third.yaml")
assert.NoError(t, fErr)
fourthFile, fErr = os.CreateTemp("", "*-fourth.yaml")
assert.NoError(t, fErr)
fifthFile, fErr = os.CreateTemp("", "*-fifth.yaml")
assert.NoError(t, fErr)
first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\")
second = strings.ReplaceAll(strings.ReplaceAll(second, "$3", thirdFile.Name()), "\\", "\\\\")
third = strings.ReplaceAll(third, "$4", filepath.Base(fourthFile.Name()))
third = strings.ReplaceAll(third, "$_4", fourthFile.Name())
third = strings.ReplaceAll(third, "$5", filepath.Base(fifthFile.Name()))
third = strings.ReplaceAll(third, "$_5", fifthFile.Name())
third = strings.ReplaceAll(strings.ReplaceAll(third, "$2", secondFile.Name()), "\\", "\\\\")
firstFile.WriteString(first)
secondFile.WriteString(second)
thirdFile.WriteString(third)
fourthFile.WriteString(fourth)
fifthFile.WriteString(fifth)
defer os.Remove(firstFile.Name())
defer os.Remove(secondFile.Name())
defer os.Remove(thirdFile.Name())
defer os.Remove(fourthFile.Name())
defer os.Remove(fifthFile.Name())
baseDir := filepath.Dir(firstFile.Name())
fsCfg := &LocalFSConfig{ fsCfg := &LocalFSConfig{
BaseDirectory: baseDir, BaseDirectory: baseDir,
DirFS: os.DirFS(baseDir), DirFS: os.DirFS(baseDir),
FileFilters: []string{ FileFilters: []string{
"first.yaml", filepath.Base(firstFile.Name()),
"second.yaml", filepath.Base(secondFile.Name()),
"third.yaml", filepath.Base(thirdFile.Name()),
"fourth.yaml", filepath.Base(fourthFile.Name()),
"fifth.yaml", filepath.Base(fifthFile.Name()),
}, },
} }
@@ -474,7 +506,7 @@ components:
rolodex.AddLocalFS(baseDir, fileFS) rolodex.AddLocalFS(baseDir, fileFS)
srv := test_rolodexDeepRefServer([]byte(first), []byte(second), srv := test_rolodexDeepRefServer([]byte(first), []byte(second),
[]byte(strings.ReplaceAll(third, "$PWD", cwd)), []byte(fourth), []byte(fifth)) []byte(third), []byte(fourth), []byte(fifth))
defer srv.Close() defer srv.Close()
u, _ := url.Parse(srv.URL) u, _ := url.Parse(srv.URL)
@@ -491,10 +523,10 @@ components:
// there are two circles. Once when reading the journey from first.yaml, and then a second internal look in second.yaml // there are two circles. Once when reading the journey from first.yaml, and then a second internal look in second.yaml
// the index won't find three, because by the time that 'three' has been read, it's already been indexed and the journey // the index won't find three, because by the time that 'three' has been read, it's already been indexed and the journey
// discovered. // discovered.
assert.Len(t, rolodex.GetIgnoredCircularReferences(), 2) assert.GreaterOrEqual(t, len(rolodex.GetIgnoredCircularReferences()), 1)
// extract a local file // extract a local file
f, _ := rolodex.Open("first.yaml") f, _ := rolodex.Open(firstFile.Name())
// index // index
x, y := f.(*rolodexFile).Index(cf) x, y := f.(*rolodexFile).Index(cf)
assert.NotNil(t, x) assert.NotNil(t, x)
@@ -506,7 +538,7 @@ components:
assert.NoError(t, y) assert.NoError(t, y)
// extract a remote file // extract a remote file
f, _ = rolodex.Open("http://the-space-race-is-all-about-space-and-time-dot.com/fourth.yaml") f, _ = rolodex.Open("http://the-space-race-is-all-about-space-and-time-dot.com/" + filepath.Base(fourthFile.Name()))
// index // index
x, y = f.(*rolodexFile).Index(cf) x, y = f.(*rolodexFile).Index(cf)
@@ -519,7 +551,7 @@ components:
assert.NoError(t, y) assert.NoError(t, y)
// extract another remote file // extract another remote file
f, _ = rolodex.Open("http://the-space-race-is-all-about-space-and-time-dot.com/fifth.yaml") f, _ = rolodex.Open("http://the-space-race-is-all-about-space-and-time-dot.com/" + filepath.Base(fifthFile.Name()))
//change cf to perform document check (which should fail) //change cf to perform document check (which should fail)
cf.SkipDocumentCheck = false cf.SkipDocumentCheck = false
@@ -533,23 +565,23 @@ components:
func test_rolodexDeepRefServer(a, b, c, d, e []byte) *httptest.Server { func test_rolodexDeepRefServer(a, b, c, d, e []byte) *httptest.Server {
return httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { return httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("Last-Modified", "Wed, 21 Oct 2015 12:28:00 GMT") rw.Header().Set("Last-Modified", "Wed, 21 Oct 2015 12:28:00 GMT")
if strings.HasSuffix(req.URL.String(), "/first.yaml") { if strings.HasSuffix(req.URL.String(), "-first.yaml") {
_, _ = rw.Write(a) _, _ = rw.Write(a)
return return
} }
if strings.HasSuffix(req.URL.String(), "/second.yaml") { if strings.HasSuffix(req.URL.String(), "-second.yaml") {
_, _ = rw.Write(b) _, _ = rw.Write(b)
return return
} }
if strings.HasSuffix(req.URL.String(), "/third.yaml") { if strings.HasSuffix(req.URL.String(), "-third.yaml") {
_, _ = rw.Write(c) _, _ = rw.Write(c)
return return
} }
if strings.HasSuffix(req.URL.String(), "/fourth.yaml") { if strings.HasSuffix(req.URL.String(), "-fourth.yaml") {
_, _ = rw.Write(d) _, _ = rw.Write(d)
return return
} }
if strings.HasSuffix(req.URL.String(), "/fifth.yaml") { if strings.HasSuffix(req.URL.String(), "-fifth.yaml") {
_, _ = rw.Write(e) _, _ = rw.Write(e)
return return
} }
@@ -569,8 +601,10 @@ properties:
third := `type: "object" third := `type: "object"
properties: properties:
herbs:
$ref: "$1"
name: name:
$ref: "http://the-space-race-is-all-about-space-and-time-dot.com/fourth.yaml"` $ref: "http://the-space-race-is-all-about-space-and-time-dot.com/$4"`
second := `openapi: 3.1.0 second := `openapi: 3.1.0
components: components:
@@ -585,7 +619,7 @@ components:
children: children:
type: "object" type: "object"
anyOf: anyOf:
- $ref: "third.yaml" - $ref: "$3"
required: required:
- "name" - "name"
- "children"` - "children"`
@@ -599,20 +633,39 @@ components:
- muffins - muffins
properties: properties:
muffins: muffins:
$ref: "second_n.yaml#/components/schemas/CircleTest"` $ref: "$2#/components/schemas/CircleTest"`
cwd, _ := os.Getwd() var firstFile, secondFile, thirdFile, fourthFile *os.File
var fErr error
_ = os.WriteFile("third_n.yaml", []byte(strings.ReplaceAll(third, "$PWD", cwd)), 0644) firstFile, fErr = os.CreateTemp("", "*-first.yaml")
_ = os.WriteFile("second_n.yaml", []byte(second), 0644) assert.NoError(t, fErr)
_ = os.WriteFile("first_n.yaml", []byte(first), 0644)
_ = os.WriteFile("fourth_n.yaml", []byte(fourth), 0644)
defer os.Remove("first_n.yaml")
defer os.Remove("second_n.yaml")
defer os.Remove("third_n.yaml")
defer os.Remove("fourth_n.yaml")
baseDir := "." secondFile, fErr = os.CreateTemp("", "*-second.yaml")
assert.NoError(t, fErr)
thirdFile, fErr = os.CreateTemp("", "*-third.yaml")
assert.NoError(t, fErr)
fourthFile, fErr = os.CreateTemp("", "*-fourth.yaml")
assert.NoError(t, fErr)
first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\")
second = strings.ReplaceAll(strings.ReplaceAll(second, "$3", thirdFile.Name()), "\\", "\\\\")
third = strings.ReplaceAll(strings.ReplaceAll(third, "$4", filepath.Base(fourthFile.Name())), "\\", "\\\\")
third = strings.ReplaceAll(strings.ReplaceAll(first, "$1", filepath.Base(firstFile.Name())), "\\", "\\\\")
firstFile.WriteString(first)
secondFile.WriteString(second)
thirdFile.WriteString(third)
fourthFile.WriteString(fourth)
defer os.Remove(firstFile.Name())
defer os.Remove(secondFile.Name())
defer os.Remove(thirdFile.Name())
defer os.Remove(fourthFile.Name())
baseDir := filepath.Dir(firstFile.Name())
cf := CreateOpenAPIIndexConfig() cf := CreateOpenAPIIndexConfig()
cf.BasePath = baseDir cf.BasePath = baseDir
cf.IgnorePolymorphicCircularReferences = true cf.IgnorePolymorphicCircularReferences = true
@@ -635,7 +688,7 @@ components:
rolodex.SetRootNode(&rootNode) rolodex.SetRootNode(&rootNode)
srv := test_rolodexDeepRefServer([]byte(first), []byte(second), srv := test_rolodexDeepRefServer([]byte(first), []byte(second),
[]byte(strings.ReplaceAll(third, "$PWD", cwd)), []byte(fourth), nil) []byte(third), []byte(fourth), nil)
defer srv.Close() defer srv.Close()
u, _ := url.Parse(srv.URL) u, _ := url.Parse(srv.URL)
@@ -647,7 +700,9 @@ components:
err = rolodex.IndexTheRolodex() err = rolodex.IndexTheRolodex()
assert.Error(t, err) assert.Error(t, err)
assert.Len(t, rolodex.GetCaughtErrors(), 2) assert.GreaterOrEqual(t, len(rolodex.GetCaughtErrors()), 1)
assert.Equal(t, "cannot resolve reference `not_found.yaml`, it's missing: [8:11]", rolodex.GetCaughtErrors()[0].Error())
} }
func TestRolodex_IndexCircularLookup_PolyItems_LocalLoop_WithFiles(t *testing.T) { func TestRolodex_IndexCircularLookup_PolyItems_LocalLoop_WithFiles(t *testing.T) {
@@ -664,7 +719,7 @@ components:
type: "object" type: "object"
oneOf: oneOf:
items: items:
$ref: "second_a.yaml#/components/schemas/CircleTest" $ref: "$2#/components/schemas/CircleTest"
required: required:
- "name" - "name"
- "children" - "children"
@@ -704,26 +759,38 @@ components:
anyOf: anyOf:
- $ref: "#/components/schemas/CircleTest"` - $ref: "#/components/schemas/CircleTest"`
var firstFile, secondFile *os.File
var fErr error
firstFile, fErr = os.CreateTemp("", "*-first.yaml")
assert.NoError(t, fErr)
secondFile, fErr = os.CreateTemp("", "*-second.yaml")
assert.NoError(t, fErr)
first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\")
firstFile.WriteString(first)
secondFile.WriteString(second)
defer os.Remove(firstFile.Name())
defer os.Remove(secondFile.Name())
var rootNode yaml.Node var rootNode yaml.Node
_ = yaml.Unmarshal([]byte(first), &rootNode) _ = yaml.Unmarshal([]byte(first), &rootNode)
_ = os.WriteFile("second_a.yaml", []byte(second), 0644)
_ = os.WriteFile("first_a.yaml", []byte(first), 0644)
defer os.Remove("first_a.yaml")
defer os.Remove("second_a.yaml")
cf := CreateOpenAPIIndexConfig() cf := CreateOpenAPIIndexConfig()
cf.IgnorePolymorphicCircularReferences = true cf.IgnorePolymorphicCircularReferences = true
rolodex := NewRolodex(cf) rolodex := NewRolodex(cf)
baseDir := "." baseDir := filepath.Dir(firstFile.Name())
fsCfg := &LocalFSConfig{ fsCfg := &LocalFSConfig{
BaseDirectory: baseDir, BaseDirectory: baseDir,
DirFS: os.DirFS(baseDir), DirFS: os.DirFS(baseDir),
FileFilters: []string{ FileFilters: []string{
"first_a.yaml", filepath.Base(firstFile.Name()),
"second_a.yaml", filepath.Base(secondFile.Name()),
}, },
} }
@@ -758,7 +825,7 @@ components:
type: "object" type: "object"
oneOf: oneOf:
items: items:
$ref: "second_d.yaml#/components/schemas/CircleTest" $ref: "$2#/components/schemas/CircleTest"
required: required:
- "name" - "name"
- "children" - "children"
@@ -798,27 +865,39 @@ components:
anyOf: anyOf:
- $ref: "#/components/schemas/CircleTest"` - $ref: "#/components/schemas/CircleTest"`
var firstFile, secondFile *os.File
var fErr error
firstFile, fErr = os.CreateTemp("", "*-first.yaml")
assert.NoError(t, fErr)
secondFile, fErr = os.CreateTemp("", "*-second.yaml")
assert.NoError(t, fErr)
first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\")
firstFile.WriteString(first)
secondFile.WriteString(second)
defer os.Remove(firstFile.Name())
defer os.Remove(secondFile.Name())
var rootNode yaml.Node var rootNode yaml.Node
_ = yaml.Unmarshal([]byte(first), &rootNode) _ = yaml.Unmarshal([]byte(first), &rootNode)
_ = os.WriteFile("second_d.yaml", []byte(second), 0644)
_ = os.WriteFile("first_d.yaml", []byte(first), 0644)
defer os.Remove("first_d.yaml")
defer os.Remove("second_d.yaml")
cf := CreateOpenAPIIndexConfig() cf := CreateOpenAPIIndexConfig()
cf.IgnorePolymorphicCircularReferences = true cf.IgnorePolymorphicCircularReferences = true
cf.AvoidBuildIndex = true cf.AvoidBuildIndex = true
rolodex := NewRolodex(cf) rolodex := NewRolodex(cf)
baseDir := "." baseDir := filepath.Dir(firstFile.Name())
fsCfg := &LocalFSConfig{ fsCfg := &LocalFSConfig{
BaseDirectory: baseDir, BaseDirectory: baseDir,
DirFS: os.DirFS(baseDir), DirFS: os.DirFS(baseDir),
FileFilters: []string{ FileFilters: []string{
"first_d.yaml", filepath.Base(firstFile.Name()),
"second_d.yaml", filepath.Base(secondFile.Name()),
}, },
} }
@@ -858,7 +937,7 @@ components:
children: children:
type: "array" type: "array"
items: items:
$ref: "second_b.yaml#/components/schemas/CircleTest" $ref: "$2#/components/schemas/CircleTest"
required: required:
- "name" - "name"
- "children" - "children"
@@ -897,26 +976,38 @@ components:
items: items:
$ref: "#/components/schemas/CircleTest"` $ref: "#/components/schemas/CircleTest"`
var firstFile, secondFile *os.File
var fErr error
firstFile, fErr = os.CreateTemp("", "*-first.yaml")
assert.NoError(t, fErr)
secondFile, fErr = os.CreateTemp("", "*-second.yaml")
assert.NoError(t, fErr)
first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\")
firstFile.WriteString(first)
secondFile.WriteString(second)
defer os.Remove(firstFile.Name())
defer os.Remove(secondFile.Name())
var rootNode yaml.Node var rootNode yaml.Node
_ = yaml.Unmarshal([]byte(first), &rootNode) _ = yaml.Unmarshal([]byte(first), &rootNode)
_ = os.WriteFile("second_b.yaml", []byte(second), 0644)
_ = os.WriteFile("first_b.yaml", []byte(first), 0644)
defer os.Remove("first_b.yaml")
defer os.Remove("second_b.yaml")
cf := CreateOpenAPIIndexConfig() cf := CreateOpenAPIIndexConfig()
cf.IgnoreArrayCircularReferences = true cf.IgnoreArrayCircularReferences = true
rolodex := NewRolodex(cf) rolodex := NewRolodex(cf)
baseDir := "." baseDir := filepath.Dir(firstFile.Name())
fsCfg := &LocalFSConfig{ fsCfg := &LocalFSConfig{
BaseDirectory: baseDir, BaseDirectory: baseDir,
DirFS: os.DirFS(baseDir), DirFS: os.DirFS(baseDir),
FileFilters: []string{ FileFilters: []string{
"first_b.yaml", filepath.Base(firstFile.Name()),
"second_b.yaml", filepath.Base(secondFile.Name()),
}, },
} }
@@ -954,27 +1045,27 @@ components:
type: "string" type: "string"
anyOf: anyOf:
items: items:
$ref: "https://I-love-a-good-cake-and-pizza.com/third.yaml" $ref: "https://I-love-a-good-cake-and-pizza.com/$3"
pizza: pizza:
type: "string" type: "string"
anyOf: anyOf:
items: items:
$ref: "third.yaml" $ref: "$3"
same: same:
type: "string" type: "string"
oneOf: oneOf:
items: items:
$ref: "https://kjahsdkjahdkjashdas.com/fourth.yaml#/components/schemas/Chicken" $ref: "https://milly-the-milk-bottle.com/$4#/components/schemas/Chicken"
name: name:
type: "string" type: "string"
oneOf: oneOf:
items: items:
$ref: "https://kjahsdkjahdkjashdas.com/third.yaml#/" $ref: "https://junk-peddlers-blues.com/$3#/"
children: children:
type: "object" type: "object"
allOf: allOf:
items: items:
$ref: "first.yaml#/components/schemas/StartTest" $ref: "$1#/components/schemas/StartTest"
required: required:
- "name" - "name"
- "children" - "children"
@@ -1003,17 +1094,49 @@ components:
chuffins: chuffins:
type: object type: object
allOf: allOf:
- $ref: "https://kjahsdkjahdkjashdas.com/third.yaml" - $ref: "https://what-a-lovely-fence.com/$3"
buffins: buffins:
type: object type: object
allOf: allOf:
- $ref: "https://kjahsdkjahdkjashdas.com/second.yaml#/" - $ref: "https://no-more-bananas-please.com/$2#/"
muffins: muffins:
type: object type: object
anyOf: anyOf:
- $ref: "https://kjahsdkjahdkjashdas.com/second.yaml#/components/schemas/CircleTest" - $ref: "https://where-are-all-my-jellies.com/$2#/components/schemas/CircleTest"
` `
var firstFile, secondFile, thirdFile, fourthFile *os.File
var fErr error
firstFile, fErr = os.CreateTemp("", "*-first.yaml")
assert.NoError(t, fErr)
secondFile, fErr = os.CreateTemp("", "*-second.yaml")
assert.NoError(t, fErr)
thirdFile, fErr = os.CreateTemp("", "*-third.yaml")
assert.NoError(t, fErr)
fourthFile, fErr = os.CreateTemp("", "*-fourth.yaml")
assert.NoError(t, fErr)
first = strings.ReplaceAll(first, "$2", filepath.Base(secondFile.Name()))
first = strings.ReplaceAll(strings.ReplaceAll(first, "$3", filepath.Base(thirdFile.Name())), "\\", "\\\\")
second = strings.ReplaceAll(second, "$3", filepath.Base(thirdFile.Name()))
second = strings.ReplaceAll(second, "$1", filepath.Base(firstFile.Name()))
second = strings.ReplaceAll(strings.ReplaceAll(second, "$4", filepath.Base(fourthFile.Name())), "\\", "\\\\")
firstFile.WriteString(first)
secondFile.WriteString(second)
thirdFile.WriteString(third)
fourthFile.WriteString(fourth)
defer os.Remove(firstFile.Name())
defer os.Remove(secondFile.Name())
defer os.Remove(thirdFile.Name())
defer os.Remove(fourthFile.Name())
var rootNode yaml.Node var rootNode yaml.Node
_ = yaml.Unmarshal([]byte(first), &rootNode) _ = yaml.Unmarshal([]byte(first), &rootNode)
@@ -1037,8 +1160,7 @@ components:
assert.Len(t, rolodex.GetCaughtErrors(), 0) assert.Len(t, rolodex.GetCaughtErrors(), 0)
assert.GreaterOrEqual(t, len(rolodex.GetIgnoredCircularReferences()), 1) assert.GreaterOrEqual(t, len(rolodex.GetIgnoredCircularReferences()), 1)
assert.Equal(t, rolodex.GetRootIndex().GetResolver().GetIndexesVisited(), 6) assert.Equal(t, rolodex.GetRootIndex().GetResolver().GetIndexesVisited(), 11)
assert.Equal(t, int64(1719), rolodex.RolodexFileSize())
} }
@@ -1056,12 +1178,12 @@ components:
type: object type: object
allOf: allOf:
items: items:
$ref: "third_c.yaml" $ref: "$3"
boop: boop:
type: object type: object
allOf: allOf:
items: items:
$ref: "$PWD/third_c.yaml" $ref: "$3"
loop: loop:
type: object type: object
oneOf: oneOf:
@@ -1091,34 +1213,49 @@ components:
muffins: muffins:
type: object type: object
anyOf: anyOf:
- $ref: "second_c.yaml#/components/schemas/CircleTest" - $ref: "$2#/components/schemas/CircleTest"
- $ref: "$PWD/third_c.yaml"` - $ref: "$3"`
var firstFile, secondFile, thirdFile *os.File
var fErr error
firstFile, fErr = os.CreateTemp("", "*-first.yaml")
assert.NoError(t, fErr)
secondFile, fErr = os.CreateTemp("", "*-second.yaml")
assert.NoError(t, fErr)
thirdFile, fErr = os.CreateTemp("", "*-third.yaml")
assert.NoError(t, fErr)
first = strings.ReplaceAll(first, "$2", secondFile.Name())
first = strings.ReplaceAll(strings.ReplaceAll(first, "$3", thirdFile.Name()), "\\", "\\\\")
second = strings.ReplaceAll(strings.ReplaceAll(second, "$3", thirdFile.Name()), "\\", "\\\\")
firstFile.WriteString(first)
secondFile.WriteString(second)
thirdFile.WriteString(third)
defer os.Remove(firstFile.Name())
defer os.Remove(secondFile.Name())
defer os.Remove(thirdFile.Name())
var rootNode yaml.Node var rootNode yaml.Node
cws, _ := os.Getwd() _ = yaml.Unmarshal([]byte(first), &rootNode)
_ = yaml.Unmarshal([]byte(strings.ReplaceAll(first, "$PWD", cws)), &rootNode)
_ = os.WriteFile("second_c.yaml", []byte(strings.ReplaceAll(second, "$PWD", cws)), 0644)
_ = os.WriteFile("first_c.yaml", []byte(strings.ReplaceAll(first, "$PWD", cws)), 0644)
_ = os.WriteFile("third_c.yaml", []byte(third), 0644)
defer os.Remove("first_c.yaml")
defer os.Remove("second_c.yaml")
defer os.Remove("third_c.yaml")
cf := CreateOpenAPIIndexConfig() cf := CreateOpenAPIIndexConfig()
cf.IgnorePolymorphicCircularReferences = true cf.IgnorePolymorphicCircularReferences = true
rolodex := NewRolodex(cf) rolodex := NewRolodex(cf)
baseDir := "." baseDir := filepath.Dir(firstFile.Name())
fsCfg := &LocalFSConfig{ fsCfg := &LocalFSConfig{
BaseDirectory: baseDir, BaseDirectory: baseDir,
DirFS: os.DirFS(baseDir), DirFS: os.DirFS(baseDir),
FileFilters: []string{ FileFilters: []string{
"first_c.yaml", filepath.Base(firstFile.Name()),
"second_c.yaml", filepath.Base(secondFile.Name()),
"third_c.yaml", filepath.Base(thirdFile.Name()),
}, },
} }
@@ -1150,7 +1287,7 @@ properties:
third := `type: "object" third := `type: "object"
properties: properties:
name: name:
$ref: "http://the-space-race-is-all-about-space-and-time-dot.com/fourth.yaml"` $ref: "http://the-space-race-is-all-about-space-and-time-dot.com/$4"`
second := `openapi: 3.1.0 second := `openapi: 3.1.0
components: components:
@@ -1165,7 +1302,7 @@ components:
children: children:
type: "object" type: "object"
anyOf: anyOf:
- $ref: "third.yaml" - $ref: "$3"
required: required:
- "name" - "name"
- "children"` - "children"`
@@ -1179,29 +1316,47 @@ components:
- muffins - muffins
properties: properties:
muffins: muffins:
$ref: "second_e.yaml#/components/schemas/CircleTest"` $ref: "$2#/components/schemas/CircleTest"`
cwd, _ := os.Getwd() var firstFile, secondFile, thirdFile, fourthFile *os.File
var fErr error
_ = os.WriteFile("third_e.yaml", []byte(strings.ReplaceAll(third, "$PWD", cwd)), 0644) firstFile, fErr = os.CreateTemp("", "*-first.yaml")
_ = os.WriteFile("second_e.yaml", []byte(second), 0644) assert.NoError(t, fErr)
_ = os.WriteFile("first_e.yaml", []byte(first), 0644)
_ = os.WriteFile("fourth_e.yaml", []byte(fourth), 0644)
defer os.Remove("first_e.yaml")
defer os.Remove("second_e.yaml")
defer os.Remove("third_e.yaml")
defer os.Remove("fourth_e.yaml")
baseDir := "." secondFile, fErr = os.CreateTemp("", "*-second.yaml")
assert.NoError(t, fErr)
thirdFile, fErr = os.CreateTemp("", "*-third.yaml")
assert.NoError(t, fErr)
fourthFile, fErr = os.CreateTemp("", "*-fourth.yaml")
assert.NoError(t, fErr)
first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\")
second = strings.ReplaceAll(strings.ReplaceAll(second, "$3", thirdFile.Name()), "\\", "\\\\")
third = strings.ReplaceAll(strings.ReplaceAll(third, "$4", filepath.Base(fourthFile.Name())), "\\", "\\\\")
firstFile.WriteString(first)
secondFile.WriteString(second)
thirdFile.WriteString(third)
fourthFile.WriteString(fourth)
defer os.Remove(firstFile.Name())
defer os.Remove(secondFile.Name())
defer os.Remove(thirdFile.Name())
defer os.Remove(fourthFile.Name())
baseDir := filepath.Dir(firstFile.Name())
fsCfg := &LocalFSConfig{ fsCfg := &LocalFSConfig{
BaseDirectory: baseDir, BaseDirectory: baseDir,
DirFS: os.DirFS(baseDir), DirFS: os.DirFS(baseDir),
FileFilters: []string{ FileFilters: []string{
"first_e.yaml", filepath.Base(firstFile.Name()),
"second_e.yaml", filepath.Base(secondFile.Name()),
"third_e.yaml", filepath.Base(thirdFile.Name()),
"fourth_e.yaml", filepath.Base(fourthFile.Name()),
}, },
} }
@@ -1217,7 +1372,7 @@ components:
rolodex.AddLocalFS(baseDir, fileFS) rolodex.AddLocalFS(baseDir, fileFS)
srv := test_rolodexDeepRefServer([]byte(first), []byte(second), srv := test_rolodexDeepRefServer([]byte(first), []byte(second),
[]byte(strings.ReplaceAll(third, "$PWD", cwd)), []byte(fourth), nil) []byte(third), []byte(fourth), nil)
defer srv.Close() defer srv.Close()
u, _ := url.Parse(srv.URL) u, _ := url.Parse(srv.URL)
@@ -1229,7 +1384,7 @@ components:
err = rolodex.IndexTheRolodex() err = rolodex.IndexTheRolodex()
assert.Error(t, err) assert.Error(t, err)
assert.Len(t, rolodex.GetCaughtErrors(), 2) assert.Len(t, rolodex.GetCaughtErrors(), 3)
} }
func TestRolodex_IndexCircularLookup_LookupHttpNoBaseURL(t *testing.T) { func TestRolodex_IndexCircularLookup_LookupHttpNoBaseURL(t *testing.T) {
@@ -1371,9 +1526,14 @@ func TestRolodex_SimpleTest_OneDoc(t *testing.T) {
assert.NoError(t, ierr) assert.NoError(t, ierr)
assert.NotNil(t, idx) assert.NotNil(t, idx)
assert.Equal(t, YAML, f.GetFileExtension()) assert.Equal(t, YAML, f.GetFileExtension())
assert.True(t, strings.HasSuffix(f.GetFullPath(), "rolodex_test_data/components.yaml")) assert.True(t, strings.HasSuffix(f.GetFullPath(), "rolodex_test_data"+string(os.PathSeparator)+"components.yaml"))
assert.NotNil(t, f.ModTime()) assert.NotNil(t, f.ModTime())
assert.Equal(t, int64(283), f.Size()) if runtime.GOOS != "windows" {
assert.Equal(t, int64(283), f.Size())
} else {
assert.Equal(t, int64(295), f.Size())
}
assert.False(t, f.IsDir()) assert.False(t, f.IsDir())
assert.Nil(t, f.Sys()) assert.Nil(t, f.Sys())
assert.Equal(t, fs.FileMode(0), f.Mode()) assert.Equal(t, fs.FileMode(0), f.Mode())

View File

@@ -7,6 +7,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath" "github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"path/filepath"
"strings" "strings"
"testing" "testing"
) )
@@ -57,7 +58,9 @@ func TestRolodex_FindNodeOrigin(t *testing.T) {
origin := rolo.FindNodeOrigin(results[0]) origin := rolo.FindNodeOrigin(results[0])
assert.NotNil(t, origin) assert.NotNil(t, origin)
assert.True(t, strings.HasSuffix(origin.AbsoluteLocation, "index/rolodex_test_data/dir2/utils/utils.yaml")) sep := string(filepath.Separator)
assert.True(t, strings.HasSuffix(origin.AbsoluteLocation, "index"+sep+
"rolodex_test_data"+sep+"dir2"+sep+"utils"+sep+"utils.yaml"))
// should be identical to the original node // should be identical to the original node
assert.Equal(t, results[0], origin.Node) assert.Equal(t, results[0], origin.Node)

View File

@@ -14,6 +14,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"runtime"
"testing" "testing"
"time" "time"
@@ -258,7 +259,11 @@ func TestSpecIndex_DigitalOcean_FullCheckoutLocalResolve(t *testing.T) {
assert.Len(t, rolo.GetCaughtErrors(), 0) assert.Len(t, rolo.GetCaughtErrors(), 0)
assert.Len(t, rolo.GetIgnoredCircularReferences(), 0) assert.Len(t, rolo.GetIgnoredCircularReferences(), 0)
assert.Equal(t, "1.27 MB", rolo.RolodexFileSizeAsString()) if runtime.GOOS != "windows" {
assert.Equal(t, "1.27 MB", rolo.RolodexFileSizeAsString())
} else {
assert.Equal(t, "1.32 MB", rolo.RolodexFileSizeAsString())
}
assert.Equal(t, 1699, rolo.RolodexTotalFiles()) assert.Equal(t, 1699, rolo.RolodexTotalFiles())
} }
@@ -330,7 +335,11 @@ func TestSpecIndex_DigitalOcean_FullCheckoutLocalResolve_RecursiveLookup(t *test
assert.Len(t, rolo.GetCaughtErrors(), 0) assert.Len(t, rolo.GetCaughtErrors(), 0)
assert.Len(t, rolo.GetIgnoredCircularReferences(), 0) assert.Len(t, rolo.GetIgnoredCircularReferences(), 0)
assert.Equal(t, "1.21 MB", rolo.RolodexFileSizeAsString()) if runtime.GOOS != "windows" {
assert.Equal(t, "1.21 MB", rolo.RolodexFileSizeAsString())
} else {
assert.Equal(t, "1.26 MB", rolo.RolodexFileSizeAsString())
}
assert.Equal(t, 1685, rolo.RolodexTotalFiles()) assert.Equal(t, 1685, rolo.RolodexTotalFiles())
} }
@@ -414,6 +423,20 @@ func TestSpecIndex_BaseURLError(t *testing.T) {
// create a new remote fs and set the config for indexing. // create a new remote fs and set the config for indexing.
remoteFS, _ := NewRemoteFSWithConfig(cf) remoteFS, _ := NewRemoteFSWithConfig(cf)
// create a handler that uses an env variable to capture any GH_PAT in the OS ENV
// and inject it into the request header, so this does not fail when running lots of local tests.
if os.Getenv("GH_PAT") != "" {
fmt.Println("GH_PAT found, setting remote handler func")
client := &http.Client{
Timeout: time.Second * 120,
}
remoteFS.SetRemoteHandlerFunc(func(url string) (*http.Response, error) {
request, _ := http.NewRequest(http.MethodGet, url, nil)
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", os.Getenv("GH_PAT")))
return client.Do(request)
})
}
// add remote filesystem // add remote filesystem
rolo.AddRemoteFS(location, remoteFS) rolo.AddRemoteFS(location, remoteFS)
@@ -781,8 +804,14 @@ func TestSpecIndex_BurgerShopMixedRef(t *testing.T) {
assert.Len(t, index.GetCircularReferences(), 0) assert.Len(t, index.GetCircularReferences(), 0)
// get the size of the rolodex. // get the size of the rolodex.
assert.Equal(t, int64(60226), rolo.RolodexFileSize()+int64(len(yml)))
assert.Equal(t, "50.48 KB", rolo.RolodexFileSizeAsString()) if runtime.GOOS != "windows" {
assert.Equal(t, int64(60226), rolo.RolodexFileSize()+int64(len(yml)))
assert.Equal(t, "50.48 KB", rolo.RolodexFileSizeAsString())
} else {
assert.Equal(t, int64(62128), rolo.RolodexFileSize()+int64(len(yml)))
assert.Equal(t, "52.09 KB", rolo.RolodexFileSizeAsString())
}
assert.Equal(t, 3, rolo.RolodexTotalFiles()) assert.Equal(t, 3, rolo.RolodexTotalFiles())
} }

View File

@@ -134,11 +134,11 @@ func extractRequiredReferenceProperties(fulldef string, idx *SpecIndex, required
abs, _ = filepath.Abs(filepath.Join(filepath.Dir(u.Path), r[0])) abs, _ = filepath.Abs(filepath.Join(filepath.Dir(u.Path), r[0]))
} }
u.Path = abs u.Path = utils.ReplaceWindowsDriveWithLinuxPath(abs)
u.Fragment = "" u.Fragment = ""
defPath = fmt.Sprintf("%s#/%s", u.String(), r[1]) defPath = fmt.Sprintf("%s#/%s", u.String(), r[1])
} else { } else {
u.Path = filepath.Join(filepath.Dir(u.Path), r[0]) u.Path = utils.ReplaceWindowsDriveWithLinuxPath(filepath.Join(filepath.Dir(u.Path), r[0]))
u.Fragment = "" u.Fragment = ""
defPath = u.String() defPath = u.String()
} }
@@ -166,11 +166,11 @@ func extractRequiredReferenceProperties(fulldef string, idx *SpecIndex, required
r := strings.Split(refName, "#/") r := strings.Split(refName, "#/")
if len(r) == 2 { if len(r) == 2 {
abs, _ := filepath.Abs(filepath.Join(filepath.Dir(u.Path), r[0])) abs, _ := filepath.Abs(filepath.Join(filepath.Dir(u.Path), r[0]))
u.Path = abs u.Path = utils.ReplaceWindowsDriveWithLinuxPath(abs)
u.Fragment = "" u.Fragment = ""
defPath = fmt.Sprintf("%s#/%s", u.String(), r[1]) defPath = fmt.Sprintf("%s#/%s", u.String(), r[1])
} else { } else {
u.Path = filepath.Join(filepath.Dir(u.Path), r[0]) u.Path = utils.ReplaceWindowsDriveWithLinuxPath(filepath.Join(filepath.Dir(u.Path), r[0]))
u.Fragment = "" u.Fragment = ""
defPath = u.String() defPath = u.String()
} }

View File

@@ -5,6 +5,9 @@ package index
import ( import (
"net/url" "net/url"
"os"
"path/filepath"
"runtime"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@@ -110,7 +113,11 @@ func Test_extractRequiredReferenceProperties_abs3(t *testing.T) {
data := extractRequiredReferenceProperties("/big/fat/camel.yaml#/milk", nil, data := extractRequiredReferenceProperties("/big/fat/camel.yaml#/milk", nil,
rootNode.Content[0], "cakes", props) rootNode.Content[0], "cakes", props)
assert.Len(t, props, 1) assert.Len(t, props, 1)
assert.Equal(t, "cakes", props["/big/fat/oh/pillow.yaml"][0]) if runtime.GOOS != "windows" {
assert.Equal(t, "cakes", props["/big/fat/oh/pillow.yaml"][0])
} else {
assert.Equal(t, "cakes", props["C:\\big\\fat\\oh\\pillow.yaml"][0])
}
assert.NotNil(t, data) assert.NotNil(t, data)
} }
@@ -124,7 +131,11 @@ func Test_extractRequiredReferenceProperties_rel_full(t *testing.T) {
data := extractRequiredReferenceProperties("/chalky/milky/camel.yaml#/milk", nil, data := extractRequiredReferenceProperties("/chalky/milky/camel.yaml#/milk", nil,
rootNode.Content[0], "cakes", props) rootNode.Content[0], "cakes", props)
assert.Len(t, props, 1) assert.Len(t, props, 1)
assert.Equal(t, "cakes", props["/chalky/milky/camel.yaml#/a/nice/picture/of/cake"][0]) if runtime.GOOS != "windows" {
assert.Equal(t, "cakes", props["/chalky/milky/camel.yaml#/a/nice/picture/of/cake"][0])
} else {
assert.Equal(t, "cakes", props["C:\\chalky\\milky\\camel.yaml#/a/nice/picture/of/cake"][0])
}
assert.NotNil(t, data) assert.NotNil(t, data)
} }
@@ -138,7 +149,11 @@ func Test_extractRequiredReferenceProperties_rel(t *testing.T) {
data := extractRequiredReferenceProperties("/camel.yaml#/milk", nil, data := extractRequiredReferenceProperties("/camel.yaml#/milk", nil,
rootNode.Content[0], "cakes", props) rootNode.Content[0], "cakes", props)
assert.Len(t, props, 1) assert.Len(t, props, 1)
assert.Equal(t, "cakes", props["/oh/camel.yaml#/rum/cake"][0]) if runtime.GOOS != "windows" {
assert.Equal(t, "cakes", props["/oh/camel.yaml#/rum/cake"][0])
} else {
assert.Equal(t, "cakes", props["C:\\oh\\camel.yaml#/rum/cake"][0])
}
assert.NotNil(t, data) assert.NotNil(t, data)
} }
@@ -152,7 +167,12 @@ func Test_extractRequiredReferenceProperties_abs2(t *testing.T) {
data := extractRequiredReferenceProperties("../flannel.yaml#/milk", nil, data := extractRequiredReferenceProperties("../flannel.yaml#/milk", nil,
rootNode.Content[0], "cakes", props) rootNode.Content[0], "cakes", props)
assert.Len(t, props, 1) assert.Len(t, props, 1)
assert.Equal(t, "cakes", props["/oh/my/camel.yaml#/rum/cake"][0]) if runtime.GOOS != "windows" {
assert.Equal(t, "cakes", props["/oh/my/camel.yaml#/rum/cake"][0])
} else {
cwd, _ := os.Getwd()
assert.Equal(t, "cakes", props[filepath.Dir(cwd)+"\\oh\\my\\camel.yaml#/rum/cake"][0])
}
assert.NotNil(t, data) assert.NotNil(t, data)
} }
@@ -236,7 +256,11 @@ func Test_extractRequiredReferenceProperties_nocomponent_http2(t *testing.T) {
data := extractRequiredReferenceProperties("/why.yaml", nil, data := extractRequiredReferenceProperties("/why.yaml", nil,
rootNode.Content[0], "cakes", props) rootNode.Content[0], "cakes", props)
assert.Len(t, props, 1) assert.Len(t, props, 1)
assert.Equal(t, "cakes", props["/go-to-bed.com/no/more/cake.yaml"][0]) if runtime.GOOS != "windows" {
assert.Equal(t, "cakes", props["/go-to-bed.com/no/more/cake.yaml"][0])
} else {
assert.Equal(t, "cakes", props["C:\\go-to-bed.com\\no\\more\\cake.yaml"][0])
}
assert.NotNil(t, data) assert.NotNil(t, data)
} }

11
utils/windows_drive.go Normal file
View File

@@ -0,0 +1,11 @@
package utils
import "strings"
func ReplaceWindowsDriveWithLinuxPath(path string) string {
if len(path) > 1 && path[1] == ':' {
path = strings.ReplaceAll(path, "\\", "/")
return path[2:]
}
return strings.ReplaceAll(path, "\\", "/")
}

View File

@@ -0,0 +1,19 @@
package utils
import "testing"
func TestReplaceWindowsDriveWithLinuxPath(t *testing.T) {
path := `C:\Users\pb33f\go\src\github.com\pb33f\libopenapi\utils\windows_drive_test.go`
expected := `/Users/pb33f/go/src/github.com/pb33f/libopenapi/utils/windows_drive_test.go`
result := ReplaceWindowsDriveWithLinuxPath(path)
if result != expected {
t.Errorf("Expected %s, got %s", expected, result)
}
path = `/do/not/replace/this/path`
expected = `/do/not/replace/this/path`
result = ReplaceWindowsDriveWithLinuxPath(path)
if result != expected {
t.Errorf("Expected %s, got %s", expected, result)
}
}