mirror of https://github.com/maxcnunes/gaper.git
Improve watching search and configuration by improving default ignore
Now it will ignore by default hidden files and folders, test files and vendor
This commit is contained in:
parent
586c834cb9
commit
a75eac8490
18
README.md
18
README.md
|
@ -49,9 +49,9 @@ GLOBAL OPTIONS:
|
|||
--build-args value arguments used on building the program
|
||||
--program-args value arguments used on executing the program
|
||||
--verbose turns on the verbose messages from gaper
|
||||
--disable-default-ignore turns off default ignore for hidden files and folders, "*_test.go" files, and vendor folder
|
||||
--watch value, -w value list of folders or files to watch for changes
|
||||
--ignore value, -i value list of folders or files to ignore for changes
|
||||
(always ignores all hidden files and directories)
|
||||
--poll-interval value, -p value how often in milliseconds to poll watched files for changes (default: 500)
|
||||
--extensions value, -e value a comma-delimited list of file extensions to watch for changes (default: "go")
|
||||
--no-restart-on value, -n value don't automatically restart the supervised program if it ends:
|
||||
|
@ -62,10 +62,26 @@ GLOBAL OPTIONS:
|
|||
--version, -v print the version
|
||||
```
|
||||
|
||||
Since in most projects there is no need to watch changes of:
|
||||
|
||||
* hidden files and folders
|
||||
* test files (`*_test.go`)
|
||||
* vendor folder
|
||||
|
||||
Gaper by default ignores those cases already. Although, if you need Gaper to watch those files anyway it is possible to disable this setting with `--disable-default-ignore` argument.
|
||||
|
||||
### Examples
|
||||
|
||||
Using all defaults provided by Gaper:
|
||||
|
||||
```
|
||||
gaper
|
||||
```
|
||||
|
||||
Ignore watch over all test files:
|
||||
|
||||
> no need for this in case you are not using `--disable-default-ignore`
|
||||
|
||||
```
|
||||
--ignore './**/*_test.go'
|
||||
```
|
||||
|
|
|
@ -17,16 +17,17 @@ var logger = gaper.NewLogger("gaper")
|
|||
func main() {
|
||||
parseArgs := func(c *cli.Context) *gaper.Config {
|
||||
return &gaper.Config{
|
||||
BinName: c.String("bin-name"),
|
||||
BuildPath: c.String("build-path"),
|
||||
BuildArgsMerged: c.String("build-args"),
|
||||
ProgramArgsMerged: c.String("program-args"),
|
||||
Verbose: c.Bool("verbose"),
|
||||
WatchItems: c.StringSlice("watch"),
|
||||
IgnoreItems: c.StringSlice("ignore"),
|
||||
PollInterval: c.Int("poll-interval"),
|
||||
Extensions: c.StringSlice("extensions"),
|
||||
NoRestartOn: c.String("no-restart-on"),
|
||||
BinName: c.String("bin-name"),
|
||||
BuildPath: c.String("build-path"),
|
||||
BuildArgsMerged: c.String("build-args"),
|
||||
ProgramArgsMerged: c.String("program-args"),
|
||||
Verbose: c.Bool("verbose"),
|
||||
DisableDefaultIgnore: c.Bool("disable-default-ignore"),
|
||||
WatchItems: c.StringSlice("watch"),
|
||||
IgnoreItems: c.StringSlice("ignore"),
|
||||
PollInterval: c.Int("poll-interval"),
|
||||
Extensions: c.StringSlice("extensions"),
|
||||
NoRestartOn: c.String("no-restart-on"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,6 +75,10 @@ func main() {
|
|||
Name: "verbose",
|
||||
Usage: "turns on the verbose messages from gaper",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-default-ignore",
|
||||
Usage: "turns off default ignore for hidden files and folders, \"*_test.go\" files, and vendor folder",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "watch, w",
|
||||
Usage: "list of folders or files to watch for changes",
|
||||
|
|
37
gaper.go
37
gaper.go
|
@ -37,19 +37,20 @@ var exitStatusError = 1
|
|||
|
||||
// Config contains all settings supported by gaper
|
||||
type Config struct {
|
||||
BinName string
|
||||
BuildPath string
|
||||
BuildArgs []string
|
||||
BuildArgsMerged string
|
||||
ProgramArgs []string
|
||||
ProgramArgsMerged string
|
||||
WatchItems []string
|
||||
IgnoreItems []string
|
||||
PollInterval int
|
||||
Extensions []string
|
||||
NoRestartOn string
|
||||
Verbose bool
|
||||
WorkingDirectory string
|
||||
BinName string
|
||||
BuildPath string
|
||||
BuildArgs []string
|
||||
BuildArgsMerged string
|
||||
ProgramArgs []string
|
||||
ProgramArgsMerged string
|
||||
WatchItems []string
|
||||
IgnoreItems []string
|
||||
PollInterval int
|
||||
Extensions []string
|
||||
NoRestartOn string
|
||||
Verbose bool
|
||||
DisableDefaultIgnore bool
|
||||
WorkingDirectory string
|
||||
}
|
||||
|
||||
// Run starts the whole gaper process watching for file changes or exit codes
|
||||
|
@ -61,9 +62,17 @@ func Run(cfg *Config, chOSSiginal chan os.Signal) error {
|
|||
return err
|
||||
}
|
||||
|
||||
wCfg := WatcherConfig{
|
||||
DefaultIgnore: !cfg.DisableDefaultIgnore,
|
||||
PollInterval: cfg.PollInterval,
|
||||
WatchItems: cfg.WatchItems,
|
||||
IgnoreItems: cfg.IgnoreItems,
|
||||
Extensions: cfg.Extensions,
|
||||
}
|
||||
|
||||
builder := NewBuilder(cfg.BuildPath, cfg.BinName, cfg.WorkingDirectory, cfg.BuildArgs)
|
||||
runner := NewRunner(os.Stdout, os.Stderr, filepath.Join(cfg.WorkingDirectory, builder.Binary()), cfg.ProgramArgs)
|
||||
watcher, err := NewWatcher(cfg.PollInterval, cfg.WatchItems, cfg.IgnoreItems, cfg.Extensions)
|
||||
watcher, err := NewWatcher(wCfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("watcher error: %v", err)
|
||||
}
|
||||
|
|
61
watcher.go
61
watcher.go
|
@ -20,6 +20,7 @@ type Watcher interface {
|
|||
|
||||
// watcher is a interface for the watch process
|
||||
type watcher struct {
|
||||
defaultIgnore bool
|
||||
pollInterval int
|
||||
watchItems map[string]bool
|
||||
ignoreItems map[string]bool
|
||||
|
@ -28,27 +29,36 @@ type watcher struct {
|
|||
errors chan error
|
||||
}
|
||||
|
||||
// WatcherConfig defines the settings available for the watcher
|
||||
type WatcherConfig struct {
|
||||
DefaultIgnore bool
|
||||
PollInterval int
|
||||
WatchItems []string
|
||||
IgnoreItems []string
|
||||
Extensions []string
|
||||
}
|
||||
|
||||
// NewWatcher creates a new watcher
|
||||
func NewWatcher(pollInterval int, watchItems []string, ignoreItems []string, extensions []string) (Watcher, error) {
|
||||
if pollInterval == 0 {
|
||||
pollInterval = DefaultPoolInterval
|
||||
func NewWatcher(cfg WatcherConfig) (Watcher, error) {
|
||||
if cfg.PollInterval == 0 {
|
||||
cfg.PollInterval = DefaultPoolInterval
|
||||
}
|
||||
|
||||
if len(extensions) == 0 {
|
||||
extensions = DefaultExtensions
|
||||
if len(cfg.Extensions) == 0 {
|
||||
cfg.Extensions = DefaultExtensions
|
||||
}
|
||||
|
||||
allowedExts := make(map[string]bool)
|
||||
for _, ext := range extensions {
|
||||
for _, ext := range cfg.Extensions {
|
||||
allowedExts["."+ext] = true
|
||||
}
|
||||
|
||||
watchPaths, err := resolvePaths(watchItems, allowedExts)
|
||||
watchPaths, err := resolvePaths(cfg.WatchItems, allowedExts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ignorePaths, err := resolvePaths(ignoreItems, allowedExts)
|
||||
ignorePaths, err := resolvePaths(cfg.IgnoreItems, allowedExts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -58,7 +68,8 @@ func NewWatcher(pollInterval int, watchItems []string, ignoreItems []string, ext
|
|||
return &watcher{
|
||||
events: make(chan string),
|
||||
errors: make(chan error),
|
||||
pollInterval: pollInterval,
|
||||
defaultIgnore: cfg.DefaultIgnore,
|
||||
pollInterval: cfg.PollInterval,
|
||||
watchItems: watchPaths,
|
||||
ignoreItems: ignorePaths,
|
||||
allowedExtensions: allowedExts,
|
||||
|
@ -105,12 +116,7 @@ func (w *watcher) scanChange(watchPath string) (string, error) {
|
|||
var fileChanged string
|
||||
|
||||
err := filepath.Walk(watchPath, func(path string, info os.FileInfo, err error) error {
|
||||
// always ignore hidden files and directories
|
||||
if dir := filepath.Base(path); dir[0] == '.' && dir != "." {
|
||||
return skipFile(info)
|
||||
}
|
||||
|
||||
if _, ignored := w.ignoreItems[path]; ignored {
|
||||
if w.ignoreFile(path, info) {
|
||||
return skipFile(info)
|
||||
}
|
||||
|
||||
|
@ -130,6 +136,31 @@ func (w *watcher) scanChange(watchPath string) (string, error) {
|
|||
return fileChanged, nil
|
||||
}
|
||||
|
||||
func (w *watcher) ignoreFile(path string, info os.FileInfo) bool {
|
||||
// check if preset ignore is enabled
|
||||
if w.defaultIgnore {
|
||||
// check for hidden files and directories
|
||||
if name := info.Name(); name[0] == '.' && name != "." {
|
||||
return true
|
||||
}
|
||||
|
||||
// check if it is a Go testing file
|
||||
if strings.HasSuffix(path, "_test.go") {
|
||||
return true
|
||||
}
|
||||
|
||||
// check if it is the vendor folder
|
||||
if info.IsDir() && info.Name() == "vendor" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if _, ignored := w.ignoreItems[path]; ignored {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func resolvePaths(paths []string, extensions map[string]bool) (map[string]bool, error) {
|
||||
result := map[string]bool{}
|
||||
|
||||
|
|
|
@ -16,7 +16,14 @@ func TestWatcherDefaultValues(t *testing.T) {
|
|||
var ignoreItems []string
|
||||
var extensions []string
|
||||
|
||||
wt, err := NewWatcher(pollInterval, watchItems, ignoreItems, extensions)
|
||||
wCfg := WatcherConfig{
|
||||
DefaultIgnore: true,
|
||||
PollInterval: pollInterval,
|
||||
WatchItems: watchItems,
|
||||
IgnoreItems: ignoreItems,
|
||||
Extensions: extensions,
|
||||
}
|
||||
wt, err := NewWatcher(wCfg)
|
||||
|
||||
expectedPath := "testdata/server"
|
||||
if runtime.GOOS == OSWindows {
|
||||
|
@ -37,7 +44,14 @@ func TestWatcherGlobPath(t *testing.T) {
|
|||
ignoreItems := []string{"./testdata/**/*_test.go"}
|
||||
var extensions []string
|
||||
|
||||
wt, err := NewWatcher(pollInterval, watchItems, ignoreItems, extensions)
|
||||
wCfg := WatcherConfig{
|
||||
DefaultIgnore: true,
|
||||
PollInterval: pollInterval,
|
||||
WatchItems: watchItems,
|
||||
IgnoreItems: ignoreItems,
|
||||
Extensions: extensions,
|
||||
}
|
||||
wt, err := NewWatcher(wCfg)
|
||||
assert.Nil(t, err, "wacher error")
|
||||
w := wt.(*watcher)
|
||||
assert.Equal(t, map[string]bool{"testdata/server/main_test.go": true}, w.ignoreItems)
|
||||
|
@ -49,7 +63,14 @@ func TestWatcherRemoveOverlapdPaths(t *testing.T) {
|
|||
ignoreItems := []string{"./testdata/**/*", "./testdata/server"}
|
||||
var extensions []string
|
||||
|
||||
wt, err := NewWatcher(pollInterval, watchItems, ignoreItems, extensions)
|
||||
wCfg := WatcherConfig{
|
||||
DefaultIgnore: true,
|
||||
PollInterval: pollInterval,
|
||||
WatchItems: watchItems,
|
||||
IgnoreItems: ignoreItems,
|
||||
Extensions: extensions,
|
||||
}
|
||||
wt, err := NewWatcher(wCfg)
|
||||
assert.Nil(t, err, "wacher error")
|
||||
w := wt.(*watcher)
|
||||
assert.Equal(t, map[string]bool{"./testdata/server": true}, w.ignoreItems)
|
||||
|
@ -69,7 +90,14 @@ func TestWatcherWatchChange(t *testing.T) {
|
|||
ignoreItems := []string{testfile}
|
||||
extensions := []string{"go"}
|
||||
|
||||
w, err := NewWatcher(pollInterval, watchItems, ignoreItems, extensions)
|
||||
wCfg := WatcherConfig{
|
||||
DefaultIgnore: true,
|
||||
PollInterval: pollInterval,
|
||||
WatchItems: watchItems,
|
||||
IgnoreItems: ignoreItems,
|
||||
Extensions: extensions,
|
||||
}
|
||||
w, err := NewWatcher(wCfg)
|
||||
assert.Nil(t, err, "wacher error")
|
||||
|
||||
go w.Watch()
|
||||
|
|
Loading…
Reference in New Issue