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  }