-
Notifications
You must be signed in to change notification settings - Fork 375
/
watch.go
108 lines (94 loc) · 2.59 KB
/
watch.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package cmd
import (
"errors"
"os"
"os/signal"
"github.com/spf13/cobra"
"github.com/Shopify/themekit/kit"
)
var (
signalChan = make(chan os.Signal)
reloadSignal = make(chan bool)
errReload = errors.New("Reload Watcher")
)
var watchCmd = &cobra.Command{
Use: "watch",
Short: "Watch directory for changes and update remote theme",
Long: `Watch is for running in the background while you are making changes to your project.
run 'theme watch' while you are editing and it will detect create, update and delete events.
For more documentation please see http://shopify.github.io/themekit/commands/#watch
`,
RunE: func(cmd *cobra.Command, args []string) error {
return startWatch()
},
}
func startWatch() error {
themeClients, err := generateThemeClients()
if err != nil {
return err
}
err = watch(themeClients)
if err == errReload {
kit.Print("Reloading because of config changes")
return startWatch()
}
return err
}
func watch(themeClients []kit.ThemeClient) error {
watchers := []*kit.FileWatcher{}
defer func() {
if len(watchers) > 0 {
kit.Print("Cleaning up watchers")
for _, watcher := range watchers {
// This is half assed because fsnotify sometimes deadlocks
// if it finishes before exit great if not garbage collection will do it.
go watcher.StopWatching()
}
}
}()
for _, client := range themeClients {
if client.Config.ReadOnly {
kit.LogErrorf("[%s]environment is reaonly", kit.GreenText(client.Config.Environment))
continue
}
kit.Printf("[%s] Watching for file changes on host %s ", kit.GreenText(client.Config.Environment), kit.YellowText(client.Config.Domain))
watcher, err := client.NewFileWatcher(notifyFile, handleWatchEvent)
if err != nil {
return err
}
watcher.WatchConfig(configPath, reloadSignal)
if err != nil {
return err
}
watchers = append(watchers, watcher)
}
if len(watchers) > 0 {
signal.Notify(signalChan, os.Interrupt)
select {
case <-signalChan:
case <-reloadSignal:
return errReload
}
}
return nil
}
func handleWatchEvent(client kit.ThemeClient, asset kit.Asset, event kit.EventType) {
kit.Printf(
"[%s] Received %s event on %s",
kit.GreenText(client.Config.Environment),
kit.GreenText(event),
kit.BlueText(asset.Key),
)
resp, err := client.Perform(asset, event)
if err != nil {
kit.LogErrorf("[%s]%s", kit.GreenText(client.Config.Environment), err)
} else {
kit.Printf(
"[%s] Successfully performed %s operation for file %s to %s",
kit.GreenText(client.Config.Environment),
kit.GreenText(resp.EventType),
kit.BlueText(resp.Asset.Key),
kit.YellowText(resp.Host),
)
}
}