github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/controllers/core/filewatch/action.go (about) 1 package filewatch 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 8 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 9 10 "github.com/tilt-dev/tilt/internal/store" 11 "github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1" 12 filewatches "github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1" 13 "github.com/tilt-dev/tilt/pkg/logger" 14 "github.com/tilt-dev/tilt/pkg/model" 15 ) 16 17 type FileWatchUpdateStatusAction struct { 18 ObjectMeta *metav1.ObjectMeta 19 Status *filewatches.FileWatchStatus 20 } 21 22 func (a FileWatchUpdateStatusAction) Summarize(_ *store.ChangeSummary) { 23 // do nothing - we only care about _spec_ changes on the summary 24 } 25 26 func (FileWatchUpdateStatusAction) Action() {} 27 28 func NewFileWatchUpdateStatusAction(fw *filewatches.FileWatch) FileWatchUpdateStatusAction { 29 return FileWatchUpdateStatusAction{ObjectMeta: fw.GetObjectMeta().DeepCopy(), Status: fw.Status.DeepCopy()} 30 } 31 32 func HandleFileWatchUpdateStatusEvent(ctx context.Context, state *store.EngineState, action FileWatchUpdateStatusAction) { 33 processFileWatchStatus(ctx, state, action.ObjectMeta, action.Status) 34 } 35 36 func processFileWatchStatus(ctx context.Context, state *store.EngineState, meta *metav1.ObjectMeta, status *v1alpha1.FileWatchStatus) { 37 if status.Error != "" || len(status.FileEvents) == 0 { 38 return 39 } 40 41 // since the store is called on EVERY update, can always just look at the last event 42 latestEvent := status.FileEvents[len(status.FileEvents)-1] 43 44 targetID, err := targetID(meta) 45 if err != nil { 46 logger.Get(ctx).Debugf("Failed to get targetID for FileWatch %q to process update: %v", meta.GetName(), err) 47 return 48 } else if targetID.Empty() { 49 return 50 } 51 52 mns := state.ManifestNamesForTargetID(targetID) 53 for _, mn := range mns { 54 ms, ok := state.ManifestState(mn) 55 if !ok { 56 return 57 } 58 59 for _, f := range latestEvent.SeenFiles { 60 ms.AddPendingFileChange(targetID, f, latestEvent.Time.Time) 61 } 62 } 63 } 64 65 func targetID(metaObj *metav1.ObjectMeta) (model.TargetID, error) { 66 labelVal := metaObj.GetAnnotations()[filewatches.AnnotationTargetID] 67 if labelVal == "" { 68 return model.TargetID{}, nil 69 } 70 targetParts := strings.SplitN(labelVal, ":", 2) 71 if len(targetParts) != 2 || targetParts[0] == "" || targetParts[1] == "" { 72 return model.TargetID{}, fmt.Errorf("invalid target ID: %q", labelVal) 73 } 74 return model.TargetID{Type: model.TargetType(targetParts[0]), Name: model.TargetName(targetParts[1])}, nil 75 }