Author: LakeFox
Email: [email protected]
Date: Thu, 20 Feb 2025 16:49:25 -0700
watcher/main.go
Init
Commits
Diff
package watcher

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"
	"github.com/fsnotify/fsnotify"
)

// !MAN: Test
func New(dir string, handler func(string, string)) {
	// Create a new watcher
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		log.Fatal(err)
	}
	defer watcher.Close()
	// Add directories recursively
	err = addWatchRecursive(watcher, dir)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Watching directory and subdirectories: %s\n", dir)

	// Channel to signal exit
	done := make(chan bool)
	

	cwd, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
	// Start watching for events 
	go func() {
		for {
			select {
			case event, ok := <-watcher.Events:
				if !ok {
					return
				}

				path := filepath.Join(cwd, event.Name)

				if (event.Op&fsnotify.Create == fsnotify.Create || 
					event.Op&fsnotify.Rename == fsnotify.Rename || 
					event.Op&fsnotify.Write == fsnotify.Write) && HasNoHiddenPath(path) {
					handler(fmt.Sprint(event.Op), path)
				}
			
				// If a new directory is created, add it to the watcher
				if event.Op&fsnotify.Create == fsnotify.Create {
					info, err := os.Stat(event.Name)
					if err == nil && info.IsDir() {
						err := addWatchRecursive(watcher, event.Name)
						if err != nil {
							log.Printf("Failed to watch new directory: %s\n", err)
						}
					}
				}

			case err, ok := <-watcher.Errors:
				if !ok {
					return
				}
				fmt.Printf("Error: %s\n", err)
			}
		}
	}()

	// Wait for the watcher to finish
	<-done
}

// addWatchRecursive adds a directory and all its subdirectories to the watcher
func addWatchRecursive(watcher *fsnotify.Watcher, dir string) error {
	return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			err := watcher.Add(path)
			if err != nil {
				log.Printf("Error adding directory to watcher: %s\n", err)
				return err
			}
		}
		return nil
	})
}

func HasNoHiddenPath(path string) bool {
	components := strings.Split(filepath.Clean(path), string(filepath.Separator))
	for _, component := range components {
		if strings.HasPrefix(component, ".") {
			return false
		}
	}
	return true
}

// !remove comments