mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-07 20:47:45 +00:00
whacking the shit out of exploded use-cases
Before everything worked, but was completely accurate, now everything works and everything is absolute and can be resolved. Phew, what a mission! Signed-off-by: quobix <dave@quobix.com>
This commit is contained in:
@@ -54,6 +54,10 @@ func (index *SpecIndex) ExtractRefs(node, parent *yaml.Node, seenPath []string,
|
|||||||
definitionPath = fmt.Sprintf("#/%s", strings.Join(loc, "/"))
|
definitionPath = fmt.Sprintf("#/%s", strings.Join(loc, "/"))
|
||||||
fullDefinitionPath = fmt.Sprintf("%s#/%s", index.specAbsolutePath, strings.Join(loc, "/"))
|
fullDefinitionPath = fmt.Sprintf("%s#/%s", index.specAbsolutePath, strings.Join(loc, "/"))
|
||||||
_, jsonPath = utils.ConvertComponentIdIntoFriendlyPathSearch(definitionPath)
|
_, jsonPath = utils.ConvertComponentIdIntoFriendlyPathSearch(definitionPath)
|
||||||
|
} else {
|
||||||
|
definitionPath = fmt.Sprintf("#/%s", n.Value)
|
||||||
|
fullDefinitionPath = fmt.Sprintf("%s#/%s", index.specAbsolutePath, n.Value)
|
||||||
|
_, jsonPath = utils.ConvertComponentIdIntoFriendlyPathSearch(definitionPath)
|
||||||
}
|
}
|
||||||
ref := &Reference{
|
ref := &Reference{
|
||||||
FullDefinition: fullDefinitionPath,
|
FullDefinition: fullDefinitionPath,
|
||||||
@@ -105,7 +109,12 @@ func (index *SpecIndex) ExtractRefs(node, parent *yaml.Node, seenPath []string,
|
|||||||
definitionPath = fmt.Sprintf("#/%s", strings.Join(loc, "/"))
|
definitionPath = fmt.Sprintf("#/%s", strings.Join(loc, "/"))
|
||||||
fullDefinitionPath = fmt.Sprintf("%s#/%s", index.specAbsolutePath, strings.Join(loc, "/"))
|
fullDefinitionPath = fmt.Sprintf("%s#/%s", index.specAbsolutePath, strings.Join(loc, "/"))
|
||||||
_, jsonPath = utils.ConvertComponentIdIntoFriendlyPathSearch(definitionPath)
|
_, jsonPath = utils.ConvertComponentIdIntoFriendlyPathSearch(definitionPath)
|
||||||
|
} else {
|
||||||
|
definitionPath = fmt.Sprintf("#/%s", n.Value)
|
||||||
|
fullDefinitionPath = fmt.Sprintf("%s#/%s", index.specAbsolutePath, n.Value)
|
||||||
|
_, jsonPath = utils.ConvertComponentIdIntoFriendlyPathSearch(definitionPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
ref := &Reference{
|
ref := &Reference{
|
||||||
FullDefinition: fullDefinitionPath,
|
FullDefinition: fullDefinitionPath,
|
||||||
Definition: definitionPath,
|
Definition: definitionPath,
|
||||||
@@ -145,7 +154,12 @@ func (index *SpecIndex) ExtractRefs(node, parent *yaml.Node, seenPath []string,
|
|||||||
definitionPath = fmt.Sprintf("#/%s", strings.Join(loc, "/"))
|
definitionPath = fmt.Sprintf("#/%s", strings.Join(loc, "/"))
|
||||||
fullDefinitionPath = fmt.Sprintf("%s#/%s", index.specAbsolutePath, strings.Join(loc, "/"))
|
fullDefinitionPath = fmt.Sprintf("%s#/%s", index.specAbsolutePath, strings.Join(loc, "/"))
|
||||||
_, jsonPath = utils.ConvertComponentIdIntoFriendlyPathSearch(definitionPath)
|
_, jsonPath = utils.ConvertComponentIdIntoFriendlyPathSearch(definitionPath)
|
||||||
|
} else {
|
||||||
|
definitionPath = fmt.Sprintf("#/%s", n.Value)
|
||||||
|
fullDefinitionPath = fmt.Sprintf("%s#/%s", index.specAbsolutePath, n.Value)
|
||||||
|
_, jsonPath = utils.ConvertComponentIdIntoFriendlyPathSearch(definitionPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
ref := &Reference{
|
ref := &Reference{
|
||||||
FullDefinition: fullDefinitionPath,
|
FullDefinition: fullDefinitionPath,
|
||||||
Definition: definitionPath,
|
Definition: definitionPath,
|
||||||
@@ -407,6 +421,7 @@ func (index *SpecIndex) ExtractRefs(node, parent *yaml.Node, seenPath []string,
|
|||||||
//} else {
|
//} else {
|
||||||
// index.allRefs[value] = ref
|
// index.allRefs[value] = ref
|
||||||
//}
|
//}
|
||||||
|
|
||||||
index.allRefs[fullDefinitionPath] = ref
|
index.allRefs[fullDefinitionPath] = ref
|
||||||
found = append(found, ref)
|
found = append(found, ref)
|
||||||
}
|
}
|
||||||
@@ -597,13 +612,13 @@ func (index *SpecIndex) ExtractComponentsFromRefs(refs []*Reference) []*Referenc
|
|||||||
if located != nil {
|
if located != nil {
|
||||||
index.refLock.Lock()
|
index.refLock.Lock()
|
||||||
// have we already mapped this?
|
// have we already mapped this?
|
||||||
if index.allMappedRefs[ref.Definition] == nil {
|
if index.allMappedRefs[ref.FullDefinition] == nil {
|
||||||
found = append(found, located)
|
found = append(found, located)
|
||||||
if located.FullDefinition != ref.FullDefinition {
|
if located.FullDefinition != ref.FullDefinition {
|
||||||
located.FullDefinition = ref.FullDefinition
|
located.FullDefinition = ref.FullDefinition
|
||||||
}
|
}
|
||||||
|
|
||||||
index.allMappedRefs[ref.Definition] = located
|
index.allMappedRefs[ref.FullDefinition] = located
|
||||||
rm := &ReferenceMapped{
|
rm := &ReferenceMapped{
|
||||||
Reference: located,
|
Reference: located,
|
||||||
Definition: ref.Definition,
|
Definition: ref.Definition,
|
||||||
@@ -612,7 +627,7 @@ func (index *SpecIndex) ExtractComponentsFromRefs(refs []*Reference) []*Referenc
|
|||||||
sequence[refIndex] = rm
|
sequence[refIndex] = rm
|
||||||
} else {
|
} else {
|
||||||
// it exists, but is it a component with the same ID?
|
// it exists, but is it a component with the same ID?
|
||||||
d := index.allMappedRefs[ref.Definition]
|
d := index.allMappedRefs[ref.FullDefinition]
|
||||||
|
|
||||||
// if the full definition matches, we're good and can skip this.
|
// if the full definition matches, we're good and can skip this.
|
||||||
if d.FullDefinition != ref.FullDefinition {
|
if d.FullDefinition != ref.FullDefinition {
|
||||||
|
|||||||
@@ -4,80 +4,80 @@
|
|||||||
package index
|
package index
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath"
|
"github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FindComponent will locate a component by its reference, returns nil if nothing is found.
|
// FindComponent will locate a component by its reference, returns nil if nothing is found.
|
||||||
// This method will recurse through remote, local and file references. For each new external reference
|
// This method will recurse through remote, local and file references. For each new external reference
|
||||||
// a new index will be created. These indexes can then be traversed recursively.
|
// a new index will be created. These indexes can then be traversed recursively.
|
||||||
func (index *SpecIndex) FindComponent(componentId string, parent *yaml.Node) *Reference {
|
func (index *SpecIndex) FindComponent(componentId string, parent *yaml.Node) *Reference {
|
||||||
if index.root == nil {
|
if index.root == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//remoteLookup := func(id string) (*yaml.Node, *yaml.Node, error) {
|
//remoteLookup := func(id string) (*yaml.Node, *yaml.Node, error) {
|
||||||
// if index.config.AllowRemoteLookup {
|
// if index.config.AllowRemoteLookup {
|
||||||
// return index.lookupRemoteReference(id)
|
// return index.lookupRemoteReference(id)
|
||||||
// } else {
|
// } else {
|
||||||
// return nil, nil, fmt.Errorf("remote lookups are not permitted, " +
|
// return nil, nil, fmt.Errorf("remote lookups are not permitted, " +
|
||||||
// "please set AllowRemoteLookup to true in the configuration")
|
// "please set AllowRemoteLookup to true in the configuration")
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//fileLookup := func(id string) (*yaml.Node, *yaml.Node, error) {
|
//fileLookup := func(id string) (*yaml.Node, *yaml.Node, error) {
|
||||||
// if index.config.AllowFileLookup {
|
// if index.config.AllowFileLookup {
|
||||||
// return index.lookupFileReference(id)
|
// return index.lookupFileReference(id)
|
||||||
// } else {
|
// } else {
|
||||||
// return nil, nil, fmt.Errorf("local lookups are not permitted, " +
|
// return nil, nil, fmt.Errorf("local lookups are not permitted, " +
|
||||||
// "please set AllowFileLookup to true in the configuration")
|
// "please set AllowFileLookup to true in the configuration")
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//witch DetermineReferenceResolveType(componentId) {
|
//witch DetermineReferenceResolveType(componentId) {
|
||||||
//case LocalResolve: // ideally, every single ref in every single spec is local. however, this is not the case.
|
//case LocalResolve: // ideally, every single ref in every single spec is local. however, this is not the case.
|
||||||
//return index.FindComponentInRoot(componentId)
|
//return index.FindComponentInRoot(componentId)
|
||||||
|
|
||||||
//case HttpResolve, FileResolve:
|
//case HttpResolve, FileResolve:
|
||||||
|
|
||||||
uri := strings.Split(componentId, "#/")
|
uri := strings.Split(componentId, "#/")
|
||||||
if len(uri) == 2 {
|
if len(uri) == 2 {
|
||||||
if uri[0] != "" {
|
if uri[0] != "" {
|
||||||
if index.specAbsolutePath == uri[0] {
|
if index.specAbsolutePath == uri[0] {
|
||||||
return index.FindComponentInRoot(fmt.Sprintf("#/%s", uri[1]))
|
return index.FindComponentInRoot(fmt.Sprintf("#/%s", uri[1]))
|
||||||
} else {
|
} else {
|
||||||
return index.lookupRolodex(uri)
|
return index.lookupRolodex(uri)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return index.FindComponentInRoot(fmt.Sprintf("#/%s", uri[1]))
|
return index.FindComponentInRoot(fmt.Sprintf("#/%s", uri[1]))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !strings.Contains(componentId, "#") {
|
if !strings.Contains(componentId, "#") {
|
||||||
|
|
||||||
// does it contain a file extension?
|
// does it contain a file extension?
|
||||||
fileExt := filepath.Ext(componentId)
|
fileExt := filepath.Ext(componentId)
|
||||||
if fileExt != "" {
|
if fileExt != "" {
|
||||||
return index.lookupRolodex(uri)
|
return index.lookupRolodex(uri)
|
||||||
}
|
}
|
||||||
|
|
||||||
// root search
|
// root search
|
||||||
return index.FindComponentInRoot(componentId)
|
return index.FindComponentInRoot(componentId)
|
||||||
|
|
||||||
}
|
}
|
||||||
return index.FindComponentInRoot(fmt.Sprintf("#/%s", uri[0]))
|
return index.FindComponentInRoot(fmt.Sprintf("#/%s", uri[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
//}
|
//}
|
||||||
//return nil
|
//return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var httpClient = &http.Client{Timeout: time.Duration(60) * time.Second}
|
var httpClient = &http.Client{Timeout: time.Duration(60) * time.Second}
|
||||||
@@ -85,18 +85,18 @@ var httpClient = &http.Client{Timeout: time.Duration(60) * time.Second}
|
|||||||
type RemoteURLHandler = func(url string) (*http.Response, error)
|
type RemoteURLHandler = func(url string) (*http.Response, error)
|
||||||
|
|
||||||
func getRemoteDoc(g RemoteURLHandler, u string, d chan []byte, e chan error) {
|
func getRemoteDoc(g RemoteURLHandler, u string, d chan []byte, e chan error) {
|
||||||
resp, err := g(u)
|
resp, err := g(u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e <- err
|
e <- err
|
||||||
close(e)
|
close(e)
|
||||||
close(d)
|
close(d)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var body []byte
|
var body []byte
|
||||||
body, _ = io.ReadAll(resp.Body)
|
body, _ = io.ReadAll(resp.Body)
|
||||||
d <- body
|
d <- body
|
||||||
close(e)
|
close(e)
|
||||||
close(d)
|
close(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
//func (index *SpecIndex) lookupRemoteReference(ref string) (*yaml.Node, *yaml.Node, error) {
|
//func (index *SpecIndex) lookupRemoteReference(ref string) (*yaml.Node, *yaml.Node, error) {
|
||||||
@@ -315,255 +315,255 @@ func getRemoteDoc(g RemoteURLHandler, u string, d chan []byte, e chan error) {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
func FindComponent(root *yaml.Node, componentId, absoluteFilePath string) *Reference {
|
func FindComponent(root *yaml.Node, componentId, absoluteFilePath string) *Reference {
|
||||||
// check component for url encoding.
|
// check component for url encoding.
|
||||||
if strings.Contains(componentId, "%") {
|
if strings.Contains(componentId, "%") {
|
||||||
// decode the url.
|
// decode the url.
|
||||||
componentId, _ = url.QueryUnescape(componentId)
|
componentId, _ = url.QueryUnescape(componentId)
|
||||||
}
|
}
|
||||||
|
|
||||||
name, friendlySearch := utils.ConvertComponentIdIntoFriendlyPathSearch(componentId)
|
name, friendlySearch := utils.ConvertComponentIdIntoFriendlyPathSearch(componentId)
|
||||||
path, err := yamlpath.NewPath(friendlySearch)
|
path, err := yamlpath.NewPath(friendlySearch)
|
||||||
if path == nil || err != nil {
|
if path == nil || err != nil {
|
||||||
return nil // no component found
|
return nil // no component found
|
||||||
}
|
}
|
||||||
res, _ := path.Find(root)
|
res, _ := path.Find(root)
|
||||||
|
|
||||||
if len(res) == 1 {
|
if len(res) == 1 {
|
||||||
resNode := res[0]
|
resNode := res[0]
|
||||||
if res[0].Kind == yaml.DocumentNode {
|
if res[0].Kind == yaml.DocumentNode {
|
||||||
resNode = res[0].Content[0]
|
resNode = res[0].Content[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
fullDef := fmt.Sprintf("%s%s", absoluteFilePath, componentId)
|
fullDef := fmt.Sprintf("%s%s", absoluteFilePath, componentId)
|
||||||
|
|
||||||
// extract properties
|
// extract properties
|
||||||
|
|
||||||
ref := &Reference{
|
ref := &Reference{
|
||||||
FullDefinition: fullDef,
|
FullDefinition: fullDef,
|
||||||
Definition: componentId,
|
Definition: componentId,
|
||||||
Name: name,
|
Name: name,
|
||||||
Node: resNode,
|
Node: resNode,
|
||||||
Path: friendlySearch,
|
Path: friendlySearch,
|
||||||
RequiredRefProperties: extractDefinitionRequiredRefProperties(resNode, map[string][]string{}, fullDef),
|
RequiredRefProperties: extractDefinitionRequiredRefProperties(resNode, map[string][]string{}, fullDef),
|
||||||
}
|
}
|
||||||
|
|
||||||
return ref
|
return ref
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (index *SpecIndex) FindComponentInRoot(componentId string) *Reference {
|
func (index *SpecIndex) FindComponentInRoot(componentId string) *Reference {
|
||||||
if index.root != nil {
|
if index.root != nil {
|
||||||
return FindComponent(index.root, componentId, index.specAbsolutePath)
|
return FindComponent(index.root, componentId, index.specAbsolutePath)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (index *SpecIndex) lookupRolodex(uri []string) *Reference {
|
func (index *SpecIndex) lookupRolodex(uri []string) *Reference {
|
||||||
|
|
||||||
if len(uri) > 0 {
|
if len(uri) > 0 {
|
||||||
|
|
||||||
// split string to remove file reference
|
// split string to remove file reference
|
||||||
file := strings.ReplaceAll(uri[0], "file:", "")
|
file := strings.ReplaceAll(uri[0], "file:", "")
|
||||||
|
|
||||||
var absoluteFileLocation, fileName string
|
var absoluteFileLocation, fileName string
|
||||||
|
|
||||||
// is this a local or a remote file?
|
// is this a local or a remote file?
|
||||||
|
|
||||||
fileName = filepath.Base(file)
|
fileName = filepath.Base(file)
|
||||||
if filepath.IsAbs(file) || strings.HasPrefix(file, "http") {
|
if filepath.IsAbs(file) || strings.HasPrefix(file, "http") {
|
||||||
absoluteFileLocation = file
|
absoluteFileLocation = file
|
||||||
} else {
|
} else {
|
||||||
if index.specAbsolutePath != "" {
|
if index.specAbsolutePath != "" {
|
||||||
if index.config.BaseURL != nil {
|
if index.config.BaseURL != nil {
|
||||||
|
|
||||||
// consider the file remote.
|
// consider the file remote.
|
||||||
//if strings.Contains(file, "../../") {
|
//if strings.Contains(file, "../../") {
|
||||||
|
|
||||||
// extract the base path from the specAbsolutePath for this index.
|
// extract the base path from the specAbsolutePath for this index.
|
||||||
sap, _ := url.Parse(index.specAbsolutePath)
|
sap, _ := url.Parse(index.specAbsolutePath)
|
||||||
newPath, _ := filepath.Abs(filepath.Join(filepath.Dir(sap.Path), file))
|
newPath, _ := filepath.Abs(filepath.Join(filepath.Dir(sap.Path), file))
|
||||||
|
|
||||||
sap.Path = newPath
|
sap.Path = newPath
|
||||||
f := sap.String()
|
f := sap.String()
|
||||||
absoluteFileLocation = f
|
absoluteFileLocation = f
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//loc := fmt.Sprintf("%s%s", index.config.BaseURL.Path, file)
|
//loc := fmt.Sprintf("%s%s", index.config.BaseURL.Path, file)
|
||||||
|
|
||||||
//absoluteFileLocation = loc
|
//absoluteFileLocation = loc
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// consider the file local
|
// consider the file local
|
||||||
|
|
||||||
dir := filepath.Dir(index.config.SpecAbsolutePath)
|
dir := filepath.Dir(index.config.SpecAbsolutePath)
|
||||||
absoluteFileLocation, _ = filepath.Abs(filepath.Join(dir, file))
|
absoluteFileLocation, _ = filepath.Abs(filepath.Join(dir, file))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
absoluteFileLocation = file
|
absoluteFileLocation = file
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the absolute file location has no file ext, then get the rolodex root.
|
// if the absolute file location has no file ext, then get the rolodex root.
|
||||||
ext := filepath.Ext(absoluteFileLocation)
|
ext := filepath.Ext(absoluteFileLocation)
|
||||||
|
|
||||||
var parsedDocument *yaml.Node
|
var parsedDocument *yaml.Node
|
||||||
var err error
|
var err error
|
||||||
if ext != "" {
|
if ext != "" {
|
||||||
|
|
||||||
// extract the document from the rolodex.
|
// extract the document from the rolodex.
|
||||||
rFile, rError := index.rolodex.Open(absoluteFileLocation)
|
rFile, rError := index.rolodex.Open(absoluteFileLocation)
|
||||||
|
|
||||||
if rError != nil {
|
if rError != nil {
|
||||||
logger.Error("unable to open rolodex file", "file", absoluteFileLocation, "error", rError)
|
logger.Error("unable to open rolodex file", "file", absoluteFileLocation, "error", rError)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if rFile == nil {
|
if rFile == nil {
|
||||||
logger.Error("rolodex file is empty!", "file", absoluteFileLocation)
|
logger.Error("rolodex file is empty!", "file", absoluteFileLocation)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedDocument, err = rFile.GetContentAsYAMLNode()
|
parsedDocument, err = rFile.GetContentAsYAMLNode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("unable to parse rolodex file", "file", absoluteFileLocation, "error", err)
|
logger.Error("unable to parse rolodex file", "file", absoluteFileLocation, "error", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
parsedDocument = index.root
|
parsedDocument = index.root
|
||||||
}
|
}
|
||||||
|
|
||||||
//fmt.Printf("parsedDocument: %v\n", parsedDocument)
|
//fmt.Printf("parsedDocument: %v\n", parsedDocument)
|
||||||
|
|
||||||
//index.externalLock.RLock()
|
//index.externalLock.RLock()
|
||||||
//externalSpecIndex := index.externalSpecIndex[uri[0]]
|
//externalSpecIndex := index.externalSpecIndex[uri[0]]
|
||||||
//index.externalLock.RUnlock()
|
//index.externalLock.RUnlock()
|
||||||
|
|
||||||
//if externalSpecIndex == nil {
|
//if externalSpecIndex == nil {
|
||||||
// _, newRoot, err := lookupFunction(componentId)
|
// _, newRoot, err := lookupFunction(componentId)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// indexError := &IndexingError{
|
// indexError := &IndexingError{
|
||||||
// Err: err,
|
// Err: err,
|
||||||
// Node: parent,
|
// Node: parent,
|
||||||
// Path: componentId,
|
// Path: componentId,
|
||||||
// }
|
// }
|
||||||
// index.errorLock.Lock()
|
// index.errorLock.Lock()
|
||||||
// index.refErrors = append(index.refErrors, indexError)
|
// index.refErrors = append(index.refErrors, indexError)
|
||||||
// index.errorLock.Unlock()
|
// index.errorLock.Unlock()
|
||||||
// return nil
|
// return nil
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// // cool, cool, lets index this spec also. This is a recursive action and will keep going
|
// // cool, cool, lets index this spec also. This is a recursive action and will keep going
|
||||||
// // until all remote references have been found.
|
// // until all remote references have been found.
|
||||||
// var bp *url.URL
|
// var bp *url.URL
|
||||||
// var bd string
|
// var bd string
|
||||||
//
|
//
|
||||||
// if index.config.BaseURL != nil {
|
// if index.config.BaseURL != nil {
|
||||||
// bp = index.config.BaseURL
|
// bp = index.config.BaseURL
|
||||||
// }
|
// }
|
||||||
// if index.config.BasePath != "" {
|
// if index.config.BasePath != "" {
|
||||||
// bd = index.config.BasePath
|
// bd = index.config.BasePath
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// var path, newBasePath string
|
// var path, newBasePath string
|
||||||
// var newUrl *url.URL
|
// var newUrl *url.URL
|
||||||
//
|
//
|
||||||
// if bp != nil {
|
// if bp != nil {
|
||||||
// path = GenerateCleanSpecConfigBaseURL(bp, uri[0], false)
|
// path = GenerateCleanSpecConfigBaseURL(bp, uri[0], false)
|
||||||
// newUrl, _ = url.Parse(path)
|
// newUrl, _ = url.Parse(path)
|
||||||
// newBasePath = filepath.Dir(filepath.Join(index.config.BasePath, filepath.Dir(newUrl.Path)))
|
// newBasePath = filepath.Dir(filepath.Join(index.config.BasePath, filepath.Dir(newUrl.Path)))
|
||||||
// }
|
// }
|
||||||
// if bd != "" {
|
// if bd != "" {
|
||||||
// if len(uri[0]) > 0 {
|
// if len(uri[0]) > 0 {
|
||||||
// // if there is no base url defined, but we can know we have been requested remotely,
|
// // if there is no base url defined, but we can know we have been requested remotely,
|
||||||
// // set the base url to the remote url base path.
|
// // set the base url to the remote url base path.
|
||||||
// // first check if the first param is actually a URL
|
// // first check if the first param is actually a URL
|
||||||
// io, er := url.ParseRequestURI(uri[0])
|
// io, er := url.ParseRequestURI(uri[0])
|
||||||
// if er != nil {
|
// if er != nil {
|
||||||
// newBasePath = filepath.Dir(filepath.Join(bd, uri[0]))
|
// newBasePath = filepath.Dir(filepath.Join(bd, uri[0]))
|
||||||
// } else {
|
// } else {
|
||||||
// if newUrl == nil || newUrl.String() != io.String() {
|
// if newUrl == nil || newUrl.String() != io.String() {
|
||||||
// newUrl, _ = url.Parse(fmt.Sprintf("%s://%s%s", io.Scheme, io.Host, filepath.Dir(io.Path)))
|
// newUrl, _ = url.Parse(fmt.Sprintf("%s://%s%s", io.Scheme, io.Host, filepath.Dir(io.Path)))
|
||||||
// }
|
// }
|
||||||
// newBasePath = filepath.Dir(filepath.Join(bd, uri[1]))
|
// newBasePath = filepath.Dir(filepath.Join(bd, uri[1]))
|
||||||
// }
|
// }
|
||||||
// } else {
|
// } else {
|
||||||
// newBasePath = filepath.Dir(filepath.Join(bd, uri[0]))
|
// newBasePath = filepath.Dir(filepath.Join(bd, uri[0]))
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// if newUrl != nil || newBasePath != "" {
|
// if newUrl != nil || newBasePath != "" {
|
||||||
// newConfig := &SpecIndexConfig{
|
// newConfig := &SpecIndexConfig{
|
||||||
// BaseURL: newUrl,
|
// BaseURL: newUrl,
|
||||||
// BasePath: newBasePath,
|
// BasePath: newBasePath,
|
||||||
// AllowRemoteLookup: index.config.AllowRemoteLookup,
|
// AllowRemoteLookup: index.config.AllowRemoteLookup,
|
||||||
// AllowFileLookup: index.config.AllowFileLookup,
|
// AllowFileLookup: index.config.AllowFileLookup,
|
||||||
// ParentIndex: index,
|
// ParentIndex: index,
|
||||||
// seenRemoteSources: index.config.seenRemoteSources,
|
// seenRemoteSources: index.config.seenRemoteSources,
|
||||||
// remoteLock: index.config.remoteLock,
|
// remoteLock: index.config.remoteLock,
|
||||||
// uri: uri,
|
// uri: uri,
|
||||||
// AvoidBuildIndex: index.config.AvoidBuildIndex,
|
// AvoidBuildIndex: index.config.AvoidBuildIndex,
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// var newIndex *SpecIndex
|
// var newIndex *SpecIndex
|
||||||
// seen := index.SearchAncestryForSeenURI(uri[0])
|
// seen := index.SearchAncestryForSeenURI(uri[0])
|
||||||
// if seen == nil {
|
// if seen == nil {
|
||||||
//
|
//
|
||||||
// newIndex = NewSpecIndexWithConfig(newRoot, newConfig)
|
// newIndex = NewSpecIndexWithConfig(newRoot, newConfig)
|
||||||
// index.refLock.Lock()
|
// index.refLock.Lock()
|
||||||
// index.externalLock.Lock()
|
// index.externalLock.Lock()
|
||||||
// index.externalSpecIndex[uri[0]] = newIndex
|
// index.externalSpecIndex[uri[0]] = newIndex
|
||||||
// index.externalLock.Unlock()
|
// index.externalLock.Unlock()
|
||||||
// newIndex.relativePath = path
|
// newIndex.relativePath = path
|
||||||
// newIndex.parentIndex = index
|
// newIndex.parentIndex = index
|
||||||
// index.AddChild(newIndex)
|
// index.AddChild(newIndex)
|
||||||
// index.refLock.Unlock()
|
// index.refLock.Unlock()
|
||||||
// externalSpecIndex = newIndex
|
// externalSpecIndex = newIndex
|
||||||
// } else {
|
// } else {
|
||||||
// externalSpecIndex = seen
|
// externalSpecIndex = seen
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
wholeFile := false
|
wholeFile := false
|
||||||
query := ""
|
query := ""
|
||||||
if len(uri) < 2 {
|
if len(uri) < 2 {
|
||||||
wholeFile = true
|
wholeFile = true
|
||||||
} else {
|
} else {
|
||||||
query = fmt.Sprintf("#/%s", strings.Replace(uri[1], "~1", "./", 1))
|
query = fmt.Sprintf("#/%s", strings.Replace(uri[1], "~1", "./", 1))
|
||||||
query = strings.ReplaceAll(query, "~1", "/")
|
query = strings.ReplaceAll(query, "~1", "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if there is a component we want to suck in, or if the
|
// check if there is a component we want to suck in, or if the
|
||||||
// entire root needs to come in.
|
// entire root needs to come in.
|
||||||
var foundRef *Reference
|
var foundRef *Reference
|
||||||
if wholeFile {
|
if wholeFile {
|
||||||
if parsedDocument.Kind == yaml.DocumentNode {
|
if parsedDocument.Kind == yaml.DocumentNode {
|
||||||
parsedDocument = parsedDocument.Content[0]
|
parsedDocument = parsedDocument.Content[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remote locations
|
// TODO: remote locations
|
||||||
|
|
||||||
foundRef = &Reference{
|
foundRef = &Reference{
|
||||||
FullDefinition: absoluteFileLocation,
|
FullDefinition: absoluteFileLocation,
|
||||||
Definition: fileName,
|
Definition: fileName,
|
||||||
Name: fileName,
|
Name: fileName,
|
||||||
Node: parsedDocument,
|
Node: parsedDocument,
|
||||||
IsRemote: true,
|
IsRemote: true,
|
||||||
RemoteLocation: absoluteFileLocation,
|
RemoteLocation: absoluteFileLocation,
|
||||||
Path: "$",
|
Path: "$",
|
||||||
RequiredRefProperties: extractDefinitionRequiredRefProperties(parsedDocument, map[string][]string{}, absoluteFileLocation),
|
RequiredRefProperties: extractDefinitionRequiredRefProperties(parsedDocument, map[string][]string{}, absoluteFileLocation),
|
||||||
}
|
}
|
||||||
return foundRef
|
return foundRef
|
||||||
} else {
|
} else {
|
||||||
foundRef = FindComponent(parsedDocument, query, absoluteFileLocation)
|
foundRef = FindComponent(parsedDocument, query, absoluteFileLocation)
|
||||||
if foundRef != nil {
|
if foundRef != nil {
|
||||||
foundRef.IsRemote = true
|
foundRef.IsRemote = true
|
||||||
foundRef.RemoteLocation = absoluteFileLocation
|
foundRef.RemoteLocation = absoluteFileLocation
|
||||||
return foundRef
|
return foundRef
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ func NewResolver(index *SpecIndex) *Resolver {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
r := &Resolver{
|
r := &Resolver{
|
||||||
|
|
||||||
specIndex: index,
|
specIndex: index,
|
||||||
resolvedRoot: index.GetRootNode(),
|
resolvedRoot: index.GetRootNode(),
|
||||||
}
|
}
|
||||||
@@ -336,7 +335,7 @@ func (resolver *Resolver) isInfiniteCircularDependency(ref *Reference, visitedDe
|
|||||||
}
|
}
|
||||||
|
|
||||||
for refDefinition := range ref.RequiredRefProperties {
|
for refDefinition := range ref.RequiredRefProperties {
|
||||||
r := resolver.specIndex.GetMappedReferences()[refDefinition]
|
r := resolver.specIndex.SearchIndexForReference(refDefinition)
|
||||||
if initialRef != nil && initialRef.Definition == r.Definition {
|
if initialRef != nil && initialRef.Definition == r.Definition {
|
||||||
return true, visitedDefinitions
|
return true, visitedDefinitions
|
||||||
}
|
}
|
||||||
@@ -434,11 +433,24 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// split the full def into parts
|
if filepath.IsAbs(exp[0]) {
|
||||||
fileDef := strings.Split(ref.FullDefinition, "#/")
|
fullDef = value
|
||||||
|
|
||||||
// extract the location of the ref and build a full def path.
|
} else {
|
||||||
fullDef = fmt.Sprintf("%s#/%s", fileDef[0], exp[1])
|
|
||||||
|
// split the referring ref full def into parts
|
||||||
|
fileDef := strings.Split(ref.FullDefinition, "#/")
|
||||||
|
|
||||||
|
// extract the location of the ref and build a full def path.
|
||||||
|
fullDef, _ = filepath.Abs(filepath.Join(filepath.Dir(fileDef[0]), exp[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
//// split the full def into parts
|
||||||
|
//fileDef := strings.Split(ref.FullDefinition, "#/")
|
||||||
|
//
|
||||||
|
//// extract the location of the ref and build a full def path.
|
||||||
|
//
|
||||||
|
//fullDef = fmt.Sprintf("%s#/%s", fileDef[0], exp[1])
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -470,9 +482,9 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
|
|||||||
fileDef := strings.Split(ref.FullDefinition, "#/")
|
fileDef := strings.Split(ref.FullDefinition, "#/")
|
||||||
|
|
||||||
// extract the location of the ref and build a full def path.
|
// extract the location of the ref and build a full def path.
|
||||||
loc, _ := filepath.Abs(filepath.Join(filepath.Dir(fileDef[0]), exp[0]))
|
//loc, _ := filepath.Abs(fileDef[0]), exp[1]))
|
||||||
|
|
||||||
fullDef = fmt.Sprintf("%s#/%s", loc, exp[1])
|
fullDef = fmt.Sprintf("%s#/%s", fileDef[0], exp[1])
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,7 +517,6 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// extract the location of the ref and build a full def path.
|
|
||||||
fullDef, _ = filepath.Abs(filepath.Join(filepath.Dir(fileDef[0]), exp[0]))
|
fullDef, _ = filepath.Abs(filepath.Join(filepath.Dir(fileDef[0]), exp[0]))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
899
index/rolodex.go
899
index/rolodex.go
File diff suppressed because it is too large
Load Diff
@@ -36,6 +36,7 @@ type RemoteFS struct {
|
|||||||
remoteErrors []error
|
remoteErrors []error
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
defaultClient *http.Client
|
defaultClient *http.Client
|
||||||
|
extractedFiles map[string]RolodexFile
|
||||||
}
|
}
|
||||||
|
|
||||||
type RemoteFile struct {
|
type RemoteFile struct {
|
||||||
@@ -158,7 +159,8 @@ func (f *RemoteFile) Index(config *SpecIndexConfig) (*SpecIndex, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
index := NewSpecIndexWithConfig(info.RootNode, config)
|
index := NewSpecIndexWithConfig(info.RootNode, config)
|
||||||
index.specAbsolutePath = f.fullPath
|
|
||||||
|
index.specAbsolutePath = config.SpecAbsolutePath
|
||||||
f.index = index
|
f.index = index
|
||||||
return index, nil
|
return index, nil
|
||||||
}
|
}
|
||||||
@@ -233,6 +235,7 @@ func (i *RemoteFS) GetFiles() map[string]RolodexFile {
|
|||||||
files[key.(string)] = value.(*RemoteFile)
|
files[key.(string)] = value.(*RemoteFile)
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
i.extractedFiles = files
|
||||||
return files
|
return files
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,6 +305,7 @@ func (i *RemoteFS) Open(remoteURL string) (fs.File, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
remoteParsedURLOriginal, _ := url.Parse(remoteURL)
|
||||||
|
|
||||||
// try path first
|
// try path first
|
||||||
if r, ok := i.Files.Load(remoteParsedURL.Path); ok {
|
if r, ok := i.Files.Load(remoteParsedURL.Path); ok {
|
||||||
@@ -418,7 +422,7 @@ func (i *RemoteFS) Open(remoteURL string) (fs.File, error) {
|
|||||||
|
|
||||||
copiedCfg := *i.indexConfig
|
copiedCfg := *i.indexConfig
|
||||||
|
|
||||||
newBase := fmt.Sprintf("%s://%s%s", remoteParsedURL.Scheme, remoteParsedURL.Host,
|
newBase := fmt.Sprintf("%s://%s%s", remoteParsedURLOriginal.Scheme, remoteParsedURLOriginal.Host,
|
||||||
filepath.Dir(remoteParsedURL.Path))
|
filepath.Dir(remoteParsedURL.Path))
|
||||||
newBaseURL, _ := url.Parse(newBase)
|
newBaseURL, _ := url.Parse(newBase)
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,19 @@ func (index *SpecIndex) SearchIndexForReferenceByReference(fullRef *Reference) *
|
|||||||
roloLookup, _ = filepath.Abs(filepath.Join(absPath, uri[0]))
|
roloLookup, _ = filepath.Abs(filepath.Join(absPath, uri[0]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
//roloLookup = absPath // hang on a jiffy whiffy
|
||||||
|
if filepath.Ext(uri[1]) != "" {
|
||||||
|
roloLookup = absPath
|
||||||
|
} else {
|
||||||
|
roloLookup = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
ref = fmt.Sprintf("%s#/%s", absPath, uri[1])
|
||||||
|
|
||||||
}
|
}
|
||||||
ref = fmt.Sprintf("#/%s", uri[1])
|
|
||||||
} else {
|
} else {
|
||||||
if filepath.IsAbs(uri[0]) {
|
if filepath.IsAbs(uri[0]) {
|
||||||
roloLookup = uri[0]
|
roloLookup = uri[0]
|
||||||
@@ -65,7 +76,9 @@ func (index *SpecIndex) SearchIndexForReferenceByReference(fullRef *Reference) *
|
|||||||
|
|
||||||
// extract the index from the rolodex file.
|
// extract the index from the rolodex file.
|
||||||
idx := rFile.GetIndex()
|
idx := rFile.GetIndex()
|
||||||
index.resolver.indexesVisited++
|
if index.resolver != nil {
|
||||||
|
index.resolver.indexesVisited++
|
||||||
|
}
|
||||||
if idx != nil {
|
if idx != nil {
|
||||||
|
|
||||||
// check mapped refs.
|
// check mapped refs.
|
||||||
|
|||||||
@@ -212,6 +212,12 @@ func TestSpecIndex_DigitalOcean_FullCheckoutLocalResolve(t *testing.T) {
|
|||||||
assert.Len(t, index.GetMappedReferencesSequenced(), 299)
|
assert.Len(t, index.GetMappedReferencesSequenced(), 299)
|
||||||
assert.Len(t, index.GetMappedReferences(), 299)
|
assert.Len(t, index.GetMappedReferences(), 299)
|
||||||
assert.Len(t, fileFS.GetErrors(), 0)
|
assert.Len(t, fileFS.GetErrors(), 0)
|
||||||
|
|
||||||
|
// check circular references
|
||||||
|
rolo.CheckForCircularReferences()
|
||||||
|
assert.Len(t, rolo.GetCaughtErrors(), 0)
|
||||||
|
assert.Len(t, rolo.GetIgnoredCircularReferences(), 0)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSpecIndex_DigitalOcean_LookupsNotAllowed(t *testing.T) {
|
func TestSpecIndex_DigitalOcean_LookupsNotAllowed(t *testing.T) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package index
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@@ -31,14 +32,14 @@ func (index *SpecIndex) extractDefinitionsAndSchemas(schemasNode *yaml.Node, pat
|
|||||||
Node: schema,
|
Node: schema,
|
||||||
Path: fmt.Sprintf("$.components.schemas.%s", name),
|
Path: fmt.Sprintf("$.components.schemas.%s", name),
|
||||||
ParentNode: schemasNode,
|
ParentNode: schemasNode,
|
||||||
RequiredRefProperties: extractDefinitionRequiredRefProperties(schemasNode, map[string][]string{}),
|
RequiredRefProperties: extractDefinitionRequiredRefProperties(schemasNode, map[string][]string{}, fullDef),
|
||||||
}
|
}
|
||||||
index.allComponentSchemaDefinitions[def] = ref
|
index.allComponentSchemaDefinitions[def] = ref
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// extractDefinitionRequiredRefProperties goes through the direct properties of a schema and extracts the map of required definitions from within it
|
// extractDefinitionRequiredRefProperties goes through the direct properties of a schema and extracts the map of required definitions from within it
|
||||||
func extractDefinitionRequiredRefProperties(schemaNode *yaml.Node, reqRefProps map[string][]string) map[string][]string {
|
func extractDefinitionRequiredRefProperties(schemaNode *yaml.Node, reqRefProps map[string][]string, fulldef string) map[string][]string {
|
||||||
if schemaNode == nil {
|
if schemaNode == nil {
|
||||||
return reqRefProps
|
return reqRefProps
|
||||||
}
|
}
|
||||||
@@ -73,7 +74,7 @@ func extractDefinitionRequiredRefProperties(schemaNode *yaml.Node, reqRefProps m
|
|||||||
// Check to see if the current property is directly embedded within the current schema, and handle its properties if so
|
// Check to see if the current property is directly embedded within the current schema, and handle its properties if so
|
||||||
_, paramPropertiesMapNode := utils.FindKeyNodeTop("properties", param.Content)
|
_, paramPropertiesMapNode := utils.FindKeyNodeTop("properties", param.Content)
|
||||||
if paramPropertiesMapNode != nil {
|
if paramPropertiesMapNode != nil {
|
||||||
reqRefProps = extractDefinitionRequiredRefProperties(param, reqRefProps)
|
reqRefProps = extractDefinitionRequiredRefProperties(param, reqRefProps, fulldef)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to see if the current property is polymorphic, and dive into that model if so
|
// Check to see if the current property is polymorphic, and dive into that model if so
|
||||||
@@ -81,7 +82,7 @@ func extractDefinitionRequiredRefProperties(schemaNode *yaml.Node, reqRefProps m
|
|||||||
_, ofNode := utils.FindKeyNodeTop(key, param.Content)
|
_, ofNode := utils.FindKeyNodeTop(key, param.Content)
|
||||||
if ofNode != nil {
|
if ofNode != nil {
|
||||||
for _, ofNodeItem := range ofNode.Content {
|
for _, ofNodeItem := range ofNode.Content {
|
||||||
reqRefProps = extractRequiredReferenceProperties(ofNodeItem, name, reqRefProps)
|
reqRefProps = extractRequiredReferenceProperties(fulldef, ofNodeItem, name, reqRefProps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,14 +95,14 @@ func extractDefinitionRequiredRefProperties(schemaNode *yaml.Node, reqRefProps m
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
reqRefProps = extractRequiredReferenceProperties(requiredPropDefNode, requiredPropertyNode.Value, reqRefProps)
|
reqRefProps = extractRequiredReferenceProperties(fulldef, requiredPropDefNode, requiredPropertyNode.Value, reqRefProps)
|
||||||
}
|
}
|
||||||
|
|
||||||
return reqRefProps
|
return reqRefProps
|
||||||
}
|
}
|
||||||
|
|
||||||
// extractRequiredReferenceProperties returns a map of definition names to the property or properties which reference it within a node
|
// extractRequiredReferenceProperties returns a map of definition names to the property or properties which reference it within a node
|
||||||
func extractRequiredReferenceProperties(requiredPropDefNode *yaml.Node, propName string, reqRefProps map[string][]string) map[string][]string {
|
func extractRequiredReferenceProperties(fulldef string, requiredPropDefNode *yaml.Node, propName string, reqRefProps map[string][]string) map[string][]string {
|
||||||
isRef, _, defPath := utils.IsNodeRefValue(requiredPropDefNode)
|
isRef, _, defPath := utils.IsNodeRefValue(requiredPropDefNode)
|
||||||
if !isRef {
|
if !isRef {
|
||||||
_, defItems := utils.FindKeyNodeTop("items", requiredPropDefNode.Content)
|
_, defItems := utils.FindKeyNodeTop("items", requiredPropDefNode.Content)
|
||||||
@@ -114,6 +115,69 @@ func extractRequiredReferenceProperties(requiredPropDefNode *yaml.Node, propName
|
|||||||
return reqRefProps
|
return reqRefProps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// explode defpath
|
||||||
|
exp := strings.Split(defPath, "#/")
|
||||||
|
if len(exp) == 2 {
|
||||||
|
if exp[0] != "" {
|
||||||
|
if !strings.HasPrefix(exp[0], "http") {
|
||||||
|
|
||||||
|
if !filepath.IsAbs(exp[0]) {
|
||||||
|
|
||||||
|
if strings.HasPrefix(fulldef, "http") {
|
||||||
|
|
||||||
|
u, _ := url.Parse(fulldef)
|
||||||
|
p := filepath.Dir(u.Path)
|
||||||
|
abs, _ := filepath.Abs(filepath.Join(p, exp[0]))
|
||||||
|
u.Path = abs
|
||||||
|
defPath = fmt.Sprintf("%s#/%s", u.String(), exp[1])
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
abs, _ := filepath.Abs(filepath.Join(filepath.Dir(fulldef), exp[0]))
|
||||||
|
defPath = fmt.Sprintf("%s#/%s", abs, exp[1])
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if strings.HasPrefix(exp[0], "http") {
|
||||||
|
|
||||||
|
defPath = exp[0]
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// file shit again
|
||||||
|
|
||||||
|
if filepath.IsAbs(exp[0]) {
|
||||||
|
|
||||||
|
defPath = exp[0]
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// check full def and decide what to do next.
|
||||||
|
if strings.HasPrefix(fulldef, "http") {
|
||||||
|
|
||||||
|
u, _ := url.Parse(fulldef)
|
||||||
|
p := filepath.Dir(u.Path)
|
||||||
|
abs, _ := filepath.Abs(filepath.Join(p, exp[0]))
|
||||||
|
u.Path = abs
|
||||||
|
defPath = u.String()
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
defPath, _ = filepath.Abs(filepath.Join(filepath.Dir(fulldef), exp[0]))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if _, ok := reqRefProps[defPath]; !ok {
|
if _, ok := reqRefProps[defPath]; !ok {
|
||||||
reqRefProps[defPath] = []string{}
|
reqRefProps[defPath] = []string{}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,5 +49,5 @@ func TestGenerateCleanSpecConfigBaseURL_HttpStrip(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSpecIndex_extractDefinitionRequiredRefProperties(t *testing.T) {
|
func TestSpecIndex_extractDefinitionRequiredRefProperties(t *testing.T) {
|
||||||
assert.Nil(t, extractDefinitionRequiredRefProperties(nil, nil))
|
assert.Nil(t, extractDefinitionRequiredRefProperties(nil, nil, ""))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user