Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] File watch #763

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,7 @@
[[constraint]]
name = "github.com/alexellis/go-execute"
version = "0.3.0"

[[constraint]]
name = "github.com/fsnotify/fsnotify"
version = "1.4.7"
123 changes: 121 additions & 2 deletions commands/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,37 @@ package commands

import (
"fmt"
"log"
"os"
"path/filepath"
"strings"
"time"

"github.com/bep/debounce"
"github.com/fsnotify/fsnotify"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)

var (
skipPush bool
skipDeploy bool
skipPush bool
skipDeploy bool
watch bool
ignoredDirs []string
ignoredSuffixes []string
ignoredDirsDefault = []string{"build", ".git", "template"}
ignoredSuffixesDefault = []string{"~"}
)

func init() {

upFlagset := pflag.NewFlagSet("up", pflag.ExitOnError)
upFlagset.BoolVar(&skipPush, "skip-push", false, "Skip pushing function to remote registry")
upFlagset.BoolVar(&skipDeploy, "skip-deploy", false, "Skip function deployment")
upFlagset.BoolVar(&watch, "watch", false, "Watch for file changes and trigger up")
upFlagset.StringSliceVar(&ignoredDirs, "ignore-dir", []string{}, "Exclude directories from filesystem watch")
upFlagset.StringSliceVar(&ignoredSuffixes, "ignore-suffix", []string{}, "Exclude files with matching suffix from filesystem watch")

upCmd.Flags().AddFlagSet(upFlagset)

build, _, _ := faasCmd.Find([]string{"build"})
Expand Down Expand Up @@ -64,6 +80,88 @@ func preRunUp(cmd *cobra.Command, args []string) error {
}

func upHandler(cmd *cobra.Command, args []string) error {

if !watch {
return doUp(cmd, args)
}

ignoredDirs = append(ignoredDirs, ignoredDirsDefault...)
ignoredSuffixes = append(ignoredSuffixes, ignoredSuffixesDefault...)
ignoredSuffixes = append(ignoredSuffixes, ignoredDirs...)

debounced := debounce.New(500 * time.Millisecond)

watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
defer watcher.Close()

done := make(chan bool)
go func() {
for {
select {
case event := <-watcher.Events:

log.Printf("changed: %s", event)

if skipIgnoredSuffix(event, ignoredSuffixes) {
break
}

if opWrite(event) {
debounced(func() {
if err := doUp(cmd, args); err != nil {
log.Printf("Error detecting change: %v", err)
}
})
}

case err := <-watcher.Errors:
fmt.Println("error:", err)
}
}
}()

cwd, err := os.Getwd()
if err != nil {
return err
}
log.Println("Watching: ", cwd)

watchedDirs := []string{}
err = filepath.Walk(cwd,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

if skipIgnoredDir(info, ignoredDirs) {
return filepath.SkipDir
}

if info.IsDir() {
if err = watcher.Add(path); err != nil {
return err
}
watchedDirs = append(watchedDirs, path)
}
return nil
})
if err != nil {
return err
}

<-done

return nil
}

func opWrite(event fsnotify.Event) bool {
return event.Op&fsnotify.Write == fsnotify.Write
}

func doUp(cmd *cobra.Command, args []string) error {
if err := runBuild(cmd, args); err != nil {
return err
}
Expand All @@ -81,3 +179,24 @@ func upHandler(cmd *cobra.Command, args []string) error {
}
return nil
}

func skipIgnoredDir(info os.FileInfo, ignoredDirs []string) bool {
if !info.IsDir() {
return false
}
for _, ignoredDir := range ignoredDirs {
if info.Name() == ignoredDir {
return true
}
}
return false
}

func skipIgnoredSuffix(event fsnotify.Event, ignoredSuffixes []string) bool {
for _, ignoredSuffix := range ignoredSuffixes {
if strings.HasSuffix(event.Name, ignoredSuffix) {
return true
}
}
return false
}
27 changes: 27 additions & 0 deletions vendor/github.com/bep/debounce/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions vendor/github.com/bep/debounce/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions vendor/github.com/bep/debounce/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 35 additions & 0 deletions vendor/github.com/bep/debounce/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions vendor/github.com/bep/debounce/debounce.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions vendor/github.com/bep/debounce/go.mod

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file.
5 changes: 5 additions & 0 deletions vendor/github.com/fsnotify/fsnotify/.editorconfig

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions vendor/github.com/fsnotify/fsnotify/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading