From 2acad09f1f51205fe4fe1fce3aa2c69f9382a1ec Mon Sep 17 00:00:00 2001 From: Nathan Youngman Date: Fri, 15 Aug 2014 22:26:19 -0600 Subject: [PATCH] documentation and golint Improve documentation for exported identifiers. closes #30 --- CHANGELOG.md | 6 +++++- fsnotify.go | 26 +++++++++++------------- fsnotify_bsd.go | 44 ++++++++++++++++++++--------------------- fsnotify_linux.go | 24 +++++++++++----------- fsnotify_open_bsd.go | 2 +- fsnotify_open_darwin.go | 2 +- fsnotify_windows.go | 19 ++++++++---------- 7 files changed, 60 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc01cd8..3e78e16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## v0.14.3 / 2014-08-15 + +* Improve documentation for exported identifiers. [#30](https://github.com/go-fsnotify/fsnotify/issues/30) +* Minor updates based on feedback from golint. + ## v0.14.2 / 2014-07-09 * Moved to [github.com/go-fsnotify/fsnotify](https://github.com/go-fsnotify/fsnotify). @@ -19,7 +24,6 @@ ## v0.13.0 / 2014-06-21 * Events channel of type Event rather than *Event. -* Add/Remove accept a name rather than a path (same behavior). * [API] Remove AddWatch on Windows, use Add. * [internal] use syscall constants directly for inotify and kqueue. * [internal] kqueue: rename events to kevents and fileEvent to event. diff --git a/fsnotify.go b/fsnotify.go index b1bc573..13cce99 100644 --- a/fsnotify.go +++ b/fsnotify.go @@ -4,15 +4,15 @@ // +build !plan9,!solaris -// Package fsnotify implements file system notification. +// Package fsnotify provides a platform-independent interface for file system notifications. package fsnotify import "fmt" -// Event represents a single file system event. +// Event represents a single file system notification. type Event struct { - Name string // Relative path to the file/directory. - Op Op // Platform-independent bitmask. + Name string // Relative path to the file or directory. + Op Op // File operation that triggered the event. } // Op describes a set of file operations. @@ -27,29 +27,25 @@ const ( Chmod ) -// String formats the event e in the form -// "filename: REMOVE|WRITE|..." +// String returns a string representation of the event in the form +// "file: REMOVE|WRITE|..." func (e Event) String() string { events := "" if e.Op&Create == Create { - events += "|" + "CREATE" + events += "|CREATE" } - if e.Op&Remove == Remove { - events += "|" + "REMOVE" + events += "|REMOVE" } - if e.Op&Write == Write { - events += "|" + "WRITE" + events += "|WRITE" } - if e.Op&Rename == Rename { - events += "|" + "RENAME" + events += "|RENAME" } - if e.Op&Chmod == Chmod { - events += "|" + "CHMOD" + events += "|CHMOD" } if len(events) > 0 { diff --git a/fsnotify_bsd.go b/fsnotify_bsd.go index 974056a..c43c972 100644 --- a/fsnotify_bsd.go +++ b/fsnotify_bsd.go @@ -17,13 +17,14 @@ import ( ) const ( - // Watch all events - sys_NOTE_ALLEVENTS = syscall.NOTE_DELETE | syscall.NOTE_WRITE | syscall.NOTE_ATTRIB | syscall.NOTE_RENAME + // Watch all events (except NOTE_EXTEND, NOTE_LINK, NOTE_REVOKE) + noteAllEvents = syscall.NOTE_DELETE | syscall.NOTE_WRITE | syscall.NOTE_ATTRIB | syscall.NOTE_RENAME // Block for 100 ms on each call to kevent keventWaitTime = 100e6 ) +// newEvent returns an platform-independent Event based on kqueue Fflags. func newEvent(name string, mask uint32, create bool) Event { e := Event{Name: name} if create { @@ -44,27 +45,28 @@ func newEvent(name string, mask uint32, create bool) Event { return e } +// Watcher watches a set of files, delivering events to a channel. type Watcher struct { + Events chan Event + Errors chan error mu sync.Mutex // Mutex for the Watcher itself. - kq int // File descriptor (as returned by the kqueue() syscall) - watches map[string]int // Map of watched file descriptors (key: path) + kq int // File descriptor (as returned by the kqueue() syscall). + watches map[string]int // Map of watched file descriptors (key: path). wmut sync.Mutex // Protects access to watches. - enFlags map[string]uint32 // Map of watched files to evfilt note flags used in kqueue + enFlags map[string]uint32 // Map of watched files to evfilt note flags used in kqueue. enmut sync.Mutex // Protects access to enFlags. - paths map[int]string // Map of watched paths (key: watch descriptor) - finfo map[int]os.FileInfo // Map of file information (isDir, isReg; key: watch descriptor) + paths map[int]string // Map of watched paths (key: watch descriptor). + finfo map[int]os.FileInfo // Map of file information (isDir, isReg; key: watch descriptor). pmut sync.Mutex // Protects access to paths and finfo. - fileExists map[string]bool // Keep track of if we know this file exists (to stop duplicate create events) + fileExists map[string]bool // Keep track of if we know this file exists (to stop duplicate create events). femut sync.Mutex // Protects access to fileExists. externalWatches map[string]bool // Map of watches added by user of the library. ewmut sync.Mutex // Protects access to externalWatches. - Errors chan error // Errors are sent on this channel - Events chan Event // Events are returned on this channel done chan bool // Channel for sending a "quit message" to the reader goroutine isClosed bool // Set to true when Close() is first called } -// NewWatcher creates and returns a new kevent instance using kqueue(2) +// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events. func NewWatcher() (*Watcher, error) { fd, errno := syscall.Kqueue() if fd == -1 { @@ -87,9 +89,7 @@ func NewWatcher() (*Watcher, error) { return w, nil } -// Close closes a kevent watcher instance -// It sends a message to the reader goroutine to quit and removes all watches -// associated with the kevent instance +// Close removes all watches and closes the events channel. func (w *Watcher) Close() error { w.mu.Lock() if w.isClosed { @@ -99,7 +99,7 @@ func (w *Watcher) Close() error { w.isClosed = true w.mu.Unlock() - // Send "quit" message to the reader goroutine + // Send "quit" message to the reader goroutine: w.done <- true w.wmut.Lock() ws := w.watches @@ -111,7 +111,7 @@ func (w *Watcher) Close() error { return nil } -// AddWatch adds path to the watched file set. +// addWatch adds path to the watched file set. // The flags are interpreted as described in kevent(2). func (w *Watcher) addWatch(path string, flags uint32) error { w.mu.Lock() @@ -155,7 +155,7 @@ func (w *Watcher) addWatch(path string, flags uint32) error { } } - fd, errno := syscall.Open(path, open_FLAGS, 0700) + fd, errno := syscall.Open(path, openMode, 0700) if fd == -1 { return os.NewSyscallError("Open", errno) } @@ -206,21 +206,21 @@ func (w *Watcher) addWatch(path string, flags uint32) error { return nil } -// Add starts watching on the named file. +// Add starts watching the named file or directory (non-recursively). func (w *Watcher) Add(name string) error { w.ewmut.Lock() w.externalWatches[name] = true w.ewmut.Unlock() - return w.addWatch(name, sys_NOTE_ALLEVENTS) + return w.addWatch(name, noteAllEvents) } -// Remove stops watching on the named file. +// Remove stops watching the the named file or directory (non-recursively). func (w *Watcher) Remove(name string) error { w.wmut.Lock() watchfd, ok := w.watches[name] w.wmut.Unlock() if !ok { - return errors.New(fmt.Sprintf("can't remove non-existent kevent watch for: %s", name)) + return fmt.Errorf("can't remove non-existent kevent watch for: %s", name) } var kbuf [1]syscall.Kevent_t watchEntry := &kbuf[0] @@ -399,7 +399,7 @@ func (w *Watcher) watchDirectoryFiles(dirPath string) error { if fileInfo.IsDir() == false { // Watch file to mimic linux fsnotify - e := w.addWatch(filePath, sys_NOTE_ALLEVENTS) + e := w.addWatch(filePath, noteAllEvents) if e != nil { return e } diff --git a/fsnotify_linux.go b/fsnotify_linux.go index 52cacee..51aca18 100644 --- a/fsnotify_linux.go +++ b/fsnotify_linux.go @@ -15,11 +15,12 @@ import ( ) const ( - sys_AGNOSTIC_EVENTS = syscall.IN_MOVED_TO | syscall.IN_MOVED_FROM | + agnosticEvents = syscall.IN_MOVED_TO | syscall.IN_MOVED_FROM | syscall.IN_CREATE | syscall.IN_ATTRIB | syscall.IN_MODIFY | syscall.IN_MOVE_SELF | syscall.IN_DELETE | syscall.IN_DELETE_SELF ) +// newEvent returns an platform-independent Event based on an inotify mask. func newEvent(name string, mask uint32) Event { e := Event{Name: name} if mask&syscall.IN_CREATE == syscall.IN_CREATE || mask&syscall.IN_MOVED_TO == syscall.IN_MOVED_TO { @@ -45,18 +46,19 @@ type watch struct { flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags) } +// Watcher watches a set of files, delivering events to a channel. type Watcher struct { + Events chan Event + Errors chan error mu sync.Mutex // Map access fd int // File descriptor (as returned by the inotify_init() syscall) watches map[string]*watch // Map of inotify watches (key: path) paths map[int]string // Map of watched paths (key: watch descriptor) - Errors chan error // Errors are sent on this channel - Events chan Event // Events are returned on this channel done chan bool // Channel for sending a "quit message" to the reader goroutine isClosed bool // Set to true when Close() is first called } -// NewWatcher creates and returns a new inotify instance using inotify_init(2) +// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events. func NewWatcher() (*Watcher, error) { fd, errno := syscall.InotifyInit() if fd == -1 { @@ -75,9 +77,7 @@ func NewWatcher() (*Watcher, error) { return w, nil } -// Close closes an inotify watcher instance -// It sends a message to the reader goroutine to quit and removes all watches -// associated with the inotify instance +// Close removes all watches and closes the events channel. func (w *Watcher) Close() error { if w.isClosed { return nil @@ -95,13 +95,13 @@ func (w *Watcher) Close() error { return nil } -// Add starts watching on the named file. +// Add starts watching the named file or directory (non-recursively). func (w *Watcher) Add(name string) error { if w.isClosed { return errors.New("inotify instance already closed") } - var flags uint32 = sys_AGNOSTIC_EVENTS + var flags uint32 = agnosticEvents w.mu.Lock() watchEntry, found := w.watches[name] @@ -123,13 +123,13 @@ func (w *Watcher) Add(name string) error { return nil } -// Remove stops watching on the named file. +// Remove stops watching the the named file or directory (non-recursively). func (w *Watcher) Remove(name string) error { w.mu.Lock() defer w.mu.Unlock() watch, ok := w.watches[name] if !ok { - return errors.New(fmt.Sprintf("can't remove non-existent inotify watch for: %s", name)) + return fmt.Errorf("can't remove non-existent inotify watch for: %s", name) } success, errno := syscall.InotifyRmWatch(w.fd, watch.wd) if success == -1 { @@ -178,7 +178,7 @@ func (w *Watcher) readEvents() { continue } - var offset uint32 = 0 + var offset uint32 // We don't know how many events we just read into the buffer // While the offset points to at least one whole event... for offset <= uint32(n-syscall.SizeofInotifyEvent) { diff --git a/fsnotify_open_bsd.go b/fsnotify_open_bsd.go index 37ea998..2f9b20a 100644 --- a/fsnotify_open_bsd.go +++ b/fsnotify_open_bsd.go @@ -8,4 +8,4 @@ package fsnotify import "syscall" -const open_FLAGS = syscall.O_NONBLOCK | syscall.O_RDONLY +const openMode = syscall.O_NONBLOCK | syscall.O_RDONLY diff --git a/fsnotify_open_darwin.go b/fsnotify_open_darwin.go index d450318..a0ceef3 100644 --- a/fsnotify_open_darwin.go +++ b/fsnotify_open_darwin.go @@ -8,4 +8,4 @@ package fsnotify import "syscall" -const open_FLAGS = syscall.O_EVTONLY +const openMode = syscall.O_EVTONLY diff --git a/fsnotify_windows.go b/fsnotify_windows.go index b2d3771..31c13ba 100644 --- a/fsnotify_windows.go +++ b/fsnotify_windows.go @@ -94,20 +94,19 @@ type watch struct { type indexMap map[uint64]*watch type watchMap map[uint32]indexMap -// A Watcher waits for and receives event notifications -// for a specific set of files and directories. +// Watcher watches a set of files, delivering events to a channel. type Watcher struct { + Events chan Event + Errors chan error + isClosed bool // Set to true when Close() is first called mu sync.Mutex // Map access port syscall.Handle // Handle to completion port watches watchMap // Map of watches (key: i-number) input chan *input // Inputs to the reader are sent on this channel - Events chan Event // Events are returned on this channel - Errors chan error // Errors are sent on this channel - isClosed bool // Set to true when Close() is first called quit chan chan<- error } -// NewWatcher creates and returns a Watcher. +// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events. func NewWatcher() (*Watcher, error) { port, e := syscall.CreateIoCompletionPort(syscall.InvalidHandle, 0, 0, 0) if e != nil { @@ -125,9 +124,7 @@ func NewWatcher() (*Watcher, error) { return w, nil } -// Close closes a Watcher. -// It sends a message to the reader goroutine to quit and removes all watches -// associated with the watcher. +// Close removes all watches and closes the events channel. func (w *Watcher) Close() error { if w.isClosed { return nil @@ -161,12 +158,12 @@ func (w *Watcher) AddWatch(name string, flags uint32) error { return <-in.reply } -// Add starts watching on the named file. +// Add starts watching the named file or directory (non-recursively). func (w *Watcher) Add(name string) error { return w.AddWatch(name, sys_FS_ALL_EVENTS) } -// Remove stops watching on the named file. +// Remove stops watching the the named file or directory (non-recursively). func (w *Watcher) Remove(name string) error { in := &input{ op: opRemoveWatch, -- 2.50.1