-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(RefResolver): introduce RefResolver interface, use in DatasetReq…
…uests.Get Reference resolution returns a "canonicalized" dsref with the InitID and HEAD Path assigned. Multiple subsystems now implement the RefResolver interface. lib.Instance composes these multiple implementations in a predetermined order to resolve a reference. Future implementations of the RefResolver interface can use network calls to do foreign reference resolution. Thsi commit introduces `/fsi` as a path prefix for data persisted using qri's file system integration, setting the stage for pushing fsi integration farther down the qri import hierarchy, toward being another implementation of a qfs.Filesystem on the read side.
- Loading branch information
Showing
18 changed files
with
386 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package lib | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/qri-io/dataset" | ||
"github.com/qri-io/qri/base/dsfs" | ||
"github.com/qri-io/qri/dsref" | ||
"github.com/qri-io/qri/fsi" | ||
"github.com/qri-io/qri/resolve" | ||
) | ||
|
||
// assert at compile time that instance is a RefResolver | ||
var _ resolve.RefResolver = (*Instance)(nil) | ||
|
||
// ParseAndResolveRef combines reference parsing and resolution | ||
func (inst *Instance) ParseAndResolveRef(ctx context.Context, refStr string) (dsref.Ref, error) { | ||
ref, err := dsref.Parse(refStr) | ||
|
||
// bad case references are allowed-but-warned for backwards compatibility | ||
if errors.Is(err, dsref.ErrBadCaseName) { | ||
log.Error(dsref.ErrBadCaseShouldRename) | ||
err = nil | ||
} else if err != nil { | ||
return ref, fmt.Errorf("%q is not a valid dataset reference: %w", refStr, err) | ||
} | ||
|
||
err = inst.ResolveRef(ctx, &ref) | ||
return ref, err | ||
} | ||
|
||
// ResolveRef finds the identifier for a dataset reference | ||
func (inst *Instance) ResolveRef(ctx context.Context, ref *dsref.Ref) error { | ||
if inst == nil { | ||
return resolve.ErrCannotResolveName | ||
} | ||
|
||
resolvers := []resolve.RefResolver{ | ||
// local resolution | ||
inst.dscache, | ||
inst.repo, | ||
inst.logbook, | ||
|
||
// network resolution | ||
// inst.registry, | ||
// inst.QriNode | ||
} | ||
|
||
for _, r := range resolvers { | ||
err := r.ResolveRef(ctx, ref) | ||
if err == nil { | ||
return nil | ||
} else if errors.Is(err, resolve.ErrCannotResolveName) { | ||
continue | ||
} | ||
|
||
return err | ||
} | ||
|
||
return resolve.ErrCannotResolveName | ||
} | ||
|
||
// TODO (b5) - this needs to move down into base, replacing base.LoadDataset with | ||
// a version that can load paths with a /fsi prefix, but before that can happen | ||
// base needs to be able to import FSI. Currently FSI imports base, and doesn't | ||
// really need to. Most of the base package functions used by FSI should be in | ||
// FSI, as they deal with filesystem interaction. | ||
func (inst *Instance) loadDataset(ctx context.Context, ref dsref.Ref) (*dataset.Dataset, error) { | ||
var ( | ||
ds *dataset.Dataset | ||
err error | ||
) | ||
|
||
if strings.HasPrefix(ref.Path, "/fsi") { | ||
// Has an FSI Path, load from working directory | ||
if ds, err = fsi.ReadDir(strings.TrimPrefix(ref.Path, "/fsi")); err != nil { | ||
return nil, err | ||
} | ||
} else { | ||
// Load from dsfs | ||
if ds, err = dsfs.LoadDataset(ctx, inst.store, ref.Path); err != nil { | ||
return nil, err | ||
} | ||
} | ||
// Set transient info on the returned dataset | ||
ds.Name = ref.Name | ||
ds.Peername = ref.Username | ||
return ds, nil | ||
} |
Oops, something went wrong.