From d9c9fa5ed9ffded2356942aa76612af6796a76c3 Mon Sep 17 00:00:00 2001 From: Martin Tournoij Date: Fri, 29 Jul 2022 20:28:45 +0200 Subject: [PATCH] Add cmd/fsnotify (#463) This adds a little example that can be run: % go run ./cmd/fsnotify **/* 12:76:11.4710 watching; press ^C to exit 12:76:13.6549 1 REMOVE "cmd/fsnotify/4913" 12:76:13.6550 2 RENAME "cmd/fsnotify/main.go" 12:76:13.6550 3 RENAME "cmd/fsnotify/main.go" 12:76:13.6612 4 CREATE "cmd/fsnotify/main.go" 12:76:13.6612 5 WRITE (modified) "cmd/fsnotify/main.go" 12:76:13.6614 6 WRITE (modified) "cmd/fsnotify/main.go" 12:76:13.6648 7 CHMOD "cmd/fsnotify/main.go" 12:76:15.2919 8 CREATE "cmd/fsnotify/4913" 12:76:15.2919 9 REMOVE "cmd/fsnotify/4913" 12:76:15.2922 10 CHMOD "cmd/fsnotify/main.go" 12:76:15.2923 11 REMOVE "cmd/fsnotify/main.go" 12:76:15.2925 12 RENAME "cmd/fsnotify/main.go" 12:76:15.2986 13 CREATE "cmd/fsnotify/main.go" 12:76:15.2986 14 WRITE (modified) "cmd/fsnotify/main.go" 12:76:15.2988 15 WRITE (modified) "cmd/fsnotify/main.go" 12:76:15.3024 16 CHMOD "cmd/fsnotify/main.go" ^C It's mostly the same as the example in the README, except that it takes paths from the commandline and aligns things a bit nicer. This is useful for documentation and experimentation. For example, while reviewing some PRs I found it useful to quickly get an overview of "what does fsnotify do now, and what does it do with this patch?" --- README.md | 5 ++++ cmd/fsnotify/main.go | 67 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 cmd/fsnotify/main.go diff --git a/README.md b/README.md index 01de753b..823e019d 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,11 @@ func main() { } ``` +A slightly more expansive example can be found in [cmd/fsnotify](cmd/fsnotify), which can be run with: + + # Watch the current directory (not recursive). + $ go run ./cmd/fsnotify . + ## Contributing Please refer to [CONTRIBUTING][] before opening an issue or pull request. diff --git a/cmd/fsnotify/main.go b/cmd/fsnotify/main.go new file mode 100644 index 00000000..1b0356ac --- /dev/null +++ b/cmd/fsnotify/main.go @@ -0,0 +1,67 @@ +package main + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "time" + + "github.com/fsnotify/fsnotify" +) + +func fatal(err error) { + if err == nil { + return + } + fmt.Fprintf(os.Stderr, "%s: %s\n", filepath.Base(os.Args[0]), err) + os.Exit(1) +} + +func line(s string, args ...interface{}) { + fmt.Printf(time.Now().Format("15:16:05.0000")+" "+s+"\n", args...) +} + +func main() { + if len(os.Args) < 2 { + fatal(errors.New("must specify at least one path to watch")) + } + + w, err := fsnotify.NewWatcher() + fatal(err) + defer w.Close() + + go func() { + i := 0 + for { + select { + case e, ok := <-w.Events: + if !ok { + return + } + + i++ + m := "" + if e.Op&fsnotify.Write == fsnotify.Write { + m = "(modified)" + } + line("%3d %-10s %-10s %q", i, e.Op, m, e.Name) + case err, ok := <-w.Errors: + if !ok { + return + } + line("ERROR: %s", err) + } + } + }() + + for _, p := range os.Args[1:] { + err = w.Add(p) + if err != nil { + fatal(fmt.Errorf("%q: %w", p, err)) + } + } + + line("watching; press ^C to exit") + <-make(chan struct{}) +}