From a18fb33cd57755fc50eb3d0153ebf4be52432981 Mon Sep 17 00:00:00 2001 From: asoseil Date: Sun, 12 Nov 2017 22:42:21 +0100 Subject: [PATCH] bug fix --- cmd.go | 14 ++++----- exec.go | 4 +-- notify.go | 4 +-- realize.go | 6 ++-- server.go | 10 +++---- settings.go | 2 +- watcher.go | 83 +++++++++++++++++++++++++++-------------------------- 7 files changed, 63 insertions(+), 60 deletions(-) diff --git a/cmd.go b/cmd.go index 3fd1f4b..6dfa95c 100644 --- a/cmd.go +++ b/cmd.go @@ -9,9 +9,9 @@ import ( // Tool options customizable, should be moved in Cmd type tool struct { - dir, status bool - name, err string - cmd, options []string + name, err string + cmd, options []string + dir, status bool } // Cmds list of go commands @@ -29,11 +29,11 @@ type Cmds struct { // Cmd single command fields and options type Cmd struct { - Status bool `yaml:"status,omitempty" json:"status,omitempty"` Method string `yaml:"method,omitempty" json:"method,omitempty"` Args []string `yaml:"args,omitempty" json:"args,omitempty"` - method []string + Status bool `yaml:"status,omitempty" json:"status,omitempty"` tool bool + method []string name, startTxt, endTxt string } @@ -53,7 +53,7 @@ func (r *realize) clean() error { } // Add a new project -func (r *realize) add(p *cli.Context) (err error) { +func (r *realize) add(p *cli.Context) (err error) { var path string // #118 get relative and if not exist try to get abs if _, err = os.Stat(p.String("path")); os.IsNotExist(err) { @@ -62,7 +62,7 @@ func (r *realize) add(p *cli.Context) (err error) { if err != nil { return err } - }else{ + } else { path = filepath.Clean(p.String("path")) } diff --git a/exec.go b/exec.go index bfdff8d..3b5e6e5 100644 --- a/exec.go +++ b/exec.go @@ -206,7 +206,7 @@ func (p *Project) goTool(wg *sync.WaitGroup, stop <-chan bool, result chan<- too case <-stop: // Stop running command cmd.Process.Kill() - break + return case err := <-done: // Command completed if err != nil { @@ -214,7 +214,7 @@ func (p *Project) goTool(wg *sync.WaitGroup, stop <-chan bool, result chan<- too // send command result result <- tool } - break + return } } diff --git a/notify.go b/notify.go index cd30b16..47cb785 100644 --- a/notify.go +++ b/notify.go @@ -107,9 +107,8 @@ func (w *fsNotifyWatcher) Walk(path string, init bool) string { // All watches are stopped, removed, and the poller cannot be added to func (w *filePoller) Close() error { w.mu.Lock() - defer w.mu.Unlock() - if w.closed { + w.mu.Unlock() return nil } @@ -118,6 +117,7 @@ func (w *filePoller) Close() error { w.remove(name) delete(w.watches, name) } + w.mu.Unlock() return nil } diff --git a/realize.go b/realize.go index 604062e..7473e65 100644 --- a/realize.go +++ b/realize.go @@ -35,8 +35,8 @@ type realize struct { // Cli commands func main() { app := &cli.App{ - Name: "Realize", - Version: version, + Name: "Realize", + Version: version, Description: "Go build system with file watchers, output streams and live reload. Run, build and watch file changes with custom paths", Commands: []*cli.Command{ { @@ -162,7 +162,7 @@ func main() { if err != nil { return d.Err() } - r.Settings.FileLimit = int8(val) + r.Settings.FileLimit = int32(val) return nil }, }, diff --git a/server.go b/server.go index f5c6d29..4f6d535 100644 --- a/server.go +++ b/server.go @@ -26,16 +26,15 @@ type Server struct { parent *realize Status bool `yaml:"status" json:"status"` Open bool `yaml:"open" json:"open"` - Host string `yaml:"host" json:"host"` Port int `yaml:"port" json:"port"` + Host string `yaml:"host" json:"host"` } // Websocket projects -func (s *Server) projects(c echo.Context) error { +func (s *Server) projects(c echo.Context) (err error) { websocket.Handler(func(ws *websocket.Conn) { - defer ws.Close() msg, _ := json.Marshal(s.parent) - err := websocket.Message.Send(ws, string(msg)) + err = websocket.Message.Send(ws, string(msg)) go func() { for { select { @@ -51,7 +50,7 @@ func (s *Server) projects(c echo.Context) error { for { // Read text := "" - err := websocket.Message.Receive(ws, &text) + err = websocket.Message.Receive(ws, &text) if err != nil { break } else { @@ -62,6 +61,7 @@ func (s *Server) projects(c echo.Context) error { } } } + ws.Close() }).ServeHTTP(c.Response(), c.Request()) return nil } diff --git a/settings.go b/settings.go index 7dd928e..e941874 100644 --- a/settings.go +++ b/settings.go @@ -32,8 +32,8 @@ const ( type Settings struct { file string Files `yaml:"files,omitempty" json:"files,omitempty"` - FileLimit int8 `yaml:"flimit,omitempty" json:"flimit,omitempty"` Legacy Legacy `yaml:"legacy" json:"legacy"` + FileLimit int32 `yaml:"flimit,omitempty" json:"flimit,omitempty"` Recovery bool `yaml:"recovery,omitempty" json:"recovery,omitempty"` } diff --git a/watcher.go b/watcher.go index cdd3897..c26ead1 100644 --- a/watcher.go +++ b/watcher.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "github.com/fsnotify/fsnotify" "log" "math/big" "os" @@ -12,9 +13,6 @@ import ( "sync" "syscall" "time" - - "github.com/fsnotify/fsnotify" - "reflect" ) var ( @@ -55,12 +53,12 @@ type Project struct { parent *realize watcher FileWatcher init bool + Settings `yaml:"-" json:"-"` files, folders int64 name, lastFile string tools []tool paths []string lastTime time.Time - Settings `yaml:"-" json:"-"` Name string `yaml:"name" json:"name"` Path string `yaml:"path" json:"path"` Environment map[string]string `yaml:"environment,omitempty" json:"environment,omitempty"` @@ -350,10 +348,12 @@ func (p *Project) tool(stop <-chan bool, path string) error { result := make(chan tool) go func() { var wg sync.WaitGroup - wg.Add(len(p.tools)) for _, element := range p.tools { // no need a sequence, these commands can be asynchronous - go p.goTool(&wg, stop, result, path, element) + if element.status { + wg.Add(1) + go p.goTool(&wg, stop, result, path, element) + } } wg.Wait() close(done) @@ -466,6 +466,7 @@ func (p *Project) stamp(t string, o BufferOut, msg string, stream string) { // Routines launches the toolchain run, build, install func (p *Project) routines(stop <-chan bool, watcher FileWatcher, path string) { var done bool + var install, build error go func() { for { select { @@ -475,43 +476,45 @@ func (p *Project) routines(stop <-chan bool, watcher FileWatcher, path string) { } } }() - invoke(done,p.cmd,stop,"before",false) - invoke(done,p.tool,stop,path) - // prevent init error on walk - p.init = true + if !done { + // before command + p.cmd(stop, "before", false) + } + if !done { + // Go supported tools + p.tool(stop, path) + // Prevent fake events on polling startup + p.init = true + } // prevent errors using realize without config with only run flag if p.Cmds.Run && !p.Cmds.Install.Status && !p.Cmds.Build.Status { p.Cmds.Install.Status = true } - invoke(done,p.compile,stop,p.Cmds.Install) - invoke(done,p.compile,stop,p.Cmds.Build) - if !done && p.Cmds.Run { - start := time.Now() - runner := make(chan bool, 1) - go func() { - log.Println(p.pname(p.Name, 1), ":", "Running..") - p.goRun(stop, runner) - }() - select { - case <-runner: - msg = fmt.Sprintln(p.pname(p.Name, 5), ":", green.regular("Started"), "in", magenta.regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s")) - out = BufferOut{Time: time.Now(), Text: "Started in " + big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3) + " s"} - p.stamp("log", out, msg, "") - case <-stop: - return - } - } - invoke(done,p.cmd,stop,"after",false) -} - -// Invoke is used to exec func from routines and check done -func invoke(done bool, fn interface{}, args ...interface{}) { if !done { - v := reflect.ValueOf(fn) - rargs := make([]reflect.Value, len(args)) - for i, a := range args { - rargs[i] = reflect.ValueOf(a) - } - v.Call(rargs) + install = p.compile(stop, p.Cmds.Install) } -} \ No newline at end of file + if !done { + build = p.compile(stop, p.Cmds.Build) + } + if !done && (install == nil && build == nil) { + if p.Cmds.Run { + start := time.Now() + runner := make(chan bool, 1) + go func() { + log.Println(p.pname(p.Name, 1), ":", "Running..") + p.goRun(stop, runner) + }() + select { + case <-runner: + msg = fmt.Sprintln(p.pname(p.Name, 5), ":", green.regular("Started"), "in", magenta.regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s")) + out = BufferOut{Time: time.Now(), Text: "Started in " + big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3) + " s"} + p.stamp("log", out, msg, "") + case <-stop: + return + } + } + } + if !done { + p.cmd(stop, "after", false) + } +}