This commit is contained in:
asoseil 2017-11-12 22:42:21 +01:00
parent 989c898dbf
commit a18fb33cd5
7 changed files with 63 additions and 60 deletions

14
cmd.go
View File

@ -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"))
}

View File

@ -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
}
}

View File

@ -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
}

View File

@ -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
},
},

View File

@ -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
}

View File

@ -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"`
}

View File

@ -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)
}
}
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)
}
}