fswatch

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 23, 2026 License: MIT Imports: 6 Imported by: 0

README

go-fswatch

CI Go Reference License

Polling-based file system watcher for Go. Zero dependencies

Installation

go get github.com/philiprehberger/go-fswatch

Usage

package main

import (
	"context"
	"fmt"
	"os/signal"
	"syscall"
	"time"

	"github.com/philiprehberger/go-fswatch"
)

func main() {
	w, err := fswatch.New(
		fswatch.Paths("./src", "./config"),
		fswatch.Glob("*.go", "*.yaml"),
		fswatch.Ignore(".git", "*.tmp", "node_modules"),
		fswatch.Debounce(300*time.Millisecond),
		fswatch.PollInterval(1*time.Second),
		fswatch.Recursive(true),
	)
	if err != nil {
		panic(err)
	}

	w.OnChange(func(events []fswatch.Event) {
		for _, e := range events {
			fmt.Printf("%s %s\n", e.Op, e.Path)
		}
	})

	ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
	defer stop()

	if err := w.Start(ctx); err != nil && err != context.Canceled {
		panic(err)
	}
}
Per-Event Callbacks

Register callbacks for specific event types. These fire in addition to OnChange:

w.OnCreate(func(e fswatch.Event) {
	fmt.Println("created:", e.Path)
})

w.OnModify(func(e fswatch.Event) {
	fmt.Println("modified:", e.Path)
})

w.OnDelete(func(e fswatch.Event) {
	fmt.Println("deleted:", e.Path)
})
Single File Watching

Use WatchFile to watch a single file without setting up paths and globs manually:

w, err := fswatch.WatchFile("config.yaml", func(e fswatch.Event) {
	fmt.Printf("config changed: %s\n", e.Op)
})
if err != nil {
	panic(err)
}

ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()
_ = w.Start(ctx)
Snapshot

Retrieve the current map of tracked files and their last modification times:

snap := w.Snapshot()
for path, modTime := range snap {
	fmt.Printf("%s last modified at %s\n", path, modTime)
}
Configuration
Option Description Default
Paths(...) Directories to watch required
Glob(...) Include patterns all files
Ignore(...) Exclude patterns none
Debounce(d) Debounce interval 500ms
PollInterval(d) Poll frequency 1s
Recursive(bool) Watch subdirs true
MaxDepth(n) Limit recursion depth (0 = top dir only) unlimited
Events
Op Description
Create New file detected
Modify File content changed
Delete File removed

API

Function / Type Description
New(opts ...Option) (*Watcher, error) Create a new watcher
WatchFile(path string, fn func(Event), opts ...Option) (*Watcher, error) Watch a single file
(*Watcher).OnChange(fn func([]Event)) Register batch change callback
(*Watcher).OnCreate(fn func(Event)) Register create-only callback
(*Watcher).OnModify(fn func(Event)) Register modify-only callback
(*Watcher).OnDelete(fn func(Event)) Register delete-only callback
(*Watcher).Start(ctx context.Context) error Start watching (blocks)
(*Watcher).Close() error Stop watching
(*Watcher).Snapshot() map[string]time.Time Get tracked files and mod times
Paths(paths ...string) Option Set directories to watch
Glob(patterns ...string) Option Set include patterns
Ignore(patterns ...string) Option Set exclude patterns
Debounce(d time.Duration) Option Set debounce interval
PollInterval(d time.Duration) Option Set poll frequency
Recursive(enabled bool) Option Enable/disable recursive watching
MaxDepth(n int) Option Limit recursion depth
Event File system change event
Op Operation type (Create, Modify, Delete)

Development

go test ./...
go vet ./...

License

MIT

Documentation

Overview

Package fswatch provides a polling-based file system watcher for Go.

It uses polling (not OS-level events) to detect file changes, which means zero external dependencies. File modification times are tracked via os.Stat, directories are walked with filepath.WalkDir, and glob matching uses filepath.Match from the standard library.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Event

