فهرست منبع

add support for `excludes` and `rebuild`

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof 2 سال پیش
والد
کامیت
b19df5c96c
2فایلهای تغییر یافته به همراه50 افزوده شده و 33 حذف شده
  1. 48 22
      pkg/compose/watch.go
  2. 2 11
      pkg/watch/watcher_darwin.go

+ 48 - 22
pkg/compose/watch.go

@@ -28,12 +28,23 @@ import (
 	"github.com/jonboulle/clockwork"
 	"github.com/mitchellh/mapstructure"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sync/errgroup"
 )
 
 type DevelopmentConfig struct {
-	Sync     map[string]string `json:"sync,omitempty"`
-	Excludes []string          `json:"excludes,omitempty"`
+	Watch []Trigger `json:"watch,omitempty"`
+}
+
+const (
+	WatchActionSync    = "sync"
+	WatchActionRebuild = "rebuild"
+)
+
+type Trigger struct {
+	Path   string `json:"path,omitempty"`
+	Action string `json:"action,omitempty"`
+	Target string `json:"target,omitempty"`
 }
 
 const quietPeriod = 2 * time.Second
@@ -85,26 +96,38 @@ func (s *composeService) Watch(ctx context.Context, project *types.Project, serv
 				case <-ctx.Done():
 					return nil
 				case event := <-watcher.Events():
-					fmt.Fprintf(s.stderr(), "change detected on %s\n", event.Path())
-
-					for src, dest := range config.Sync {
-						path := filepath.Clean(event.Path())
-						src = filepath.Clean(src)
-						if watch.IsChild(path, src) {
-							rel, err := filepath.Rel(src, path)
-							if err != nil {
-								return err
-							}
-							dest = filepath.Join(dest, rel)
-							needSync <- api.CopyOptions{
-								Source:      path,
-								Destination: fmt.Sprintf("%s:%s", service.Name, dest),
+					path := event.Path()
+
+					for _, trigger := range config.Watch {
+						logrus.Debugf("change deteced on %s - comparing with %s", path, trigger.Path)
+						if watch.IsChild(trigger.Path, path) {
+							fmt.Fprintf(s.stderr(), "change detected on %s\n", path)
+
+							switch trigger.Action {
+							case WatchActionSync:
+								logrus.Debugf("modified file %s triggered sync", path)
+								rel, err := filepath.Rel(trigger.Path, path)
+								if err != nil {
+									return err
+								}
+								dest := filepath.Join(trigger.Target, rel)
+								needSync <- api.CopyOptions{
+									Source:      path,
+									Destination: fmt.Sprintf("%s:%s", service.Name, dest),
+								}
+							case WatchActionRebuild:
+								logrus.Debugf("modified file %s require image to be rebuilt", path)
+								needRebuild <- service.Name
+							default:
+								return fmt.Errorf("watch action %q is not supported", trigger)
 							}
 							continue WATCH
 						}
 					}
 
+					// default
 					needRebuild <- service.Name
+
 				case err := <-watcher.Errors():
 					return err
 				}
@@ -124,14 +147,17 @@ func loadDevelopmentConfig(service types.ServiceConfig, project *types.Project)
 	if y, ok := service.Extensions["x-develop"]; ok {
 		err := mapstructure.Decode(y, &config)
 		if err != nil {
-			return DevelopmentConfig{}, err
+			return config, err
 		}
-		for src, dest := range config.Sync {
-			if !filepath.IsAbs(src) {
-				delete(config.Sync, src)
-				src = filepath.Join(project.WorkingDir, src)
-				config.Sync[src] = dest
+		for i, trigger := range config.Watch {
+			if !filepath.IsAbs(trigger.Path) {
+				trigger.Path = filepath.Join(project.WorkingDir, trigger.Path)
+			}
+			trigger.Path = filepath.Clean(trigger.Path)
+			if trigger.Path == "" {
+				return config, errors.New("watch rules MUST define a path")
 			}
+			config.Watch[i] = trigger
 		}
 	}
 	return config, nil

+ 2 - 11
pkg/watch/watcher_darwin.go

@@ -20,6 +20,7 @@
 package watch
 
 import (
+	"fmt"
 	"path/filepath"
 	"time"
 
@@ -52,19 +53,9 @@ func (d *fseventNotify) loop() {
 			}
 
 			for _, e := range events {
+				fmt.Println(e)
 				e.Path = filepath.Join("/", e.Path)
 
-				if e.Flags&fsevents.HistoryDone == fsevents.HistoryDone {
-					d.sawAnyHistoryDone = true
-					continue
-				}
-
-				// We wait until we've seen the HistoryDone event for this watcher before processing any events
-				// so that we skip all of the "spurious" events that precede it.
-				if !d.sawAnyHistoryDone {
-					continue
-				}
-
 				_, isPathWereWatching := d.pathsWereWatching[e.Path]
 				if e.Flags&fsevents.ItemIsDir == fsevents.ItemIsDir && e.Flags&fsevents.ItemCreated == fsevents.ItemCreated && isPathWereWatching {
 					// This is the first create for the path that we're watching. We always get exactly one of these