<commit_before>package kit

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"gopkg.in/fsnotify.v1"
)

const (
	debounceTimeout = 1100 * time.Millisecond
)

var (
	assetLocations = []string{
		filepath.FromSlash("templates/customers"),
		"assets",
		"config",
		"layout",
		"snippets",
		"templates",
		"locales",
		"sections",
	}
)

// FileEventCallback is the callback that is called when there is an event from
// a file watcher.
type FileEventCallback func(ThemeClient, Asset, EventType, error)

// FileWatcher is the object used to watch files for change and notify on any events,
// these events can then be passed along to kit to be sent to shopify.
type FileWatcher struct {
	done     chan bool
	client   ThemeClient
	watcher  *fsnotify.Watcher
	filter   fileFilter
	callback FileEventCallback
	notify   string
}

func newFileWatcher(client ThemeClient, dir, notifyFile string, recur bool, filter fileFilter, callback FileEventCallback) (*FileWatcher, error) {
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		return nil, err
	}

	newWatcher := &FileWatcher{
		done:     make(chan bool),
		client:   client,
		watcher:  watcher,
		callback: callback,
		filter:   filter,
	}

	go newWatcher.watchFsEvents(notifyFile)

	return newWatcher, newWatcher.watchDirectory(dir)
}

func (watcher *FileWatcher) watchDirectory(root string) error {
	root = filepath.Clean(root)
	return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		if info.IsDir() && !watcher.filter.matchesFilter(path) && path != root {
			for _, dir := range assetLocations {
				if strings.HasPrefix(path, filepath.Join(root, dir, string(filepath.Separator))) {
					if err := watcher.watcher.Add(path); err != nil {
						return fmt.Errorf("Could not watch directory %s: %s", path, err)
					}
					break
				}<commit_msg>stopping errors in directory walk<commit_after>package kit

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"gopkg.in/fsnotify.v1"
)

const (
	debounceTimeout = 1100 * time.Millisecond
)

var (
	assetLocations = []string{
		filepath.FromSlash("templates/customers"),
		"assets",
		"config",
		"layout",
		"snippets",
		"templates",
		"locales",
		"sections",
	}
)

// FileEventCallback is the callback that is called when there is an event from
// a file watcher.
type FileEventCallback func(ThemeClient, Asset, EventType, error)

// FileWatcher is the object used to watch files for change and notify on any events,
// these events can then be passed along to kit to be sent to shopify.
type FileWatcher struct {
	done     chan bool
	client   ThemeClient
	watcher  *fsnotify.Watcher
	filter   fileFilter
	callback FileEventCallback
	notify   string
}

func newFileWatcher(client ThemeClient, dir, notifyFile string, recur bool, filter fileFilter, callback FileEventCallback) (*FileWatcher, error) {
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		return nil, err
	}

	newWatcher := &FileWatcher{
		done:     make(chan bool),
		client:   client,
		watcher:  watcher,
		callback: callback,
		filter:   filter,
	}

	go newWatcher.watchFsEvents(notifyFile)

	return newWatcher, newWatcher.watchDirectory(dir)
}

func (watcher *FileWatcher) watchDirectory(root string) error {
	root = filepath.Clean(root)
	return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if info.IsDir() && !watcher.filter.matchesFilter(path) && path != root {
			for _, dir := range assetLocations {
				if strings.HasPrefix(path, filepath.Join(root, dir, string(filepath.Separator))) {
					if err := watcher.watcher.Add(path); err != nil {
						return fmt.Errorf("Could not watch directory %s: %s", path, err)
					}
					break
				}
{'fraction_non_alphanumeric': 0.10989597225926914, 'fraction_numerical': 0.002667377967457989, 'mean_word_length': 3.940711462450593, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3263092', 'n_tokens_mistral': 1335, 'n_tokens_neox': 1224, 'n_words': 367}