github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/lib/resolve.go (about) 1 package lib 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/qri-io/qri/dsref" 8 "github.com/qri-io/qri/remote" 9 ) 10 11 // ParseAndResolveRef combines reference parsing and resolution 12 func (inst *Instance) ParseAndResolveRef(ctx context.Context, refStr, source string) (dsref.Ref, string, error) { 13 log.Debugf("inst.ParseAndResolveRef refStr=%q source=%q", refStr, source) 14 ref, err := dsref.Parse(refStr) 15 if err != nil { 16 return ref, "", fmt.Errorf("%q is not a valid dataset reference: %w", refStr, err) 17 } 18 19 // Resolve the reference 20 location, err := inst.ResolveReference(ctx, &ref, source) 21 if err != nil { 22 return ref, location, err 23 } 24 return ref, location, err 25 } 26 27 // ResolveReference finds the identifier & HEAD path for a dataset reference. 28 // the source parameter determines which subsystems of Qri to use when resolving 29 func (inst *Instance) ResolveReference(ctx context.Context, ref *dsref.Ref, source string) (string, error) { 30 log.Debugf("inst.ResolveReference ref=%q source=%q", ref, source) 31 if inst == nil { 32 return "", dsref.ErrRefNotFound 33 } 34 35 // Handle the "me" convenience shortcut 36 if ref.Username == "me" { 37 ref.Username = inst.cfg.Profile.Peername 38 } 39 40 resolver, err := inst.resolverForSource(source) 41 if err != nil { 42 log.Debug("inst.resolverForSource error=%q", err) 43 return "", err 44 } 45 46 return resolver.ResolveRef(ctx, ref) 47 } 48 49 func (inst *Instance) resolverForSource(source string) (dsref.Resolver, error) { 50 switch source { 51 case "": 52 return inst.defaultResolver(), nil 53 case "local": 54 return dsref.SequentialResolver( 55 inst.dscache, 56 inst.repo, 57 ), nil 58 case "network": 59 return dsref.ParallelResolver( 60 inst.registryResolver(), 61 inst.p2pResolver(), 62 ), nil 63 case "registry": 64 return inst.registryResolver(), nil 65 case "p2p": 66 return inst.p2pResolver(), nil 67 } 68 69 // TODO (b5) - source could be one of: 70 // * configured remote name 71 // * peername 72 // * peer multiaddress 73 // add support for peername & multiaddress resolution 74 addr, err := remote.Address(inst.GetConfig(), source) 75 if err != nil { 76 return nil, err 77 } 78 return inst.remoteClient.NewRemoteRefResolver(addr), nil 79 } 80 81 func (inst *Instance) defaultResolver() dsref.Resolver { 82 return dsref.SequentialResolver( 83 inst.dscache, 84 inst.repo, 85 dsref.ParallelResolver( 86 inst.registryResolver(), 87 // inst.node, 88 ), 89 ) 90 } 91 92 func (inst *Instance) registryResolver() dsref.Resolver { 93 var location string 94 if inst.cfg.Registry != nil { 95 location = inst.cfg.Registry.Location 96 } 97 return inst.remoteClient.NewRemoteRefResolver(location) 98 } 99 100 func (inst *Instance) p2pResolver() dsref.Resolver { 101 return inst.node.NewP2PRefResolver() 102 }