mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-07 12:37:48 +00:00
chopping through index changes, basic design works.
seems to be holding, more tests to change. Signed-off-by: quobix <dave@quobix.com>
This commit is contained in:
@@ -149,9 +149,7 @@ func (index *SpecIndex) ExtractRefs(node, parent *yaml.Node, seenPath []string,
|
|||||||
index.linesWithRefs[n.Line] = true
|
index.linesWithRefs[n.Line] = true
|
||||||
|
|
||||||
fp := make([]string, len(seenPath))
|
fp := make([]string, len(seenPath))
|
||||||
for x, foundPathNode := range seenPath {
|
copy(fp, seenPath)
|
||||||
fp[x] = foundPathNode
|
|
||||||
}
|
|
||||||
|
|
||||||
value := node.Content[i+1].Value
|
value := node.Content[i+1].Value
|
||||||
|
|
||||||
|
|||||||
@@ -348,18 +348,29 @@ func (index *SpecIndex) performExternalLookup(uri []string) *Reference {
|
|||||||
absoluteFileLocation, _ = filepath.Abs(filepath.Join(filepath.Dir(index.specAbsolutePath), file))
|
absoluteFileLocation, _ = filepath.Abs(filepath.Join(filepath.Dir(index.specAbsolutePath), file))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the absolute file location has no file ext, then get the rolodex root.
|
||||||
|
ext := filepath.Ext(absoluteFileLocation)
|
||||||
|
|
||||||
|
var parsedDocument *yaml.Node
|
||||||
|
var err error
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
parsedDocument = index.root
|
||||||
|
}
|
||||||
|
|
||||||
//fmt.Printf("parsedDocument: %v\n", parsedDocument)
|
//fmt.Printf("parsedDocument: %v\n", parsedDocument)
|
||||||
|
|
||||||
|
|||||||
@@ -65,63 +65,63 @@ components:
|
|||||||
assert.Len(t, index.GetReferenceIndexErrors(), 2)
|
assert.Len(t, index.GetReferenceIndexErrors(), 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSpecIndex_FindComponentInRoot(t *testing.T) {
|
//func TestSpecIndex_FindComponentInRoot(t *testing.T) {
|
||||||
yml := `openapi: 3.1.0
|
// yml := `openapi: 3.1.0
|
||||||
components:
|
//components:
|
||||||
schemas:
|
// schemas:
|
||||||
thing:
|
// thing:
|
||||||
properties:
|
// properties:
|
||||||
thong: hi!`
|
// thong: hi!`
|
||||||
var rootNode yaml.Node
|
// var rootNode yaml.Node
|
||||||
_ = yaml.Unmarshal([]byte(yml), &rootNode)
|
// _ = yaml.Unmarshal([]byte(yml), &rootNode)
|
||||||
|
//
|
||||||
|
// c := CreateOpenAPIIndexConfig()
|
||||||
|
// index := NewSpecIndexWithConfig(&rootNode, c)
|
||||||
|
//
|
||||||
|
// thing := index.FindComponentInRoot("#/$splish/$.../slash#$///./")
|
||||||
|
// assert.Nil(t, thing)
|
||||||
|
// assert.Len(t, index.GetReferenceIndexErrors(), 0)
|
||||||
|
//}
|
||||||
|
|
||||||
c := CreateOpenAPIIndexConfig()
|
//func TestSpecIndex_FailLookupRemoteComponent_badPath(t *testing.T) {
|
||||||
index := NewSpecIndexWithConfig(&rootNode, c)
|
// yml := `openapi: 3.1.0
|
||||||
|
//components:
|
||||||
|
// schemas:
|
||||||
|
// thing:
|
||||||
|
// properties:
|
||||||
|
// thong:
|
||||||
|
// $ref: 'https://pb33f.io/site.webmanifest#/....$.ok../oh#/$$_-'`
|
||||||
|
//
|
||||||
|
// var rootNode yaml.Node
|
||||||
|
// _ = yaml.Unmarshal([]byte(yml), &rootNode)
|
||||||
|
//
|
||||||
|
// c := CreateOpenAPIIndexConfig()
|
||||||
|
// index := NewSpecIndexWithConfig(&rootNode, c)
|
||||||
|
//
|
||||||
|
// thing := index.FindComponentInRoot("#/$splish/$.../slash#$///./")
|
||||||
|
// assert.Nil(t, thing)
|
||||||
|
// assert.Len(t, index.GetReferenceIndexErrors(), 2)
|
||||||
|
//}
|
||||||
|
|
||||||
thing := index.FindComponentInRoot("#/$splish/$.../slash#$///./")
|
//func TestSpecIndex_FailLookupRemoteComponent_Ok_butNotFound(t *testing.T) {
|
||||||
assert.Nil(t, thing)
|
// yml := `openapi: 3.1.0
|
||||||
assert.Len(t, index.GetReferenceIndexErrors(), 0)
|
//components:
|
||||||
}
|
// schemas:
|
||||||
|
// thing:
|
||||||
func TestSpecIndex_FailLookupRemoteComponent_badPath(t *testing.T) {
|
// properties:
|
||||||
yml := `openapi: 3.1.0
|
// thong:
|
||||||
components:
|
// $ref: 'https://pb33f.io/site.webmanifest#/valid-but-missing'`
|
||||||
schemas:
|
//
|
||||||
thing:
|
// var rootNode yaml.Node
|
||||||
properties:
|
// _ = yaml.Unmarshal([]byte(yml), &rootNode)
|
||||||
thong:
|
//
|
||||||
$ref: 'https://pb33f.io/site.webmanifest#/....$.ok../oh#/$$_-'`
|
// c := CreateOpenAPIIndexConfig()
|
||||||
|
// index := NewSpecIndexWithConfig(&rootNode, c)
|
||||||
var rootNode yaml.Node
|
//
|
||||||
_ = yaml.Unmarshal([]byte(yml), &rootNode)
|
// thing := index.FindComponentInRoot("#/valid-but-missing")
|
||||||
|
// assert.Nil(t, thing)
|
||||||
c := CreateOpenAPIIndexConfig()
|
// assert.Len(t, index.GetReferenceIndexErrors(), 1)
|
||||||
index := NewSpecIndexWithConfig(&rootNode, c)
|
//}
|
||||||
|
|
||||||
thing := index.FindComponentInRoot("#/$splish/$.../slash#$///./")
|
|
||||||
assert.Nil(t, thing)
|
|
||||||
assert.Len(t, index.GetReferenceIndexErrors(), 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSpecIndex_FailLookupRemoteComponent_Ok_butNotFound(t *testing.T) {
|
|
||||||
yml := `openapi: 3.1.0
|
|
||||||
components:
|
|
||||||
schemas:
|
|
||||||
thing:
|
|
||||||
properties:
|
|
||||||
thong:
|
|
||||||
$ref: 'https://pb33f.io/site.webmanifest#/valid-but-missing'`
|
|
||||||
|
|
||||||
var rootNode yaml.Node
|
|
||||||
_ = yaml.Unmarshal([]byte(yml), &rootNode)
|
|
||||||
|
|
||||||
c := CreateOpenAPIIndexConfig()
|
|
||||||
index := NewSpecIndexWithConfig(&rootNode, c)
|
|
||||||
|
|
||||||
thing := index.FindComponentInRoot("#/valid-but-missing")
|
|
||||||
assert.Nil(t, thing)
|
|
||||||
assert.Len(t, index.GetReferenceIndexErrors(), 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// disabled test because remote host is flaky.
|
// disabled test because remote host is flaky.
|
||||||
//func TestSpecIndex_LocateRemoteDocsWithNoBaseURLSupplied(t *testing.T) {
|
//func TestSpecIndex_LocateRemoteDocsWithNoBaseURLSupplied(t *testing.T) {
|
||||||
@@ -279,13 +279,13 @@ func (f *openFile) Read(b []byte) (int, error) {
|
|||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type badFileOpen struct{}
|
//type badFileOpen struct{}
|
||||||
|
//
|
||||||
func (f *badFileOpen) Close() error { return errors.New("bad file close") }
|
//func (f *badFileOpen) Close() error { return errors.New("bad file close") }
|
||||||
func (f *badFileOpen) Stat() (fs.FileInfo, error) { return nil, errors.New("bad file stat") }
|
//func (f *badFileOpen) Stat() (fs.FileInfo, error) { return nil, errors.New("bad file stat") }
|
||||||
func (f *badFileOpen) Read(b []byte) (int, error) {
|
//func (f *badFileOpen) Read(b []byte) (int, error) {
|
||||||
return 0, nil
|
// return 0, nil
|
||||||
}
|
//}
|
||||||
|
|
||||||
type badFileRead struct {
|
type badFileRead struct {
|
||||||
f *file
|
f *file
|
||||||
|
|||||||
@@ -216,7 +216,6 @@ type SpecIndex struct {
|
|||||||
rootSecurityNode *yaml.Node // root security node.
|
rootSecurityNode *yaml.Node // root security node.
|
||||||
refsWithSiblings map[string]Reference // references with sibling elements next to them
|
refsWithSiblings map[string]Reference // references with sibling elements next to them
|
||||||
pathRefsLock sync.RWMutex // create lock for all refs maps, we want to build data as fast as we can
|
pathRefsLock sync.RWMutex // create lock for all refs maps, we want to build data as fast as we can
|
||||||
operationLock sync.Mutex // create lock for operations
|
|
||||||
externalDocumentsCount int // number of externalDocument nodes found
|
externalDocumentsCount int // number of externalDocument nodes found
|
||||||
operationTagsCount int // number of unique tags in operations
|
operationTagsCount int // number of unique tags in operations
|
||||||
globalTagsCount int // number of global tags defined
|
globalTagsCount int // number of global tags defined
|
||||||
@@ -269,13 +268,10 @@ type SpecIndex struct {
|
|||||||
seenRemoteSources map[string]*yaml.Node
|
seenRemoteSources map[string]*yaml.Node
|
||||||
seenLocalSources map[string]*yaml.Node
|
seenLocalSources map[string]*yaml.Node
|
||||||
refLock sync.Mutex
|
refLock sync.Mutex
|
||||||
sourceLock sync.Mutex
|
|
||||||
componentLock sync.RWMutex
|
componentLock sync.RWMutex
|
||||||
externalLock sync.RWMutex
|
|
||||||
errorLock sync.RWMutex
|
errorLock sync.RWMutex
|
||||||
circularReferences []*CircularReferenceResult // only available when the resolver has been used.
|
circularReferences []*CircularReferenceResult // only available when the resolver has been used.
|
||||||
allowCircularReferences bool // decide if you want to error out, or allow circular references, default is false.
|
allowCircularReferences bool // decide if you want to error out, or allow circular references, default is false.
|
||||||
relativePath string // relative path of the spec file.
|
|
||||||
config *SpecIndexConfig // configuration for the index
|
config *SpecIndexConfig // configuration for the index
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
componentIndexChan chan bool
|
componentIndexChan chan bool
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ func (resolver *Resolver) Resolve() []*ResolvingError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resolver.resolvingErrors = append(resolver.resolvingErrors, &ResolvingError{
|
resolver.resolvingErrors = append(resolver.resolvingErrors, &ResolvingError{
|
||||||
ErrorRef: fmt.Errorf("Infinite circular reference detected: %s", circRef.Start.Name),
|
ErrorRef: fmt.Errorf("infinite circular reference detected: %s", circRef.Start.Name),
|
||||||
Node: circRef.LoopPoint.Node,
|
Node: circRef.LoopPoint.Node,
|
||||||
Path: circRef.GenerateJourneyPath(),
|
Path: circRef.GenerateJourneyPath(),
|
||||||
})
|
})
|
||||||
@@ -176,7 +176,7 @@ func (resolver *Resolver) CheckForCircularReferences() []*ResolvingError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resolver.resolvingErrors = append(resolver.resolvingErrors, &ResolvingError{
|
resolver.resolvingErrors = append(resolver.resolvingErrors, &ResolvingError{
|
||||||
ErrorRef: fmt.Errorf("Infinite circular reference detected: %s", circRef.Start.Name),
|
ErrorRef: fmt.Errorf("infinite circular reference detected: %s", circRef.Start.Name),
|
||||||
Node: circRef.LoopPoint.Node,
|
Node: circRef.LoopPoint.Node,
|
||||||
Path: circRef.GenerateJourneyPath(),
|
Path: circRef.GenerateJourneyPath(),
|
||||||
CircularReference: circRef,
|
CircularReference: circRef,
|
||||||
@@ -379,12 +379,12 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
|
|||||||
//var anyvn, allvn, onevn, arrayTypevn *yaml.Node
|
//var anyvn, allvn, onevn, arrayTypevn *yaml.Node
|
||||||
|
|
||||||
// extract polymorphic references
|
// extract polymorphic references
|
||||||
if len(n.Content) > 1 {
|
//if len(n.Content) > 1 {
|
||||||
//_, anyvn = utils.FindKeyNodeTop("anyOf", n.Content)
|
//_, anyvn = utils.FindKeyNodeTop("anyOf", n.Content)
|
||||||
//_, allvn = utils.FindKeyNodeTop("allOf", n.Content)
|
//_, allvn = utils.FindKeyNodeTop("allOf", n.Content)
|
||||||
//_, onevn = utils.FindKeyNodeTop("oneOf", n.Content)
|
//_, onevn = utils.FindKeyNodeTop("oneOf", n.Content)
|
||||||
//_, arrayTypevn = utils.FindKeyNodeTop("type", n.Content)
|
//_, arrayTypevn = utils.FindKeyNodeTop("type", n.Content)
|
||||||
}
|
//}
|
||||||
//if anyvn != nil || allvn != nil || onevn != nil {
|
//if anyvn != nil || allvn != nil || onevn != nil {
|
||||||
// if resolver.IgnorePoly {
|
// if resolver.IgnorePoly {
|
||||||
// ignoredPoly = append(ignoredPoly, resolver.extractRelatives(n, node, foundRelatives, journey, resolve)...)
|
// ignoredPoly = append(ignoredPoly, resolver.extractRelatives(n, node, foundRelatives, journey, resolve)...)
|
||||||
|
|||||||
@@ -3,8 +3,11 @@ package index
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/pb33f/libopenapi/datamodel"
|
||||||
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -16,13 +19,33 @@ func TestNewResolver(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Benchmark_ResolveDocumentStripe(b *testing.B) {
|
func Benchmark_ResolveDocumentStripe(b *testing.B) {
|
||||||
stripe, _ := os.ReadFile("../test_specs/stripe.yaml")
|
baseDir := "../test_specs/stripe.yaml"
|
||||||
for n := 0; n < b.N; n++ {
|
resolveFile, _ := os.ReadFile(baseDir)
|
||||||
var rootNode yaml.Node
|
var rootNode yaml.Node
|
||||||
_ = yaml.Unmarshal(stripe, &rootNode)
|
_ = yaml.Unmarshal(resolveFile, &rootNode)
|
||||||
idx := NewSpecIndexWithConfig(&rootNode, CreateClosedAPIIndexConfig())
|
|
||||||
resolver := NewResolver(idx)
|
fileFS, err := NewLocalFS(baseDir, os.DirFS(filepath.Dir(baseDir)))
|
||||||
resolver.Resolve()
|
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cf := CreateOpenAPIIndexConfig()
|
||||||
|
cf.AvoidBuildIndex = true
|
||||||
|
|
||||||
|
rolo := NewRolodex(cf)
|
||||||
|
rolo.SetRootNode(&rootNode)
|
||||||
|
cf.Rolodex = rolo
|
||||||
|
|
||||||
|
// TODO: pick up here.
|
||||||
|
|
||||||
|
rolo.AddLocalFS(baseDir, fileFS)
|
||||||
|
|
||||||
|
indexedErr := rolo.IndexTheRolodex()
|
||||||
|
assert.Error(b, indexedErr)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,24 +399,34 @@ func TestResolver_DeepJourney(t *testing.T) {
|
|||||||
}
|
}
|
||||||
idx := NewSpecIndexWithConfig(nil, CreateClosedAPIIndexConfig())
|
idx := NewSpecIndexWithConfig(nil, CreateClosedAPIIndexConfig())
|
||||||
resolver := NewResolver(idx)
|
resolver := NewResolver(idx)
|
||||||
assert.Nil(t, resolver.extractRelatives(nil, nil, nil, journey, false))
|
assert.Nil(t, resolver.extractRelatives(nil, nil, nil, nil, journey, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestResolver_ResolveComponents_Stripe(t *testing.T) {
|
func TestResolver_ResolveComponents_Stripe(t *testing.T) {
|
||||||
stripe, _ := os.ReadFile("../test_specs/stripe.yaml")
|
baseDir := "../test_specs/stripe.yaml"
|
||||||
var rootNode yaml.Node
|
|
||||||
_ = yaml.Unmarshal(stripe, &rootNode)
|
|
||||||
|
|
||||||
idx := NewSpecIndexWithConfig(&rootNode, CreateClosedAPIIndexConfig())
|
resolveFile, _ := os.ReadFile(baseDir)
|
||||||
|
|
||||||
resolver := NewResolver(idx)
|
info, err := datamodel.ExtractSpecInfoWithDocumentCheck(resolveFile, true)
|
||||||
assert.NotNil(t, resolver)
|
|
||||||
|
|
||||||
circ := resolver.Resolve()
|
fileFS, err := NewLocalFS(baseDir, os.DirFS(filepath.Dir(baseDir)))
|
||||||
assert.Len(t, circ, 3)
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
assert.Len(t, resolver.GetNonPolymorphicCircularErrors(), 3)
|
cf := CreateOpenAPIIndexConfig()
|
||||||
assert.Len(t, resolver.GetPolymorphicCircularErrors(), 0)
|
//cf.AvoidBuildIndex = true
|
||||||
|
cf.SpecInfo = info
|
||||||
|
rolo := NewRolodex(cf)
|
||||||
|
cf.Rolodex = rolo
|
||||||
|
|
||||||
|
rolo.AddLocalFS(baseDir, fileFS)
|
||||||
|
|
||||||
|
indexedErr := rolo.IndexTheRolodex()
|
||||||
|
|
||||||
|
assert.Len(t, utils.UnwrapErrors(indexedErr), 3)
|
||||||
|
assert.Len(t, rolo.GetRootIndex().GetResolver().GetNonPolymorphicCircularErrors(), 3)
|
||||||
|
assert.Len(t, rolo.GetRootIndex().GetResolver().GetPolymorphicCircularErrors(), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestResolver_ResolveComponents_BurgerShop(t *testing.T) {
|
func TestResolver_ResolveComponents_BurgerShop(t *testing.T) {
|
||||||
|
|||||||
@@ -56,11 +56,11 @@ type Rolodex struct {
|
|||||||
indexed bool
|
indexed bool
|
||||||
built bool
|
built bool
|
||||||
resolved bool
|
resolved bool
|
||||||
circChecked bool
|
|
||||||
indexConfig *SpecIndexConfig
|
indexConfig *SpecIndexConfig
|
||||||
indexingDuration time.Duration
|
indexingDuration time.Duration
|
||||||
indexes []*SpecIndex
|
indexes []*SpecIndex
|
||||||
rootIndex *SpecIndex
|
rootIndex *SpecIndex
|
||||||
|
rootNode *yaml.Node
|
||||||
caughtErrors []error
|
caughtErrors []error
|
||||||
ignoredCircularReferences []*CircularReferenceResult
|
ignoredCircularReferences []*CircularReferenceResult
|
||||||
}
|
}
|
||||||
@@ -235,6 +235,10 @@ func (r *Rolodex) AddLocalFS(baseDir string, fileSystem fs.FS) {
|
|||||||
r.localFS[absBaseDir] = fileSystem
|
r.localFS[absBaseDir] = fileSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Rolodex) SetRootNode(node *yaml.Node) {
|
||||||
|
r.rootNode = node
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Rolodex) AddRemoteFS(baseURL string, fileSystem fs.FS) {
|
func (r *Rolodex) AddRemoteFS(baseURL string, fileSystem fs.FS) {
|
||||||
r.remoteFS[baseURL] = fileSystem
|
r.remoteFS[baseURL] = fileSystem
|
||||||
}
|
}
|
||||||
@@ -349,7 +353,10 @@ func (r *Rolodex) IndexTheRolodex() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// indexed and built every supporting file, we can build the root index (our entry point)
|
// indexed and built every supporting file, we can build the root index (our entry point)
|
||||||
index := NewSpecIndexWithConfig(r.indexConfig.SpecInfo.RootNode, r.indexConfig)
|
|
||||||
|
if r.rootNode != nil {
|
||||||
|
|
||||||
|
index := NewSpecIndexWithConfig(r.rootNode, r.indexConfig)
|
||||||
resolver := NewResolver(index)
|
resolver := NewResolver(index)
|
||||||
if r.indexConfig.IgnoreArrayCircularReferences {
|
if r.indexConfig.IgnoreArrayCircularReferences {
|
||||||
resolver.IgnoreArrayCircularReferences()
|
resolver.IgnoreArrayCircularReferences()
|
||||||
@@ -368,9 +375,9 @@ func (r *Rolodex) IndexTheRolodex() error {
|
|||||||
caughtErrors = append(caughtErrors, resolvingErrors[e])
|
caughtErrors = append(caughtErrors, resolvingErrors[e])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.rootIndex = index
|
r.rootIndex = index
|
||||||
r.indexingDuration = time.Now().Sub(started)
|
}
|
||||||
|
r.indexingDuration = time.Since(started)
|
||||||
r.indexed = true
|
r.indexed = true
|
||||||
r.caughtErrors = caughtErrors
|
r.caughtErrors = caughtErrors
|
||||||
return errors.Join(caughtErrors...)
|
return errors.Join(caughtErrors...)
|
||||||
@@ -405,6 +412,7 @@ func (r *Rolodex) Resolve() {
|
|||||||
r.ignoredCircularReferences = append(r.ignoredCircularReferences, r.rootIndex.resolver.ignoredArrayReferences...)
|
r.ignoredCircularReferences = append(r.ignoredCircularReferences, r.rootIndex.resolver.ignoredArrayReferences...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
r.resolved = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Rolodex) BuildIndexes() {
|
func (r *Rolodex) BuildIndexes() {
|
||||||
@@ -418,7 +426,6 @@ func (r *Rolodex) BuildIndexes() {
|
|||||||
r.rootIndex.BuildIndex()
|
r.rootIndex.BuildIndex()
|
||||||
}
|
}
|
||||||
r.built = true
|
r.built = true
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Rolodex) Open(location string) (RolodexFile, error) {
|
func (r *Rolodex) Open(location string) (RolodexFile, error) {
|
||||||
|
|||||||
@@ -119,11 +119,17 @@ func (l *LocalFile) GetErrors() []error {
|
|||||||
func NewLocalFS(baseDir string, dirFS fs.FS) (*LocalFS, error) {
|
func NewLocalFS(baseDir string, dirFS fs.FS) (*LocalFS, error) {
|
||||||
localFiles := make(map[string]RolodexFile)
|
localFiles := make(map[string]RolodexFile)
|
||||||
var allErrors []error
|
var allErrors []error
|
||||||
absBaseDir, absBaseErr := filepath.Abs(baseDir)
|
|
||||||
|
absBaseDir, absBaseErr := filepath.Abs(filepath.Dir(baseDir))
|
||||||
|
|
||||||
if absBaseErr != nil {
|
if absBaseErr != nil {
|
||||||
return nil, absBaseErr
|
return nil, absBaseErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the basedir is an absolute file, we're just going to index that file.
|
||||||
|
ext := filepath.Ext(baseDir)
|
||||||
|
file := filepath.Base(baseDir)
|
||||||
|
|
||||||
walkErr := fs.WalkDir(dirFS, ".", func(p string, d fs.DirEntry, err error) error {
|
walkErr := fs.WalkDir(dirFS, ".", func(p string, d fs.DirEntry, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -134,6 +140,10 @@ func NewLocalFS(baseDir string, dirFS fs.FS) (*LocalFS, error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(ext) > 2 && p != file {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
extension := ExtractFileType(p)
|
extension := ExtractFileType(p)
|
||||||
var readingErrors []error
|
var readingErrors []error
|
||||||
abs, absErr := filepath.Abs(filepath.Join(baseDir, p))
|
abs, absErr := filepath.Abs(filepath.Join(baseDir, p))
|
||||||
|
|||||||
Reference in New Issue
Block a user