├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── go.mod ├── go.sum ├── main.go └── srlt.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Command Line Interface for https://github.com/fsnotify/fsnotify 2 | Copyright (C) 2016 Oleg Lebedev 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the "Software"), 6 | to deal in the Software without restriction, including without limitation 7 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | and/or sell copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 16 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 20 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | P = $(shell pwd | sed 's:.*/::') 2 | SOURCE = $(wildcard *.go) 3 | TAG = $(shell git describe --tags) 4 | GOBUILD = go build -ldflags '-w' 5 | 6 | # $(tag) here will contain either `-1.0-` or just `-` 7 | ALL = \ 8 | $(foreach arch,64,\ 9 | $(foreach tag,-$(TAG)-,\ 10 | $(foreach suffix,win.exe linux osx,\ 11 | build/$P$(tag)$(arch)-$(suffix)))) 12 | 13 | build: $(ALL) 14 | 15 | # os is determined as thus: if variable of suffix exists, it's taken, if not, then 16 | # suffix itself is taken 17 | win.exe = windows 18 | osx = darwin 19 | build/$P-$(TAG)-64-%: $(SOURCE) 20 | @mkdir -p $(@D) 21 | CGO_ENABLED=0 GOOS=$(firstword $($*) $*) GOARCH=amd64 $(GOBUILD) -o $@ 22 | @cd $(@D) && tar cvzf $(@F).tar.gz $(@F) 23 | 24 | build/$P-$(TAG)-32-%: $(SOURCE) 25 | @mkdir -p $(@D) 26 | CGO_ENABLED=0 GOOS=$(firstword $($*) $*) GOARCH=386 $(GOBUILD) -o $@ 27 | @cd $(@D) && tar cvzf $(@F).tar.gz $(@F) 28 | 29 | build/$P-%: build/$P-$(TAG)-% 30 | @mkdir -p $(@D) 31 | cd $(@D) && ln -sf $( 24 | 25 | VERSION: 26 | 0.1.0 27 | 28 | AUTHOR(S): 29 | olebedev 30 | 31 | COMMANDS: 32 | GLOBAL OPTIONS: 33 | --template, -t "{{.Name}}" output template to render received event, see: https://godoc.org/gopkg.in/fsnotify.v1#Event 34 | --mask, -m "15" event's bitwise mask, see: https://godoc.org/gopkg.in/fsnotify.v1#Op 35 | --help, -h show help 36 | --version, -v print the version 37 | ``` 38 | 39 | ### License 40 | MIT 41 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module olebedev/on 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/urfave/cli v1.22.2 7 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 // indirect 8 | gopkg.in/fsnotify.v1 v1.4.7 9 | ) 10 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 2 | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= 3 | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= 6 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 7 | github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= 8 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 9 | github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= 10 | github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= 11 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 h1:JA8d3MPx/IToSyXZG/RhwYEtfrKO1Fxrqe8KrkiLXKM= 12 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 13 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 14 | gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= 15 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 16 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 17 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "log" 7 | "os" 8 | "os/signal" 9 | "path/filepath" 10 | "text/template" 11 | 12 | "github.com/urfave/cli" 13 | "gopkg.in/fsnotify.v1" 14 | ) 15 | 16 | func main() { 17 | app := cli.NewApp() 18 | app.Usage = "cli for fsnotify" 19 | app.UsageText = `on [options] [path] 20 | 21 | Path could be mix of folders and filepaths, default is '.'. 22 | Regular usecase is watch the file's changes and execute some 23 | bash script or command line tool. It could be done in this way: 24 | 25 | on | xargs -n1 -I{} ` 26 | 27 | app.Author = "olebedev " 28 | app.Version = "0.1.0" 29 | app.Flags = []cli.Flag{ 30 | cli.StringFlag{ 31 | Name: "template,t", 32 | Usage: "output template to render received event, see: https://godoc.org/gopkg.in/fsnotify.v1#Event", 33 | Value: "{{.Name}}", 34 | }, 35 | cli.IntFlag{ 36 | Name: "mask,m", 37 | Usage: "event's bitwise mask, see: https://godoc.org/gopkg.in/fsnotify.v1#Op", 38 | Value: 15, 39 | }, 40 | cli.BoolFlag{ 41 | Name: "r", 42 | Usage: "watch given paths recursively", 43 | }, 44 | } 45 | app.Action = func(c *cli.Context) { 46 | t, err := template.New("output").Parse(c.String("template")) 47 | if err != nil { 48 | log.Fatal(err) 49 | } 50 | id := fsnotify.Op(c.Int("mask")) 51 | 52 | watcher, err := fsnotify.NewWatcher() 53 | if err != nil { 54 | log.Fatal(err) 55 | } 56 | defer watcher.Close() 57 | 58 | done := make(chan os.Signal) 59 | signal.Notify(done, os.Interrupt) 60 | 61 | go func() { 62 | for { 63 | select { 64 | case event := <-watcher.Events: 65 | // if bitwise mask covers the event 66 | if event.Op&id == event.Op && event.Name != "" { 67 | fmt.Println(render(t, event)) 68 | } 69 | case err := <-watcher.Errors: 70 | if err != nil { 71 | fmt.Fprintln(os.Stderr, err) 72 | } 73 | } 74 | } 75 | }() 76 | 77 | args := c.Args() 78 | if len(args) == 0 { 79 | args = []string{"."} 80 | } 81 | 82 | for _, arg := range args { 83 | if err := addPath(watcher, arg, c.Bool("r")); err != nil { 84 | fmt.Fprintln(os.Stderr, err) 85 | os.Exit(1) 86 | } 87 | } 88 | 89 | <-done 90 | watcher.Close() 91 | } 92 | 93 | app.Run(os.Args) 94 | } 95 | 96 | func render(t *template.Template, e fsnotify.Event) string { 97 | var doc bytes.Buffer 98 | t.Execute(&doc, e) 99 | 100 | return doc.String() 101 | } 102 | 103 | func addPath(w *fsnotify.Watcher, name string, recursively bool) error { 104 | f, err := os.Stat(name) 105 | if err != nil { 106 | return err 107 | } 108 | 109 | if !f.IsDir() || !recursively { 110 | return w.Add(name) 111 | } 112 | 113 | return filepath.Walk(name, func(p string, f os.FileInfo, err error) error { 114 | if err != nil { 115 | return err 116 | } 117 | if f.IsDir() { 118 | return w.Add(p) 119 | } 120 | return nil 121 | }) 122 | } 123 | -------------------------------------------------------------------------------- /srlt.yaml: -------------------------------------------------------------------------------- 1 | base: ./vendor 2 | dependencies: 3 | github.com/codegangsta/cli: 4 | type: git 5 | name: github.com/codegangsta/cli 6 | remote: https://github.com/codegangsta/cli 7 | commit: 222ec6fb7eb8a3da24cfa4017694ba45e3f1f516 8 | golang.org/x/sys: 9 | type: git 10 | name: golang.org/x/sys 11 | remote: https://github.com/golang/sys 12 | commit: c8bc69bc2db9c57ccf979550bc69655df5039a8a 13 | gopkg.in/fsnotify.v1: 14 | type: git 15 | name: gopkg.in/fsnotify.v1 16 | remote: https://gopkg.in/fsnotify.v1 17 | commit: 30411dbcefb7a1da7e84f75530ad3abe4011b4f8 18 | --------------------------------------------------------------------------------