Documentation ¶
Overview ¶
Package watchfs implement naive file and directory watcher.
This package is deprecated, we keep it here for historical only. The new implementation should use "watchfs/v2".
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DirWatcher ¶
type DirWatcher struct { // C channel on which the changes are delivered to user. C <-chan NodeState Options DirWatcherOptions // contains filtered or unexported fields }
DirWatcher is a naive implementation of directory change notification.
Example ¶
package main import ( "fmt" "log" "os" "path/filepath" "time" "git.sr.ht/~shulhan/pakakeh.go/lib/watchfs" ) func main() { var ( rootDir string err error ) rootDir, err = os.MkdirTemp(``, `ExampleDirWatcher`) if err != nil { log.Fatal(err) } // In this example, we watch sub directory "assets" and its // contents, including only files with ".adoc" extension and // excluding files with ".html" extension. var dw = &watchfs.DirWatcher{ Options: watchfs.DirWatcherOptions{ Root: rootDir, Includes: []string{ `assets/.*`, `.*\.adoc$`, }, Excludes: []string{ `.*\.html$`, }, Delay: 100 * time.Millisecond, }, } err = dw.Start() if err != nil { log.Fatal(err) } fmt.Println(`Deleting the root directory:`) err = os.Remove(rootDir) if err != nil { log.Fatal(err) } var ns = <-dw.C fmt.Println(`--`, ns.State, ns.Node.Path) // Create the root directory back with sub directory // This will trigger one FileStateCreated event, for "/". fmt.Println(`Re-create root directory with sub-directory:`) var dirAssets = filepath.Join(rootDir, `assets`) err = os.MkdirAll(dirAssets, 0770) if err != nil { log.Fatal(err) } ns = <-dw.C fmt.Println(`--`, ns.State, ns.Node.Path) // Modify the permission on root directory fmt.Println(`Chmod on root directory:`) err = os.Chmod(rootDir, 0700) if err != nil { log.Fatal(err) } ns = <-dw.C fmt.Println(`--`, ns.State, ns.Node.Path, ns.Node.Mode()) fmt.Println(`Create new file on root directory: /new.adoc`) var newFile = filepath.Join(rootDir, `new.adoc`) err = os.WriteFile(newFile, nil, 0600) if err != nil { log.Fatal(err) } ns = <-dw.C fmt.Println(`--`, ns.State, ns.Node.Path, ns.Node.Mode()) fmt.Println(`Remove file on root directory: /new.adoc`) err = os.Remove(newFile) if err != nil { log.Fatal(err) } ns = <-dw.C fmt.Println(`--`, ns.State, ns.Node.Path, ns.Node.Mode()) fmt.Println(`Create new sub-directory: /subdir`) var subDir = filepath.Join(rootDir, `subdir`) err = os.Mkdir(subDir, 0770) if err != nil { log.Fatal(err) } ns = <-dw.C fmt.Println(`--`, ns.State, ns.Node.Path, ns.Node.Mode()) // Add new file in sub directory. newFile = filepath.Join(subDir, `new.adoc`) fmt.Println(`Create new file in sub directory: /subdir/new.adoc`) err = os.WriteFile(newFile, nil, 0600) if err != nil { log.Fatal(err) } ns = <-dw.C fmt.Println(`--`, ns.State, ns.Node.Path, ns.Node.Mode()) fmt.Println(`Remove file in sub directory: /subdir/new.adoc`) err = os.Remove(newFile) if err != nil { log.Fatal(err) } ns = <-dw.C fmt.Println(`--`, ns.State, ns.Node.Path, ns.Node.Mode()) // Creating file that is excluded should not trigger event. fmt.Println(`Create excluded file in sub directory: /subdir/new.html`) newFile = filepath.Join(subDir, `new.html`) err = os.WriteFile(newFile, nil, 0600) if err != nil { log.Fatal(err) } // Create file without extension in directory "assets" should trigger // event. newFile = filepath.Join(dirAssets, `new`) fmt.Println(`Create new file under assets: /assets/new`) err = os.WriteFile(newFile, nil, 0600) if err != nil { log.Fatal(err) } ns = <-dw.C fmt.Println(`--`, ns.State, ns.Node.Path, ns.Node.Mode()) // TODO: fix data race. //dw.Stop() }
Output: Deleting the root directory: -- FileStateDeleted / Re-create root directory with sub-directory: -- FileStateCreated / Chmod on root directory: -- FileStateUpdateMode / drwx------ Create new file on root directory: /new.adoc -- FileStateCreated /new.adoc -rw------- Remove file on root directory: /new.adoc -- FileStateDeleted /new.adoc -rw------- Create new sub-directory: /subdir -- FileStateCreated /subdir drwxr-x--- Create new file in sub directory: /subdir/new.adoc -- FileStateCreated /subdir/new.adoc -rw------- Remove file in sub directory: /subdir/new.adoc -- FileStateDeleted /subdir/new.adoc -rw------- Create excluded file in sub directory: /subdir/new.html Create new file under assets: /assets/new -- FileStateCreated /assets/new -rw-------
func (*DirWatcher) Start ¶
func (dw *DirWatcher) Start() (err error)
Start watching changes in directory and its content.
type DirWatcherOptions ¶
type DirWatcherOptions struct { // The Root field define the directory that we want to watch. Root string // Includes contains list of regex to filter file names that we want // to be notified. Includes []string // Excludes contains list of regex to filter file names that we did // not want to be notified. Excludes []string // Delay define a duration when the new changes will be fetched from // system. // This field is optional, minimum is 100 milli second and default // is 5 seconds. Delay time.Duration }
DirWatcherOptions to create and initialize DirWatcher.
The includes and excludes pattern applied relative to the system path. The Excludes patterns will be applied first before the Includes. If the path is not excluded and Includes is empty, it will be assumed as included.
type FileState ¶
type FileState byte
FileState define the state of file. There are four states of file: created, updated on mode, updated on content or deleted.
const ( // FileStateCreated when new file is created. FileStateCreated FileState = iota // FileStateUpdateContent when the content of file is modified. FileStateUpdateContent // FileStateUpdateMode when the mode of file is modified. FileStateUpdateMode // FileStateDeleted when the file has been deleted. FileStateDeleted )
type NodeState ¶
type NodeState struct { // Node represent the file information. Node Node // State of file, its either created, modified, or deleted. State FileState }
NodeState contains the information about the file and its state.
type WatchCallback ¶
type WatchCallback func(*NodeState)
WatchCallback is a function that will be called when Watcher or DirWatcher detect any changes on its file or directory. The watcher will pass the file information and its state.
type Watcher ¶
type Watcher struct { // The channel on which the changes are delivered. C <-chan NodeState // contains filtered or unexported fields }
Watcher is a naive implementation of file event change notification.
func NewWatcher ¶
NewWatcher return a new file watcher that will inspect the file for changes for `path` with period specified by duration `d` argument.
If duration is less or equal to 100 millisecond, it will be set to default duration (5 seconds).
The changes can be consumed from the channel C. If the consumer is slower, channel is full, the changes will be dropped.
Example ¶
package main import ( "fmt" "log" "os" "time" "git.sr.ht/~shulhan/pakakeh.go/lib/watchfs" ) func main() { var ( content = `Content of file` f *os.File watcher *watchfs.Watcher ns watchfs.NodeState err error ) // Create a file to be watched. f, err = os.CreateTemp(``, `watcher`) if err != nil { log.Fatal(err) } watcher, err = watchfs.NewWatcher(f.Name(), 150*time.Millisecond) if err != nil { log.Fatal(err) } // Update file mode. err = f.Chmod(0700) if err != nil { log.Fatal(err) } ns = <-watcher.C fmt.Printf("State: %s\n", ns.State) fmt.Printf("File mode: %s\n", ns.Node.Mode()) fmt.Printf("File size: %d\n", ns.Node.Size()) // Update content of file. _, err = f.WriteString(content) if err != nil { log.Fatal(err) } ns = <-watcher.C fmt.Printf("State: %s\n", ns.State) fmt.Printf("File mode: %s\n", ns.Node.Mode()) fmt.Printf("File size: %d\n", ns.Node.Size()) err = f.Close() if err != nil { log.Fatal(err) } // Remove the file. err = os.Remove(f.Name()) if err != nil { log.Fatal(err) } ns = <-watcher.C fmt.Printf("State: %s\n", ns.State) fmt.Printf("File mode: %s\n", ns.Node.Mode()) fmt.Printf("File size: %d\n", ns.Node.Size()) }
Output: State: FileStateUpdateMode File mode: -rwx------ File size: 0 State: FileStateUpdateContent File mode: -rwx------ File size: 15 State: FileStateDeleted File mode: -rwx------ File size: 15