github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/cli/create_filewatch.go (about) 1 package cli 2 3 import ( 4 "context" 5 "os" 6 "path/filepath" 7 "time" 8 9 "github.com/spf13/cobra" 10 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 "k8s.io/cli-runtime/pkg/genericclioptions" 12 13 "github.com/tilt-dev/tilt/internal/analytics" 14 engineanalytics "github.com/tilt-dev/tilt/internal/engine/analytics" 15 "github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1" 16 "github.com/tilt-dev/tilt/pkg/model" 17 ) 18 19 // A human-friendly CLI for creating file watches. 20 // 21 // (as opposed to the machine-friendly CLIs of create -f or apply -f) 22 type createFileWatchCmd struct { 23 helper *createHelper 24 cmd *cobra.Command 25 26 ignoreValues []string 27 } 28 29 var _ tiltCmd = &createFileWatchCmd{} 30 31 func newCreateFileWatchCmd(streams genericclioptions.IOStreams) *createFileWatchCmd { 32 helper := newCreateHelper(streams) 33 return &createFileWatchCmd{ 34 helper: helper, 35 } 36 } 37 38 func (c *createFileWatchCmd) name() model.TiltSubcommand { return "create" } 39 40 func (c *createFileWatchCmd) register() *cobra.Command { 41 cmd := &cobra.Command{ 42 Use: "filewatch [NAME] [PATHS] --ignore [IGNORES]", 43 DisableFlagsInUseLine: true, 44 Short: "Create a filewatch in a running tilt session", 45 Long: `Create a FileWatch in a running tilt session. 46 47 To create a file watch, first supply the name of the 48 watch so you can reference it later. Then supply the paths 49 to watch. All paths will be watched recursively. 50 51 On its own, a FileWatch is an object that watches a set 52 of files, and updates its status field with the most recent 53 file changed. 54 55 A FileWatch is intended to combine with other Tilt objects to 56 trigger events when a file changes. 57 `, 58 Aliases: []string{"fw"}, 59 Args: cobra.MinimumNArgs(2), 60 Example: `tilt create fw src-and-web src web --ignore=web/node_modules`, 61 } 62 63 cmd.Flags().StringSliceVar(&c.ignoreValues, "ignore", nil, 64 "Patterns to ignore. Supports same syntax as .dockerignore. Paths are relative to the current directory.") 65 66 c.helper.addFlags(cmd) 67 c.cmd = cmd 68 69 return cmd 70 } 71 72 func (c *createFileWatchCmd) run(ctx context.Context, args []string) error { 73 a := analytics.Get(ctx) 74 cmdTags := engineanalytics.CmdTags(map[string]string{}) 75 a.Incr("cmd.create-filewatch", cmdTags.AsMap()) 76 defer a.Flush(time.Second) 77 78 err := c.helper.interpretFlags(ctx) 79 if err != nil { 80 return err 81 } 82 83 fw, err := c.object(args) 84 if err != nil { 85 return err 86 } 87 88 return c.helper.create(ctx, fw) 89 } 90 91 // Interprets the flags specified on the commandline to the FileWatch to create. 92 func (c *createFileWatchCmd) object(args []string) (*v1alpha1.FileWatch, error) { 93 name := args[0] 94 pathArgs := args[1:] 95 96 paths, err := c.paths(pathArgs) 97 if err != nil { 98 return nil, err 99 } 100 101 ignores, err := c.ignores() 102 if err != nil { 103 return nil, err 104 } 105 106 fw := v1alpha1.FileWatch{ 107 ObjectMeta: metav1.ObjectMeta{ 108 Name: name, 109 }, 110 Spec: v1alpha1.FileWatchSpec{ 111 WatchedPaths: paths, 112 Ignores: ignores, 113 }, 114 } 115 return &fw, nil 116 } 117 118 // Interprets the paths specified on the commandline. 119 func (c *createFileWatchCmd) paths(pathArgs []string) ([]string, error) { 120 result := []string{} 121 cwd, err := os.Getwd() 122 if err != nil { 123 return nil, err 124 } 125 126 for _, path := range pathArgs { 127 if filepath.IsAbs(path) { 128 result = append(result, path) 129 } else { 130 result = append(result, filepath.Join(cwd, path)) 131 } 132 } 133 return result, nil 134 } 135 136 // Interprets the ignores specified on the commandline. 137 func (c *createFileWatchCmd) ignores() ([]v1alpha1.IgnoreDef, error) { 138 result := v1alpha1.IgnoreDef{} 139 cwd, err := os.Getwd() 140 if err != nil { 141 return nil, err 142 } 143 144 if len(c.ignoreValues) == 0 { 145 return nil, nil 146 } 147 148 result.BasePath = cwd 149 result.Patterns = append([]string{}, c.ignoreValues...) 150 return []v1alpha1.IgnoreDef{result}, nil 151 }