diff --git a/cmd/testomatic.go b/cmd/testomatic.go index dcd5f16..84fb92c 100644 --- a/cmd/testomatic.go +++ b/cmd/testomatic.go @@ -5,7 +5,6 @@ import ( "flag" "fmt" "io/ioutil" - "log" "os" "os/exec" "path/filepath" @@ -19,6 +18,7 @@ import ( ) const ( + // scopes to create the relative path current = "current" dir = "dir" all = "all" @@ -30,17 +30,17 @@ var ( showWatched = flag.Bool("show", false, "Show files watched") ) -func Run() { +func Run() error { flag.Parse() w := watcher.New() data, err := ioutil.ReadFile(*file) if err != nil { - log.Fatal(err) + return err } if err := conf.Parse(data); err != nil { - log.Fatal(err) + return err } // file or directory writting (so two in total) @@ -48,9 +48,11 @@ func Run() { w.FilterOps(watcher.Write) w.IgnoreHiddenFiles(conf.Watch.IgnoreHidden) + w.Ignore(conf.Watch.Ignore...) + w.FilterFiles(conf.Watch.Regex) if err := w.AddRecursive(conf.Watch.Root); err != nil { - log.Fatalln(err) + return err } // Print a list of all of the files and folders currently @@ -61,48 +63,71 @@ func Run() { } } - go func() { + go func() error { for { select { case event := <-w.Event: if !event.IsDir() { - result := fireCmd(event) - fmt.Println(result) + result, err := fireCmd(event) + if err != nil { + return err + } + + fmt.Println(*result) if !conf.Notification.Disable { - notify(conf, result) + notify(conf, *result) } } case err := <-w.Error: - log.Fatalln(err) + return err case <-w.Closed: - return + return nil } } }() + if err != nil { + return err + } + fmt.Print("Testomatic is watching the files... \n") if err := w.Start(time.Millisecond * 100); err != nil { - log.Fatalln(err) + return err } + + return nil } -func fireCmd(event watcher.Event) string { +func fireCmd(event watcher.Event) (*string, error) { if conf.Command.IgnorePath { - return execCmd(conf.Command.Bin, conf.Command.Options) + result, err := execCmd(conf.Command.Bin, conf.Command.Options) + if err != nil { + return nil, err + } + return result, nil } - path := event.Path - + var path *string + path = &event.Path if filepath.IsAbs(event.Path) && conf.Command.Abs != true { - path = CreateRelative(event.Path, conf.Watch.Root, conf.Command.Scope) + var err error + path, err = CreateRelative(event.Path, conf.Watch.Root, conf.Command.Scope) + if err != nil { + return nil, err + } } - options := append(conf.Command.Options, path) - return execCmd(conf.Command.Bin, options) + options := append(conf.Command.Options, *path) + result, err := execCmd(conf.Command.Bin, options) + if err != nil { + return nil, err + } + + return result, nil } -func execCmd(cmdPath string, args []string) string { +func execCmd(cmdPath string, args []string) (*string, error) { var out bytes.Buffer var stderr bytes.Buffer @@ -117,40 +142,56 @@ func execCmd(cmdPath string, args []string) string { err := cmd.Run() if err != nil { - fmt.Println(fmt.Sprint(err) + ": " + stderr.String()) + return nil, err } - return out.String() + result := out.String() + return &result, nil } // CreateRelative path from absolute path // A point "." means that the path begins by the current directory -func CreateRelative(path, confPath, scope string) string { +// TODO refactor... +func CreateRelative(path, confPath, scope string) (*string, error) { newpath := make([]string, 2) // Get the current directory where testomatic runs if strings.Index(confPath, ".") != -1 { confPath = "." - currentDir, _ := filepath.Abs(".") - split := strings.SplitAfter(currentDir, "/") - currentDir = split[len(split)-1] - newpath = strings.SplitAfter(path, currentDir) + currentDir, err := getProjectDir() + if err != nil { + return nil, err + } + + split := strings.SplitAfter(*currentDir, "/") + *currentDir = split[len(split)-1] + newpath = strings.SplitAfter(path, *currentDir) } else { newpath = strings.SplitAfter(path, confPath) } if scope == dir { - return confPath + filepath.Dir(newpath[1]) + finalPath := confPath + filepath.Dir(newpath[1]) + return &finalPath, nil } if scope == current { - return confPath + newpath[1] + finalPath := confPath + newpath[1] + return &finalPath, nil } if scope == all { - return confPath + return &confPath, nil + } + + return nil, nil +} +func getProjectDir() (*string, error) { + projectDir, err := filepath.Abs(".") + if err != nil { + return nil, err } - return "" + return &projectDir, nil } func notify(conf config.YamlConf, result string) { diff --git a/cmd/testomatic_test.go b/cmd/testomatic_test.go index dcaaa63..ac3b00d 100644 --- a/cmd/testomatic_test.go +++ b/cmd/testomatic_test.go @@ -14,17 +14,17 @@ func TestCreateRelative(t *testing.T) { filepath := "src/" expected := "src/tests/tests.go" - if v := CreateRelative(path, filepath, "current"); v != expected { - t.Errorf(ErrorTest(expected, v)) + if v, _ := CreateRelative(path, filepath, "current"); *v != expected { + t.Errorf(ErrorTest(expected, *v)) } expected = "src/tests" - if v := CreateRelative(path, filepath, "dir"); v != expected { - t.Errorf(ErrorTest(expected, v)) + if v, _ := CreateRelative(path, filepath, "dir"); *v != expected { + t.Errorf(ErrorTest(expected, *v)) } expected = "src/" - if v := CreateRelative(path, filepath, "all"); v != expected { - t.Errorf(ErrorTest(expected, v)) + if v, _ := CreateRelative(path, filepath, "all"); *v != expected { + t.Errorf(ErrorTest(expected, *v)) } } diff --git a/examples/go/.testomatic_all.yml b/examples/go/.testomatic_all.yml index bffa328..e1bb801 100644 --- a/examples/go/.testomatic_all.yml +++ b/examples/go/.testomatic_all.yml @@ -2,6 +2,8 @@ watch: folder: ./ regex: "_test.go" + ignore: + - vendor ignore_hidden: true command: ignore_path: true diff --git a/examples/go/.testomatic_single.yml b/examples/go/.testomatic_single.yml index eb4b0ef..77a57d6 100644 --- a/examples/go/.testomatic_single.yml +++ b/examples/go/.testomatic_single.yml @@ -2,6 +2,8 @@ watch: root: . regex: "_test.go" + ignore: + - vendor ignore_hidden: true command: bin: go diff --git a/internal/config/testdata/testomatic.yml b/internal/config/testdata/testomatic.yml index 0120919..ef5fb7d 100644 --- a/internal/config/testdata/testomatic.yml +++ b/internal/config/testdata/testomatic.yml @@ -1,6 +1,8 @@ watch: root: src/Tests regex: "Test.php" + ignore: + - vendor ignore_hidden: true command: bin: docker-compose diff --git a/internal/config/yaml.go b/internal/config/yaml.go index da98b94..6180db9 100644 --- a/internal/config/yaml.go +++ b/internal/config/yaml.go @@ -9,6 +9,7 @@ type ( Root string Regex string IgnoreHidden bool `yaml:"ignore_hidden"` + Ignore []string } command struct { diff --git a/internal/config/yaml_test.go b/internal/config/yaml_test.go index 846a197..7b334b3 100644 --- a/internal/config/yaml_test.go +++ b/internal/config/yaml_test.go @@ -25,6 +25,7 @@ func TestParse(t *testing.T) { assert("src/Tests", config.Watch.Root) assert("Test.php", config.Watch.Regex) + assert("vendor", config.Watch.Ignore[0]) assert(true, config.Watch.IgnoreHidden) assert("docker-compose", config.Command.Bin) assert(false, config.Command.Abs) diff --git a/main.go b/main.go index ea95c5f..2becf6f 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,12 @@ package main import ( + "log" + testomatic "github.com/Phantas0s/testomatic/cmd" ) func main() { - testomatic.Run() + err := testomatic.Run() + log.Fatal(err) }