From d27765064679f2c08bd54d7e5d1b08824fb6c7c8 Mon Sep 17 00:00:00 2001 From: alessio Date: Wed, 17 Aug 2016 16:56:06 +0200 Subject: [PATCH] v1.0 beta --- README.md | 47 ++++++++++++++++++++++++--- realize/project.go | 35 ++++++++++++-------- realize/watcher.go | 80 ++++++++++++++++++++++++++-------------------- 3 files changed, 109 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index 562e0d2..4c8ce8d 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,44 @@ -# Realize +## Realize +######v1.0 Beta -### Overview Run, build and watch file changes with custom paths -### To do +#### Installation and usage + +- Run this for get/install it: + ``` + $ go get github.com/ghodss/yaml + ``` +- From the root of your project/projects: + ``` + realize start + ``` + Will create a realize.config.yaml file with a sample project. + + You can pass additional parameters for your first project, such as the project name, the main file name and the base path. + + ``` + realize start --name="Project Name" --main="main.go" --base="/" + ``` +- Add another project whenever you want + ``` + realize add --name="Project Name" --main="main.go" --base="/" + ``` +- Remove a project by his name + ``` + realize remove --name="Project Name" + ``` +- Lists all projects + ``` + realize list + ``` +- Build, Run and watch file changes. Realize will re-build and re-run your projects on each changes + ``` + realize run + ``` + + +#### To do - [x] Command start - default config file - [x] Command add - new project on the config file - [x] Command remove - remove project from the config file @@ -15,5 +50,7 @@ Run, build and watch file changes with custom paths - [x] Support for directories with duplicates names - [ ] Unit test - [ ] Documentation -- [ ] Support for server start/stop -- [x] Cli feedback \ No newline at end of file +- [x] Support for server start/stop +- [x] Cli feedback + + diff --git a/realize/project.go b/realize/project.go index d1a168a..394cdd2 100644 --- a/realize/project.go +++ b/realize/project.go @@ -8,10 +8,12 @@ import ( "bufio" "log" "sync" + "strings" ) type Project struct { reload time.Time + Base string Name string `yaml:"app_name,omitempty"` Path string `yaml:"app_path,omitempty"` Main string `yaml:"app_main,omitempty"` @@ -22,10 +24,9 @@ type Project struct { } func (p *Project) GoRun(channel chan bool, wr *sync.WaitGroup) error { - base, _ := os.Getwd() - build := exec.Command("go", "run", p.Main) - path := base + p.Path - build.Dir = path + name := strings.Split(p.Path, "/") + build := exec.Command(name[len(name)-1], os.Getenv("PATH")) + build.Dir = p.Base defer func() { if err := build.Process.Kill(); err != nil { log.Fatal("failed to stop: ", err) @@ -43,30 +44,36 @@ func (p *Project) GoRun(channel chan bool, wr *sync.WaitGroup) error { } in := bufio.NewScanner(stdout) - for in.Scan(){ + go func() { + for in.Scan() { + select { + default: + log.Println(p.Name + ":", in.Text()) + } + } + }() + + for{ select { - default: - log.Println(p.Name + ":", in.Text()) - case <- channel: + case <-channel: return nil } } + return nil } func (p *Project) GoBuild() error { var out bytes.Buffer - base, _ := os.Getwd() - path := base + p.Path // create bin dir - if _, err := os.Stat(path + "/bin"); err != nil { - if err = os.Mkdir(path + "/bin", 0777); err != nil { + if _, err := os.Stat(p.Base + "/bin"); err != nil { + if err = os.Mkdir(p.Base + "/bin", 0777); err != nil { return err } } - build := exec.Command("go", "build", path + "/" + p.Main) - build.Dir = path + "/bin" + build := exec.Command("go", "build", p.Base + p.Main) + build.Dir = p.Base + "/bin" build.Stdout = &out if err := build.Run(); err != nil { return err diff --git a/realize/watcher.go b/realize/watcher.go index f33e854..1a60d05 100644 --- a/realize/watcher.go +++ b/realize/watcher.go @@ -5,8 +5,8 @@ import ( "fmt" "path/filepath" "os" - "log" "strings" + "log" "time" "sync" ) @@ -26,7 +26,7 @@ func (h *Config) Watch() error { // loop projects wg.Add(len(h.Projects)) for k := range h.Projects { - _, h.Projects[k].Path = slash(h.Projects[k].Path) + h.Projects[k].Path = slash(h.Projects[k].Path) go h.Projects[k].Watching() } wg.Wait() @@ -38,17 +38,20 @@ func (h *Config) Watch() error { func (p *Project) Watching() { - channel := make(chan bool,1) var wr sync.WaitGroup var watcher *fsnotify.Watcher - watcher, _ = fsnotify.NewWatcher() - defer func() { - watcher.Close() - wg.Done() - }() + watcher, err := fsnotify.NewWatcher() + if(err != nil){ + Fail(p.Name + ": \t" + err.Error()) + } + channel := make(chan bool,1) + base, err := os.Getwd() + if(err != nil){ + Fail(p.Name + ": \t" + err.Error()) + } walk := func(path string, info os.FileInfo, err error) error { - if !ignore(path, p.Watcher.Ignore) { + if !p.ignore(path) { if (info.IsDir() && len(filepath.Ext(path)) == 0 && !strings.Contains(path, "/.")) || (inArray(filepath.Ext(path), p.Watcher.Exts)) { if p.Watcher.Preview { fmt.Println(p.Name + ": \t" + path) @@ -65,31 +68,34 @@ func (p *Project) Watching() { wr.Add(1) go p.build(); p.install(); p.run(channel, &wr); } + end := func(){ + watcher.Close() + wg.Done() + } + + defer end() + + p.Path = slash(p.Path) + p.Main = slash(p.Main) + p.Base = base + p.Path for _, dir := range p.Watcher.Paths { - base, _ := os.Getwd() // check main existence - if _, err := os.Stat(base + p.Path + dir + p.Main); err != nil { - Fail(p.Name + ": \t" + base + p.Path + dir + p.Main + " doesn't exist. Main is required") + dir = slash(dir) + if _, err := os.Stat(p.Base + dir + p.Main); err != nil { + Fail(p.Name + ": \t" + p.Base + dir + p.Main + " doesn't exist. Main is required") return } - base = base + p.Path - if check, _ := slash(dir); check != true && len(dir) >= 1 { - base = base + p.Path + dir - } + base = p.Base + dir if _, err := os.Stat(base); err == nil { if err := filepath.Walk(base, walk); err != nil { Fail(err.Error()) } - if check, _ := slash(dir); check == true && len(dir) <= 1 { - break - } } else { Fail(p.Name + ": \t" + base + " path doesn't exist") } } - routines() fmt.Println(red("\n Watching: '" + p.Name + "'\n")) @@ -158,6 +164,16 @@ func (p *Project) run(channel chan bool, wr *sync.WaitGroup) { return } +func (p *Project) ignore(str string) bool { + for _, v := range p.Watcher.Ignore { + v = slash(v) + if strings.Contains(str, p.Base + v) { + return true + } + } + return false +} + func inArray(str string, list []string) bool { for _, v := range list { if v == str { @@ -167,20 +183,16 @@ func inArray(str string, list []string) bool { return false } -func ignore(str string, list []string) bool { - base, _ := os.Getwd() - for _, v := range list { - _, v = slash(v) - if strings.Contains(str, base + v) { - return true +func slash(str string) string{ + if string(str[0]) != "/" { + str = "/"+str + } + if string(str[len(str)-1]) == "/"{ + if(string(str) == "/"){ + str = "" + }else { + str = str[0:len(str) - 2] } } - return false -} - -func slash(str string) (bool, string){ - if string(str[0]) == "/" { - return true, str - } - return false, "/"+str + return str } \ No newline at end of file