github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/cmd/pull.go (about) 1 package cmd 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/qri-io/ioes" 8 "github.com/qri-io/qri/lib" 9 reporef "github.com/qri-io/qri/repo/ref" 10 "github.com/spf13/cobra" 11 ) 12 13 // NewPullCommand creates an add command 14 func NewPullCommand(f Factory, ioStreams ioes.IOStreams) *cobra.Command { 15 o := &PullOptions{IOStreams: ioStreams} 16 cmd := &cobra.Command{ 17 Use: "pull DATASET [DATASET...]", 18 Aliases: []string{"add"}, 19 Short: "fetch & store datasets from other peers", 20 Long: `Pull downloads datasets and stores them locally, fetching the dataset log and 21 dataset version(s). By default pull fetches the latest version of a dataset. 22 `, 23 Example: ` # download a dataset log and latest version 24 $ qri pull b5/world_bank_population 25 26 # pull a specific version from a remote by hash 27 $ qri pull ramfox b5/world_bank_population@/ipfs/QmFoo...`, 28 Annotations: map[string]string{ 29 "group": "network", 30 }, 31 RunE: func(cmd *cobra.Command, args []string) error { 32 if err := o.Complete(f); err != nil { 33 return err 34 } 35 return o.Run(args) 36 }, 37 } 38 39 cmd.Flags().StringVar(&o.LinkDir, "link", "", "path to directory to link dataset to") 40 cmd.Flags().StringVar(&o.Source, "source", "", "location to pull from") 41 cmd.MarkFlagFilename("link") 42 cmd.Flags().BoolVar(&o.LogsOnly, "logs-only", false, "only fetch logs, skipping HEAD data") 43 44 return cmd 45 } 46 47 // PullOptions encapsulates state for the add command 48 type PullOptions struct { 49 ioes.IOStreams 50 LinkDir string 51 Source string 52 LogsOnly bool 53 54 inst *lib.Instance 55 } 56 57 // Complete adds any missing configuration that can only be added just before calling Run 58 func (o *PullOptions) Complete(f Factory) (err error) { 59 o.inst, err = f.Instance() 60 return 61 } 62 63 // Run adds another peer's dataset to this user's repo 64 func (o *PullOptions) Run(args []string) error { 65 66 if len(args) == 0 { 67 return fmt.Errorf("nothing to pull") 68 } 69 if len(args) > 1 && o.LinkDir != "" { 70 return fmt.Errorf("link flag can only be used with a single reference") 71 } 72 73 ctx := context.TODO() 74 75 for _, arg := range args { 76 p := &lib.PullParams{ 77 Ref: arg, 78 LogsOnly: o.LogsOnly, 79 } 80 81 res, err := o.inst.WithSource(o.Source).Dataset().Pull(ctx, p) 82 if err != nil { 83 return err 84 } 85 86 asRef := reporef.DatasetRef{ 87 Peername: res.Peername, 88 Name: res.Name, 89 Path: res.Path, 90 Dataset: res, 91 } 92 93 refStr := refStringer(asRef) 94 fmt.Fprintf(o.Out, "\n%s", refStr.String()) 95 } 96 97 return nil 98 }