diff --git a/cmd/watcher/main.go b/cmd/watcher/main.go index 3b35576..50846d7 100644 --- a/cmd/watcher/main.go +++ b/cmd/watcher/main.go @@ -3,7 +3,7 @@ package main import ( "os" - "github.com/canthefason/go-watcher" + "github.com/noamtzuberi/go-watcher" ) func main() { diff --git a/common.go b/common.go index 9a601b3..d4dc394 100644 --- a/common.go +++ b/common.go @@ -14,7 +14,8 @@ import ( // Binary name used for built package const binaryName = "watcher" -var watcherFlags = []string{"run", "watch", "watch-vendor"} +// watch-recursive works only for mac +var watcherFlags = []string{"run", "watch", "watch-vendor","watch-recursive","watch-recursive-root"} // Params is used for keeping go-watcher and application flag parameters type Params struct { @@ -161,3 +162,12 @@ func removeFile(fileName string) { cmd.Wait() } } + +func sliceContains(slice []string, s string) bool { + for _, t := range slice { + if s == t { + return true + } + } + return false +} diff --git a/dependency.go b/dependency.go new file mode 100644 index 0000000..631768d --- /dev/null +++ b/dependency.go @@ -0,0 +1,83 @@ +package watcher + +import ( + "io/ioutil" + "os" + "path/filepath" + "regexp" + "strings" +) + +func(w *Watcher) getGoFiles(rootDir string) ([]string, error) { + var files []string + ext := ".go" + + err := filepath.Walk(rootDir, func(path string, f os.FileInfo, _ error) error { + if !f.IsDir() { + r, err := regexp.MatchString(ext, f.Name()) + if err == nil && r { + files = append(files, path) + } + } + return nil + }) + + if err != nil { + return nil, err + } + + return files, nil +} + +func(w *Watcher) getImports(files []string,wd string) ([]string, error) { + goPath := os.Getenv("GOPATH") + if goPath == "" { + return nil, ErrPathNotSet + } + + importsFolders := make([]string, 0) + for _, file := range files { + content, err := ioutil.ReadFile(file) + if err != nil { + return nil, err + } + + lines := strings.Split(string(content), "\n") + startImport := false + + for _, line := range lines { + //start of import section + if strings.Contains(line, "import") { + startImport = true + } + + if startImport { + if strings.Index(line, w.watchRecursiveRoot) == -1 { + continue + } + + startIndex := strings.Index(line, "\"") + endIndex := strings.LastIndex(line, "\"") + + if startIndex != -1 && endIndex != -1 { + //import line + importStr := filepath.Join(goPath, "src", line[startIndex+1:len(line)-1]) + if strings.HasPrefix(importStr, wd) { + continue + } + + if !sliceContains(importsFolders, importStr) { + importsFolders = append(importsFolders, importStr) + } + } + + //end of import section + if strings.Contains(line, ")") { + break + } + } + } + } + + return importsFolders, nil +} diff --git a/watch.go b/watch.go index 0704936..e777526 100644 --- a/watch.go +++ b/watch.go @@ -11,6 +11,7 @@ import ( "strconv" "strings" "time" + "runtime" fsnotify "gopkg.in/fsnotify.v1" ) @@ -28,6 +29,8 @@ type Watcher struct { rootdir string watcher *fsnotify.Watcher watchVendor bool + watchRecursive bool + watchRecursiveRoot string // when a file gets changed a message is sent to the update channel update chan struct{} } @@ -36,19 +39,35 @@ type Watcher struct { // given folders func MustRegisterWatcher(params *Params) *Watcher { watchVendorStr := params.Get("watch-vendor") + watchRecursiveStr := params.Get("watch-recursive") + watchRecursiveRoot := params.Get("watch-recursive-root") var watchVendor bool + var watchRecursive bool var err error + if watchVendorStr != "" { watchVendor, err = strconv.ParseBool(watchVendorStr) if err != nil { log.Println("Wrong watch-vendor value: %s (default=false)", watchVendorStr) } } + if watchRecursiveStr != ""{ + if watchRecursiveRoot == ""{ + log.Fatal("watchRecursiveRoot is empty") + } + + watchRecursive, err = strconv.ParseBool(watchRecursiveStr) + if err != nil { + log.Fatal("Wrong watch-recursive value: %s (default=false)", watchRecursiveStr) + } + } w := &Watcher{ - update: make(chan struct{}), - rootdir: params.Get("watch"), - watchVendor: watchVendor, + update: make(chan struct{}), + rootdir: params.Get("watch"), + watchVendor: watchVendor, + watchRecursive: watchRecursive, + watchRecursiveRoot: watchRecursiveRoot, } w.watcher, err = fsnotify.NewWatcher() @@ -125,10 +144,25 @@ func (w *Watcher) Close() { // starting from the working directory func (w *Watcher) watchFolders() { wd, err := w.prepareRootDir() - if err != nil { log.Fatalf("Could not get root working directory: %s", err) } + //supported only in mac + if w.watchRecursive && runtime.GOOS == "darwin" { + goFiles, err := w.getGoFiles(wd) + if err != nil { + log.Fatalf("Could not get recursiv go files: %s", err) + } + + importsFolders, err := w.getImports(goFiles,wd) + if err != nil { + log.Fatalf("Could not get recursiv imports from go files: %s", err) + } + + for _,importFolder := range importsFolders{ + w.addFolder(importFolder) + } + } filepath.Walk(wd, func(path string, info os.FileInfo, err error) error { // skip files