86 lines
1.8 KiB
Go
86 lines
1.8 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
|
||
|
"github.com/fsnotify/fsnotify"
|
||
|
)
|
||
|
|
||
|
func WatchDirectory(op fsnotify.Op, path string) (<-chan string, error) {
|
||
|
watcher, err := fsnotify.NewWatcher()
|
||
|
if err != nil {
|
||
|
panic(err) // TODO error handling
|
||
|
}
|
||
|
|
||
|
err = watcher.Add(path)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
files, err := os.ReadDir(path)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
ch := make(chan string, 10)
|
||
|
|
||
|
go func(watcher *fsnotify.Watcher, ch chan<- string) {
|
||
|
defer watcher.Close()
|
||
|
|
||
|
for _, file := range files {
|
||
|
path := filepath.Join(path, file.Name())
|
||
|
if file.IsDir() {
|
||
|
//fmt.Println("watching directory", path)
|
||
|
watcher.Add(path)
|
||
|
|
||
|
if dirFiles, err := os.ReadDir(path); err == nil {
|
||
|
for _, dirFile := range dirFiles {
|
||
|
ch <- filepath.Join(path, dirFile.Name())
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
ch <- path
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for {
|
||
|
select {
|
||
|
case event, ok := <-watcher.Events:
|
||
|
if !ok {
|
||
|
close(ch)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if fi, err := os.Stat(event.Name); err == nil && fi.IsDir() {
|
||
|
if event.Op&fsnotify.Create == fsnotify.Create {
|
||
|
//fmt.Println("watching directory", event.Name)
|
||
|
watcher.Add(event.Name)
|
||
|
}
|
||
|
|
||
|
// read dir immediately because directory files could simultanously with its parent directory
|
||
|
if dirFiles, err := os.ReadDir(event.Name); err == nil {
|
||
|
for _, dirFile := range dirFiles {
|
||
|
ch <- filepath.Join(event.Name, dirFile.Name())
|
||
|
}
|
||
|
}
|
||
|
} else if err != nil && event.Op&fsnotify.Remove == fsnotify.Remove {
|
||
|
//fmt.Println("stopped watching directory", event.Name)
|
||
|
watcher.Remove(event.Name)
|
||
|
}
|
||
|
|
||
|
if event.Op&op == op {
|
||
|
ch <- event.Name
|
||
|
}
|
||
|
case err, ok := <-watcher.Errors:
|
||
|
fmt.Println(err, ok)
|
||
|
close(ch)
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
}(watcher, ch)
|
||
|
|
||
|
return ch, nil
|
||
|
}
|