From f980722912538334de992b84748906f451814ca6 Mon Sep 17 00:00:00 2001 From: alessio Date: Sun, 16 Apr 2017 12:04:40 +0200 Subject: [PATCH] go vet support, array of cmds and args options for build/install --- watcher/cmd.go | 81 ++++++++++++++++++++++++++++++++++----------- watcher/exec.go | 31 +++++++++++------- watcher/main.go | 43 +++++++++++++++++------- watcher/watcher.go | 82 ++++++++++++++++++---------------------------- 4 files changed, 144 insertions(+), 93 deletions(-) diff --git a/watcher/cmd.go b/watcher/cmd.go index 5f88012..a8edf6e 100644 --- a/watcher/cmd.go +++ b/watcher/cmd.go @@ -3,10 +3,9 @@ package watcher import ( "errors" "fmt" - "strings" - "github.com/tockins/realize/style" cli "gopkg.in/urfave/cli.v2" + "strings" ) // Run launches the toolchain for each project @@ -15,7 +14,41 @@ func (h *Blueprint) Run() error { if err == nil { // loop projects wg.Add(len(h.Projects)) - for k := range h.Projects { + for k, element := range h.Projects { + tools := tools{} + if element.Cmds.Fmt { + tools.Fmt = tool{ + status: &h.Projects[k].Cmds.Fmt, + cmd: "gofmt", + options: []string{"-s", "-w", "-e"}, + name: "Go Fmt", + } + } + if element.Cmds.Generate { + tools.Generate = tool{ + status: &h.Projects[k].Cmds.Generate, + cmd: "go", + options: []string{"generate"}, + name: "Go Generate", + } + } + if element.Cmds.Test { + tools.Test = tool{ + status: &h.Projects[k].Cmds.Test, + cmd: "go", + options: []string{"test"}, + name: "Go Test", + } + } + if element.Cmds.Vet { + tools.Vet = tool{ + status: &h.Projects[k].Cmds.Vet, + cmd: "go", + options: []string{"test"}, + name: "Go Test", + } + } + h.Projects[k].tools = tools h.Projects[k].parent = h h.Projects[k].path = h.Projects[k].Path if h.Legacy.Status { @@ -33,15 +66,23 @@ func (h *Blueprint) Run() error { // Add a new project func (h *Blueprint) Add(p *cli.Context) error { project := Project{ - Name: h.Name(p.String("name"), p.String("path")), - Path: h.Path(p.String("path")), - Fmt: !p.Bool("no-fmt"), - Generate: p.Bool("generate"), - Test: p.Bool("test"), - Build: p.Bool("build"), - Bin: !p.Bool("no-bin"), - Run: !p.Bool("no-run"), - Params: argsParam(p), + Name: h.Name(p.String("name"), p.String("path")), + Path: h.Path(p.String("path")), + Cmds: Cmds{ + + Vet: p.Bool("vet"), + Fmt: !p.Bool("no-fmt"), + Test: p.Bool("test"), + Generate: p.Bool("generate"), + Build: Cmd{ + Status: p.Bool("build"), + }, + Bin: Cmd{ + Status: !p.Bool("no-bin"), + }, + Run: !p.Bool("no-run"), + }, + Args: argsParam(p), Watcher: Watcher{ Paths: []string{"/"}, Ignore: []string{"vendor"}, @@ -94,14 +135,14 @@ func (h *Blueprint) List() error { name := style.Magenta.Bold("[") + strings.ToUpper(val.Name) + style.Magenta.Bold("]") fmt.Println(name, style.Yellow.Regular("Base Path"), ":", style.Magenta.Regular(val.Path)) - fmt.Println(name, style.Yellow.Regular("Fmt"), ":", style.Magenta.Regular(val.Fmt)) - fmt.Println(name, style.Yellow.Regular("Generate"), ":", style.Magenta.Regular(val.Generate)) - fmt.Println(name, style.Yellow.Regular("Test"), ":", style.Magenta.Regular(val.Test)) - fmt.Println(name, style.Yellow.Regular("Install"), ":", style.Magenta.Regular(val.Bin)) - fmt.Println(name, style.Yellow.Regular("Build"), ":", style.Magenta.Regular(val.Build)) - fmt.Println(name, style.Yellow.Regular("Run"), ":", style.Magenta.Regular(val.Run)) - if len(val.Params) > 0 { - fmt.Println(name, style.Yellow.Regular("Params"), ":", style.Magenta.Regular(val.Params)) + fmt.Println(name, style.Yellow.Regular("Fmt"), ":", style.Magenta.Regular(val.Cmds.Fmt)) + fmt.Println(name, style.Yellow.Regular("Generate"), ":", style.Magenta.Regular(val.Cmds.Generate)) + fmt.Println(name, style.Yellow.Regular("Test"), ":", style.Magenta.Regular(val.Cmds.Test)) + fmt.Println(name, style.Yellow.Regular("Install"), ":", style.Magenta.Regular(val.Cmds.Bin)) + fmt.Println(name, style.Yellow.Regular("Build"), ":", style.Magenta.Regular(val.Cmds.Build)) + fmt.Println(name, style.Yellow.Regular("Run"), ":", style.Magenta.Regular(val.Cmds.Run)) + if len(val.Args) > 0 { + fmt.Println(name, style.Yellow.Regular("Params"), ":", style.Magenta.Regular(val.Args)) } fmt.Println(name, style.Yellow.Regular("Watcher"), ":") fmt.Println(name, "\t", style.Yellow.Regular("Preview"), ":", style.Magenta.Regular(val.Watcher.Preview)) diff --git a/watcher/exec.go b/watcher/exec.go index 2797c88..72a6d27 100644 --- a/watcher/exec.go +++ b/watcher/exec.go @@ -4,6 +4,7 @@ import ( "bufio" "bytes" "fmt" + "github.com/tockins/realize/style" "log" "os" "os/exec" @@ -11,18 +12,16 @@ import ( "strings" "sync" "time" - - "github.com/tockins/realize/style" ) // GoRun is an implementation of the bin execution func (p *Project) goRun(channel chan bool, runner chan bool, wr *sync.WaitGroup) error { var build *exec.Cmd - var params []string + var args []string var path = "" - for _, param := range p.Params { - arr := strings.Fields(param) - params = append(params, arr...) + for _, arg := range p.Args { + arr := strings.Fields(arg) + args = append(args, arr...) } if _, err := os.Stat(filepath.Join(p.base, p.path)); err == nil { path = filepath.Join(p.base, p.path) @@ -32,12 +31,12 @@ func (p *Project) goRun(channel chan bool, runner chan bool, wr *sync.WaitGroup) } if path != "" { - build = exec.Command(path, params...) + build = exec.Command(path, args...) } else { if _, err := os.Stat(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.path))); err == nil { - build = exec.Command(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.path)), params...) + build = exec.Command(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.path)), args...) } else if _, err := os.Stat(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.path)) + ".exe"); err == nil { - build = exec.Command(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.path))+".exe", params...) + build = exec.Command(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.path))+".exe", args...) } else { p.Buffer.StdLog = append(p.Buffer.StdLog, BufferOut{Time: time.Now(), Text: "Can't run a not compiled project"}) p.Fatal(err, "Can't run a not compiled project", ":") @@ -102,7 +101,12 @@ func (p *Project) goRun(channel chan bool, runner chan bool, wr *sync.WaitGroup) func (p *Project) goBuild() (string, error) { var out bytes.Buffer var stderr bytes.Buffer - build := exec.Command("go", "build") + args := []string{"build"} + for _, arg := range p.Cmds.Build.Args { + arr := strings.Fields(arg) + args = append(args, arr...) + } + build := exec.Command("go", args...) build.Dir = p.base build.Stdout = &out build.Stderr = &stderr @@ -120,7 +124,12 @@ func (p *Project) goInstall() (string, error) { if err != nil { return "", err } - build := exec.Command("go", "install") + args := []string{"install"} + for _, arg := range p.Cmds.Bin.Args { + arr := strings.Fields(arg) + args = append(args, arr...) + } + build := exec.Command("go", args...) build.Dir = p.base build.Stdout = &out build.Stderr = &stderr diff --git a/watcher/main.go b/watcher/main.go index 2364b4e..ac38a06 100644 --- a/watcher/main.go +++ b/watcher/main.go @@ -1,11 +1,10 @@ package watcher import ( + "github.com/tockins/realize/settings" "log" "sync" "time" - - "github.com/tockins/realize/settings" ) var wg sync.WaitGroup @@ -21,8 +20,7 @@ type pollWatcher struct { } // Log struct -type logWriter struct { -} +type logWriter struct{} // Blueprint struct contains a projects list type Blueprint struct { @@ -38,18 +36,41 @@ type Project struct { base string Name string `yaml:"name" json:"name"` Path string `yaml:"path" json:"path"` - Fmt bool `yaml:"fmt" json:"fmt"` - Generate bool `yaml:"generate" json:"generate"` - Test bool `yaml:"test" json:"test"` - Bin bool `yaml:"bin" json:"bin"` - Build bool `yaml:"build" json:"build"` - Run bool `yaml:"run" json:"run"` - Params []string `yaml:"params,omitempty" json:"params,omitempty"` + Cmds Cmds `yaml:"cmds" json:"cmds"` + Args []string `yaml:"args,omitempty" json:"args,omitempty"` Watcher Watcher `yaml:"watcher" json:"watcher"` Streams Streams `yaml:"streams" json:"streams"` Buffer Buffer `yaml:"-" json:"buffer"` parent *Blueprint path string + tools tools +} + +type tools struct { + Fmt, Test, Generate, Vet tool +} + +type tool struct { + status *bool + cmd string + options []string + name string +} + +type Cmds struct { + Vet bool `yaml:"vet" json:"vet"` + Fmt bool `yaml:"fmt" json:"fmt"` + Test bool `yaml:"test" json:"test"` + Generate bool `yaml:"generate" json:"generate"` + Bin Cmd `yaml:"bin" json:"bin"` + Build Cmd `yaml:"build" json:"build"` + Run bool `yaml:"run" json:"run"` +} + +// Buildmode options +type Cmd struct { + Status bool `yaml:"status" json:"status"` + Args []string `yaml:"args,omitempty" json:"args,omitempty"` } // Watcher struct defines the livereload's logic diff --git a/watcher/watcher.go b/watcher/watcher.go index b7e16ba..d3880c5 100644 --- a/watcher/watcher.go +++ b/watcher/watcher.go @@ -3,19 +3,19 @@ package watcher import ( "errors" "fmt" + "github.com/fsnotify/fsnotify" + "github.com/tockins/realize/style" "log" "math/big" "os" "os/signal" "path/filepath" + "reflect" "strconv" "strings" "sync" "syscall" "time" - - "github.com/fsnotify/fsnotify" - "github.com/tockins/realize/style" ) var msg string @@ -67,7 +67,7 @@ func (p *Project) watchByPolling() { file := changed[:i] + ext path := filepath.Dir(changed[:i]) if changed[:i] != "" && inArray(ext, p.Watcher.Exts) { - if p.Run { + if p.Cmds.Run { close(channel) channel = make(chan bool) } @@ -78,9 +78,10 @@ func (p *Project) watchByPolling() { p.print("log", out, msg, "") p.cmd("change") - p.fmt(file) - p.test(path) - p.generate(path) + p.tool(file, p.tools.Fmt) + p.tool(path, p.tools.Vet) + p.tool(path, p.tools.Test) + p.tool(path, p.tools.Generate) go p.routines(channel, &wr) } return nil @@ -143,7 +144,7 @@ func (p *Project) watchByNotify() { file := event.Name[:i] + ext path := filepath.Dir(event.Name[:i]) if event.Name[:i] != "" && inArray(ext, p.Watcher.Exts) { - if p.Run { + if p.Cmds.Run { close(channel) channel = make(chan bool) } @@ -154,9 +155,10 @@ func (p *Project) watchByNotify() { p.print("log", out, msg, "") p.cmd("change") - p.fmt(file) - p.test(path) - p.generate(path) + p.tool(file, p.tools.Fmt) + p.tool(path, p.tools.Vet) + p.tool(path, p.tools.Test) + p.tool(path, p.tools.Generate) go p.routines(channel, &wr) } } @@ -186,11 +188,12 @@ func (p *Project) watch(watcher watcher) error { } if inArray(filepath.Ext(path), p.Watcher.Exts) { files++ - p.fmt(path) + p.tool(path, p.tools.Fmt) } else { folders++ - p.generate(path) - p.test(path) + p.tool(path, p.tools.Vet) + p.tool(path, p.tools.Test) + p.tool(path, p.tools.Generate) } } } @@ -222,7 +225,7 @@ func (p *Project) watch(watcher watcher) error { // Install calls an implementation of "go install" func (p *Project) install() error { - if p.Bin { + if p.Cmds.Bin.Status { start := time.Now() log.Println(p.pname(p.Name, 1), ":", "Installing..") stream, err := p.goInstall() @@ -242,7 +245,7 @@ func (p *Project) install() error { // Install calls an implementation of "go run" func (p *Project) run(channel chan bool, wr *sync.WaitGroup) { - if p.Run { + if p.Cmds.Run { start := time.Now() runner := make(chan bool, 1) log.Println(p.pname(p.Name, 1), ":", "Running..") @@ -261,7 +264,7 @@ func (p *Project) run(channel chan bool, wr *sync.WaitGroup) { // Build calls an implementation of the "go build" func (p *Project) build() error { - if p.Build { + if p.Cmds.Build.Status { start := time.Now() log.Println(p.pname(p.Name, 1), ":", "Building..") stream, err := p.goBuild() @@ -279,40 +282,17 @@ func (p *Project) build() error { return nil } -// Fmt calls an implementation of the "go fmt" -func (p *Project) fmt(path string) error { - if p.Fmt && strings.HasSuffix(path, ".go") { - if stream, err := p.goTools(p.base, "gofmt", "-s", "-w", "-e", path); err != nil { - msg = fmt.Sprintln(p.pname(p.Name, 2), ":", style.Red.Bold("Go Fmt"), style.Red.Regular("there are some errors in"), ":", style.Magenta.Bold(path)) - out = BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: "Go Fmt", Stream: stream} - p.print("error", out, msg, stream) - return err - } - } - return nil -} - -// Generate calls an implementation of the "go generate" -func (p *Project) generate(path string) error { - if p.Generate { - if stream, err := p.goTools(path, "go", "generate"); err != nil { - msg = fmt.Sprintln(p.pname(p.Name, 2), ":", style.Red.Bold("Go Generate"), style.Red.Regular("there are some errors in"), ":", style.Magenta.Bold(path)) - out = BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: "Go Generate", Stream: stream} - p.print("error", out, msg, stream) - return err - } - } - return nil -} - -// Test calls an implementation of the "go test" -func (p *Project) test(path string) error { - if p.Test { - if stream, err := p.goTools(path, "go", "test"); err != nil { - msg = fmt.Sprintln(p.pname(p.Name, 2), ":", style.Red.Bold("Go Test"), style.Red.Regular("there are some errors in "), ":", style.Magenta.Bold(path)) - out = BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: "Go Test", Stream: stream} - p.print("error", out, msg, stream) - return err +func (p *Project) tool(path string, tool tool) error { + if tool.status != nil { + v := reflect.ValueOf(tool.status).Elem() + if v.Interface().(bool) && strings.HasSuffix(path, ".go") { + options := append(tool.options, path) + if stream, err := p.goTools(p.base, tool.cmd, options...); err != nil { + msg = fmt.Sprintln(p.pname(p.Name, 2), ":", style.Red.Bold(tool.name), style.Red.Regular("there are some errors in"), ":", style.Magenta.Bold(path)) + out = BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: tool.name, Stream: stream} + p.print("error", out, msg, stream) + return err + } } } return nil