type Event struct {
	// Path is the absolute path of the affected file.
	Path string
	// Op is the operation that triggered the event.
	Op Op
	// ModTime is the last modification time of the file at the time the event was detected.
	ModTime time.Time
}

Event represents a file system change event.

type Op

type Op int

Op describes a set of file operations.

const (
	// Create indicates a new file was detected.
	Create Op = iota + 1
	// Modify indicates a file's content changed.
	Modify
	// Delete indicates a file was removed.
	Delete
)

func (Op) String

func (o Op) String() string

String returns a human-readable representation of the operation.

type Option

type Option func(*config)

Option configures a Watcher.

func Debounce

func Debounce(d time.Duration) Option

Debounce sets the debounce interval. Events are batched and delivered after no new events have been detected for this duration. Default is 500ms.

func Glob

func Glob(patterns ...string) Option

Glob sets file patterns to include (e.g., "*.yaml", "*.go"). Patterns are matched using filepath.Match against the file's base name. If no glob patterns are set, all files are included.

func Ignore

func Ignore(patterns ...string) Option

Ignore sets patterns to exclude (e.g., ".git", "*.tmp", "node_modules"). Patterns are matched using filepath.Match against the file's base name.

func MaxDepth added in v0.2.0

func MaxDepth(n int) Option

MaxDepth limits the recursion depth when watching directories. A depth of 0 means only the specified directory (no subdirectories), 1 means one level of subdirectories, and so on. MaxDepth implicitly enables recursive watching. By default there is no depth limit.

func Paths

func Paths(paths ...string) Option

Paths sets the directories to watch.

func PollInterval

func PollInterval(d time.Duration) Option

PollInterval sets how often the watcher checks for file system changes. Default is 1s.

func Recursive

func Recursive(enabled bool) Option

Recursive sets whether subdirectories are watched. Default is true.

type Watcher

type Watcher struct {
	// contains filtered or unexported fields
}

Watcher watches directories for file system changes using polling.

func New

func New(opts ...Option) (*Watcher, error)

New creates a new Watcher with the given options. At least one path must be specified via the Paths option.

func WatchFile added in v0.2.0

func WatchFile(path string, fn func(Event), opts ...Option) (*Watcher, error)

WatchFile is a convenience function that creates a watcher for a single file. It watches the file's parent directory with a glob matching only the target filename, and registers fn as the OnChange callback.

func (*Watcher) Close

func (w *Watcher) Close() error

Close stops the watcher. It is safe to call multiple times.

func (*Watcher) OnChange

func (w *Watcher) OnChange(fn func(events []Event))

OnChange registers a callback that is called with a batch of events whenever file system changes are detected. Only one callback can be registered; subsequent calls overwrite the previous callback.

func (*Watcher) OnCreate added in v0.2.0

func (w *Watcher) OnCreate(fn func(Event))

OnCreate registers a callback that fires for each Create event individually, in addition to the OnChange batch callback. Subsequent calls overwrite the previous callback.

func (*Watcher) OnDelete added in v0.2.0

func (w *Watcher) OnDelete(fn func(Event))

OnDelete registers a callback that fires for each Delete event individually, in addition to the OnChange batch callback. Subsequent calls overwrite the previous callback.

func (*Watcher) OnModify added in v0.2.0

func (w *Watcher) OnModify(fn func(Event))

OnModify registers a callback that fires for each Modify event individually, in addition to the OnChange batch callback. Subsequent calls overwrite the previous callback.

func (*Watcher) Snapshot added in v0.2.0

func (w *Watcher) Snapshot() map[string]time.Time

Snapshot returns a copy of the current map of tracked file paths to their last modification times. If the watcher has not been started yet, the returned map will be empty.

func (*Watcher) Start

func (w *Watcher) Start(ctx context.Context) error

Start begins watching for file system changes. It blocks until the provided context is cancelled or Close is called.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL