Skip to content

Commit effb4e8

Browse files
committed
add support for excludes and rebuild
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
1 parent bcbaece commit effb4e8

File tree

2 files changed

+50
-33
lines changed

2 files changed

+50
-33
lines changed

pkg/compose/watch.go

+48-22
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,23 @@ import (
2828
"github.com/jonboulle/clockwork"
2929
"github.com/mitchellh/mapstructure"
3030
"github.com/pkg/errors"
31+
"github.com/sirupsen/logrus"
3132
"golang.org/x/sync/errgroup"
3233
)
3334

3435
type DevelopmentConfig struct {
35-
Sync map[string]string `json:"sync,omitempty"`
36-
Excludes []string `json:"excludes,omitempty"`
36+
Watch []Trigger `json:"watch,omitempty"`
37+
}
38+
39+
const (
40+
WatchActionSync = "sync"
41+
WatchActionRebuild = "rebuild"
42+
)
43+
44+
type Trigger struct {
45+
Path string `json:"path,omitempty"`
46+
Action string `json:"action,omitempty"`
47+
Target string `json:"target,omitempty"`
3748
}
3849

3950
const quietPeriod = 2 * time.Second
@@ -85,26 +96,38 @@ func (s *composeService) Watch(ctx context.Context, project *types.Project, serv
8596
case <-ctx.Done():
8697
return nil
8798
case event := <-watcher.Events():
88-
fmt.Fprintf(s.stderr(), "change detected on %s\n", event.Path())
89-
90-
for src, dest := range config.Sync {
91-
path := filepath.Clean(event.Path())
92-
src = filepath.Clean(src)
93-
if watch.IsChild(path, src) {
94-
rel, err := filepath.Rel(src, path)
95-
if err != nil {
96-
return err
97-
}
98-
dest = filepath.Join(dest, rel)
99-
needSync <- api.CopyOptions{
100-
Source: path,
101-
Destination: fmt.Sprintf("%s:%s", service.Name, dest),
99+
path := event.Path()
100+
101+
for _, trigger := range config.Watch {
102+
logrus.Debugf("change deteced on %s - comparing with %s", path, trigger.Path)
103+
if watch.IsChild(trigger.Path, path) {
104+
fmt.Fprintf(s.stderr(), "change detected on %s\n", path)
105+
106+
switch trigger.Action {
107+
case WatchActionSync:
108+
logrus.Debugf("modified file %s triggered sync", path)
109+
rel, err := filepath.Rel(trigger.Path, path)
110+
if err != nil {
111+
return err
112+
}
113+
dest := filepath.Join(trigger.Target, rel)
114+
needSync <- api.CopyOptions{
115+
Source: path,
116+
Destination: fmt.Sprintf("%s:%s", service.Name, dest),
117+
}
118+
case WatchActionRebuild:
119+
logrus.Debugf("modified file %s require image to be rebuilt", path)
120+
needRebuild <- service.Name
121+
default:
122+
return fmt.Errorf("watch action %q is not supported", trigger)
102123
}
103124
continue WATCH
104125
}
105126
}
106127

128+
// default
107129
needRebuild <- service.Name
130+
108131
case err := <-watcher.Errors():
109132
return err
110133
}
@@ -124,14 +147,17 @@ func loadDevelopmentConfig(service types.ServiceConfig, project *types.Project)
124147
if y, ok := service.Extensions["x-develop"]; ok {
125148
err := mapstructure.Decode(y, &config)
126149
if err != nil {
127-
return DevelopmentConfig{}, err
150+
return config, err
128151
}
129-
for src, dest := range config.Sync {
130-
if !filepath.IsAbs(src) {
131-
delete(config.Sync, src)
132-
src = filepath.Join(project.WorkingDir, src)
133-
config.Sync[src] = dest
152+
for i, trigger := range config.Watch {
153+
if !filepath.IsAbs(trigger.Path) {
154+
trigger.Path = filepath.Join(project.WorkingDir, trigger.Path)
155+
}
156+
trigger.Path = filepath.Clean(trigger.Path)
157+
if trigger.Path == "" {
158+
return config, errors.New("watch rules MUST define a path")
134159
}
160+
config.Watch[i] = trigger
135161
}
136162
}
137163
return config, nil

pkg/watch/watcher_darwin.go

+2-11
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package watch
2121

2222
import (
23+
"fmt"
2324
"path/filepath"
2425
"time"
2526

@@ -52,19 +53,9 @@ func (d *fseventNotify) loop() {
5253
}
5354

5455
for _, e := range events {
56+
fmt.Println(e)
5557
e.Path = filepath.Join("/", e.Path)
5658

57-
if e.Flags&fsevents.HistoryDone == fsevents.HistoryDone {
58-
d.sawAnyHistoryDone = true
59-
continue
60-
}
61-
62-
// We wait until we've seen the HistoryDone event for this watcher before processing any events
63-
// so that we skip all of the "spurious" events that precede it.
64-
if !d.sawAnyHistoryDone {
65-
continue
66-
}
67-
6859
_, isPathWereWatching := d.pathsWereWatching[e.Path]
6960
if e.Flags&fsevents.ItemIsDir == fsevents.ItemIsDir && e.Flags&fsevents.ItemCreated == fsevents.ItemCreated && isPathWereWatching {
7061
// This is the first create for the path that we're watching. We always get exactly one of these

0 commit comments

Comments
 (0)