github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/cmd/apply.go (about) 1 package cmd 2 3 import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "path/filepath" 8 "strings" 9 10 "github.com/qri-io/dataset" 11 "github.com/qri-io/ioes" 12 "github.com/qri-io/qri/lib" 13 "github.com/qri-io/qri/repo" 14 "github.com/spf13/cobra" 15 ) 16 17 // NewApplyCommand creates a new `qri apply` cobra command for applying transformations 18 func NewApplyCommand(f Factory, ioStreams ioes.IOStreams) *cobra.Command { 19 o := &ApplyOptions{IOStreams: ioStreams} 20 cmd := &cobra.Command{ 21 Use: "apply", 22 Short: "apply a transform to a dataset", 23 Long: `Apply runs a transform script. The result of the transform is displayed after 24 the command completes. 25 26 The apply command itself does not commit results to the repository. Use 27 the --apply flag on the save command to commit results from transforms.`, 28 Example: ` # Apply a transform and display the output: 29 $ qri apply --file transform.star 30 31 # Apply a transform using an existing dataset version: 32 $ qri apply --file transform.star me/my_dataset`, 33 Annotations: map[string]string{ 34 "group": "dataset", 35 }, 36 RunE: func(cmd *cobra.Command, args []string) error { 37 if err := o.Complete(f, args); err != nil { 38 return err 39 } 40 return o.Run() 41 }, 42 } 43 44 cmd.Flags().StringVar(&o.FilePath, "file", "", "path of transform script file") 45 cmd.MarkFlagRequired("file") 46 cmd.Flags().StringSliceVar(&o.Secrets, "secrets", nil, "transform secrets as comma separated key,value,key,value,... sequence") 47 cmd.Flags().BoolVar(&o.Quiet, "quiet", false, "whether to suppress output from the application") 48 49 return cmd 50 } 51 52 // ApplyOptions encapsulates state for the apply command 53 type ApplyOptions struct { 54 ioes.IOStreams 55 56 Instance *lib.Instance 57 58 Refs *RefSelect 59 FilePath string 60 Quiet bool 61 Secrets []string 62 } 63 64 // Complete adds any missing configuration that can only be added just before calling Run 65 func (o *ApplyOptions) Complete(f Factory, args []string) (err error) { 66 if o.Instance, err = f.Instance(); err != nil { 67 return err 68 } 69 if o.Refs, err = GetCurrentRefSelect(f, args, -1); err != nil { 70 // This error will be handled during validation 71 if err != repo.ErrEmptyRef { 72 return err 73 } 74 err = nil 75 } 76 o.FilePath, err = filepath.Abs(o.FilePath) 77 if err != nil { 78 return err 79 } 80 return nil 81 } 82 83 // Run executes the apply command 84 func (o *ApplyOptions) Run() (err error) { 85 86 if !strings.HasSuffix(o.FilePath, ".star") { 87 return errors.New("only transform scripts are supported by --file") 88 } 89 90 ctx := context.TODO() 91 inst := o.Instance 92 93 tf := dataset.Transform{ 94 ScriptPath: o.FilePath, 95 } 96 97 if len(o.Secrets) > 0 { 98 tf.Secrets, err = parseSecrets(o.Secrets...) 99 if err != nil { 100 return err 101 } 102 } 103 104 params := lib.ApplyParams{ 105 Ref: o.Refs.Ref(), 106 Transform: &tf, 107 ScriptOutput: o.Out, 108 Wait: true, 109 } 110 111 terminalWidth, terminalHeight := sizeOfTerminal() 112 if terminalWidth > 0 && terminalHeight > 0 { 113 params.OutputWidth = terminalWidth 114 params.OutputHeight = terminalHeight 115 } 116 117 res, err := inst.Automation().Apply(ctx, ¶ms) 118 if err != nil { 119 return err 120 } 121 122 if !o.Quiet { 123 data, err := json.MarshalIndent(res.Data, "", " ") 124 if err != nil { 125 return err 126 } 127 printSuccess(o.Out, string(data)) 128 } 129 return nil 130 }