aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/cli/internal/filewatcher/filewatcher.go
diff options
context:
space:
mode:
author简律纯 <hsiangnianian@outlook.com>2023-04-28 01:36:55 +0800
committer简律纯 <hsiangnianian@outlook.com>2023-04-28 01:36:55 +0800
commitfc8c5fdce62fb229202659408798a7b6c98f6e8b (patch)
tree7554f80e50de4af6fd255afa7c21bcdd58a7af34 /cli/internal/filewatcher/filewatcher.go
parentdd84b9d64fb98746a230cd24233ff50a562c39c9 (diff)
downloadHydroRoll-fc8c5fdce62fb229202659408798a7b6c98f6e8b.tar.gz
HydroRoll-fc8c5fdce62fb229202659408798a7b6c98f6e8b.zip
Diffstat (limited to 'cli/internal/filewatcher/filewatcher.go')
-rw-r--r--cli/internal/filewatcher/filewatcher.go167
1 files changed, 0 insertions, 167 deletions
diff --git a/cli/internal/filewatcher/filewatcher.go b/cli/internal/filewatcher/filewatcher.go
deleted file mode 100644
index 4f79495..0000000
--- a/cli/internal/filewatcher/filewatcher.go
+++ /dev/null
@@ -1,167 +0,0 @@
-// Package filewatcher is used to handle watching for file changes inside the monorepo
-package filewatcher
-
-import (
- "path/filepath"
- "strings"
- "sync"
-
- "github.com/hashicorp/go-hclog"
- "github.com/pkg/errors"
- "github.com/vercel/turbo/cli/internal/turbopath"
-)
-
-// _ignores is the set of paths we exempt from file-watching
-var _ignores = []string{".git", "node_modules"}
-
-// FileWatchClient defines the callbacks used by the file watching loop.
-// All methods are called from the same goroutine so they:
-// 1) do not need synchronization
-// 2) should minimize the work they are doing when called, if possible
-type FileWatchClient interface {
- OnFileWatchEvent(ev Event)
- OnFileWatchError(err error)
- OnFileWatchClosed()
-}
-
-// FileEvent is an enum covering the kinds of things that can happen
-// to files that we might be interested in
-type FileEvent int
-
-const (
- // FileAdded - this is a new file
- FileAdded FileEvent = iota + 1
- // FileDeleted - this file has been removed
- FileDeleted
- // FileModified - this file has been changed in some way
- FileModified
- // FileRenamed - a file's name has changed
- FileRenamed
- // FileOther - some other backend-specific event has happened
- FileOther
-)
-
-var (
- // ErrFilewatchingClosed is returned when filewatching has been closed
- ErrFilewatchingClosed = errors.New("Close() has already been called for filewatching")
- // ErrFailedToStart is returned when filewatching fails to start up
- ErrFailedToStart = errors.New("filewatching failed to start")
-)
-
-// Event is the backend-independent information about a file change
-type Event struct {
- Path turbopath.AbsoluteSystemPath
- EventType FileEvent
-}
-
-// Backend is the interface that describes what an underlying filesystem watching backend
-// must provide.
-type Backend interface {
- AddRoot(root turbopath.AbsoluteSystemPath, excludePatterns ...string) error
- Events() <-chan Event
- Errors() <-chan error
- Close() error
- Start() error
-}
-
-// FileWatcher handles watching all of the files in the monorepo.
-// We currently ignore .git and top-level node_modules. We can revisit
-// if necessary.
-type FileWatcher struct {
- backend Backend
-
- logger hclog.Logger
- repoRoot turbopath.AbsoluteSystemPath
- excludePattern string
-
- clientsMu sync.RWMutex
- clients []FileWatchClient
- closed bool
-}
-
-// New returns a new FileWatcher instance
-func New(logger hclog.Logger, repoRoot turbopath.AbsoluteSystemPath, backend Backend) *FileWatcher {
- excludes := make([]string, len(_ignores))
- for i, ignore := range _ignores {
- excludes[i] = filepath.ToSlash(repoRoot.UntypedJoin(ignore).ToString() + "/**")
- }
- excludePattern := "{" + strings.Join(excludes, ",") + "}"
- return &FileWatcher{
- backend: backend,
- logger: logger,
- repoRoot: repoRoot,
- excludePattern: excludePattern,
- }
-}
-
-// Close shuts down filewatching
-func (fw *FileWatcher) Close() error {
- return fw.backend.Close()
-}
-
-// Start recursively adds all directories from the repo root, redacts the excluded ones,
-// then fires off a goroutine to respond to filesystem events
-func (fw *FileWatcher) Start() error {
- if err := fw.backend.AddRoot(fw.repoRoot, fw.excludePattern); err != nil {
- return err
- }
- if err := fw.backend.Start(); err != nil {
- return err
- }
- go fw.watch()
- return nil
-}
-
-// AddRoot registers the root a filesystem hierarchy to be watched for changes. Events are *not*
-// fired for existing files when AddRoot is called, only for subsequent changes.
-// NOTE: if it appears helpful, we could change this behavior so that we provide a stream of initial
-// events.
-func (fw *FileWatcher) AddRoot(root turbopath.AbsoluteSystemPath, excludePatterns ...string) error {
- return fw.backend.AddRoot(root, excludePatterns...)
-}
-
-// watch is the main file-watching loop. Watching is not recursive,
-// so when new directories are added, they are manually recursively watched.
-func (fw *FileWatcher) watch() {
-outer:
- for {
- select {
- case ev, ok := <-fw.backend.Events():
- if !ok {
- fw.logger.Info("Events channel closed. Exiting watch loop")
- break outer
- }
- fw.clientsMu.RLock()
- for _, client := range fw.clients {
- client.OnFileWatchEvent(ev)
- }
- fw.clientsMu.RUnlock()
- case err, ok := <-fw.backend.Errors():
- if !ok {
- fw.logger.Info("Errors channel closed. Exiting watch loop")
- break outer
- }
- fw.clientsMu.RLock()
- for _, client := range fw.clients {
- client.OnFileWatchError(err)
- }
- fw.clientsMu.RUnlock()
- }
- }
- fw.clientsMu.Lock()
- fw.closed = true
- for _, client := range fw.clients {
- client.OnFileWatchClosed()
- }
- fw.clientsMu.Unlock()
-}
-
-// AddClient registers a client for filesystem events
-func (fw *FileWatcher) AddClient(client FileWatchClient) {
- fw.clientsMu.Lock()
- defer fw.clientsMu.Unlock()
- fw.clients = append(fw.clients, client)
- if fw.closed {
- client.OnFileWatchClosed()
- }
-}