v1.0 beta

This commit is contained in:
alessio 2016-08-17 16:56:06 +02:00
parent 12781ca855
commit d277650646
3 changed files with 109 additions and 53 deletions

View File

@ -1,9 +1,44 @@
# Realize ## Realize
######v1.0 Beta
### Overview
Run, build and watch file changes with custom paths 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 start - default config file
- [x] Command add - new project on the config file - [x] Command add - new project on the config file
- [x] Command remove - remove project from 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 - [x] Support for directories with duplicates names
- [ ] Unit test - [ ] Unit test
- [ ] Documentation - [ ] Documentation
- [ ] Support for server start/stop - [x] Support for server start/stop
- [x] Cli feedback - [x] Cli feedback

View File

@ -8,10 +8,12 @@ import (
"bufio" "bufio"
"log" "log"
"sync" "sync"
"strings"
) )
type Project struct { type Project struct {
reload time.Time reload time.Time
Base string
Name string `yaml:"app_name,omitempty"` Name string `yaml:"app_name,omitempty"`
Path string `yaml:"app_path,omitempty"` Path string `yaml:"app_path,omitempty"`
Main string `yaml:"app_main,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 { func (p *Project) GoRun(channel chan bool, wr *sync.WaitGroup) error {
base, _ := os.Getwd() name := strings.Split(p.Path, "/")
build := exec.Command("go", "run", p.Main) build := exec.Command(name[len(name)-1], os.Getenv("PATH"))
path := base + p.Path build.Dir = p.Base
build.Dir = path
defer func() { defer func() {
if err := build.Process.Kill(); err != nil { if err := build.Process.Kill(); err != nil {
log.Fatal("failed to stop: ", err) 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) in := bufio.NewScanner(stdout)
go func() {
for in.Scan() { for in.Scan() {
select { select {
default: default:
log.Println(p.Name + ":", in.Text()) log.Println(p.Name + ":", in.Text())
}
}
}()
for{
select {
case <-channel: case <-channel:
return nil return nil
} }
} }
return nil return nil
} }
func (p *Project) GoBuild() error { func (p *Project) GoBuild() error {
var out bytes.Buffer var out bytes.Buffer
base, _ := os.Getwd()
path := base + p.Path
// create bin dir // create bin dir
if _, err := os.Stat(path + "/bin"); err != nil { if _, err := os.Stat(p.Base + "/bin"); err != nil {
if err = os.Mkdir(path + "/bin", 0777); err != nil { if err = os.Mkdir(p.Base + "/bin", 0777); err != nil {
return err return err
} }
} }
build := exec.Command("go", "build", path + "/" + p.Main) build := exec.Command("go", "build", p.Base + p.Main)
build.Dir = path + "/bin" build.Dir = p.Base + "/bin"
build.Stdout = &out build.Stdout = &out
if err := build.Run(); err != nil { if err := build.Run(); err != nil {
return err return err

View File

@ -5,8 +5,8 @@ import (
"fmt" "fmt"
"path/filepath" "path/filepath"
"os" "os"
"log"
"strings" "strings"
"log"
"time" "time"
"sync" "sync"
) )
@ -26,7 +26,7 @@ func (h *Config) Watch() error {
// loop projects // loop projects
wg.Add(len(h.Projects)) wg.Add(len(h.Projects))
for k := range 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() go h.Projects[k].Watching()
} }
wg.Wait() wg.Wait()
@ -38,17 +38,20 @@ func (h *Config) Watch() error {
func (p *Project) Watching() { func (p *Project) Watching() {
channel := make(chan bool,1)
var wr sync.WaitGroup var wr sync.WaitGroup
var watcher *fsnotify.Watcher var watcher *fsnotify.Watcher
watcher, _ = fsnotify.NewWatcher() watcher, err := fsnotify.NewWatcher()
defer func() { if(err != nil){
watcher.Close() Fail(p.Name + ": \t" + err.Error())
wg.Done() }
}() 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 { 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 (info.IsDir() && len(filepath.Ext(path)) == 0 && !strings.Contains(path, "/.")) || (inArray(filepath.Ext(path), p.Watcher.Exts)) {
if p.Watcher.Preview { if p.Watcher.Preview {
fmt.Println(p.Name + ": \t" + path) fmt.Println(p.Name + ": \t" + path)
@ -65,31 +68,34 @@ func (p *Project) Watching() {
wr.Add(1) wr.Add(1)
go p.build(); p.install(); p.run(channel, &wr); 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 { for _, dir := range p.Watcher.Paths {
base, _ := os.Getwd()
// check main existence // check main existence
if _, err := os.Stat(base + p.Path + dir + p.Main); err != nil { dir = slash(dir)
Fail(p.Name + ": \t" + base + p.Path + dir + p.Main + " doesn't exist. Main is required") 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 return
} }
base = base + p.Path base = p.Base + dir
if check, _ := slash(dir); check != true && len(dir) >= 1 {
base = base + p.Path + dir
}
if _, err := os.Stat(base); err == nil { if _, err := os.Stat(base); err == nil {
if err := filepath.Walk(base, walk); err != nil { if err := filepath.Walk(base, walk); err != nil {
Fail(err.Error()) Fail(err.Error())
} }
if check, _ := slash(dir); check == true && len(dir) <= 1 {
break
}
} else { } else {
Fail(p.Name + ": \t" + base + " path doesn't exist") Fail(p.Name + ": \t" + base + " path doesn't exist")
} }
} }
routines() routines()
fmt.Println(red("\n Watching: '" + p.Name + "'\n")) fmt.Println(red("\n Watching: '" + p.Name + "'\n"))
@ -158,6 +164,16 @@ func (p *Project) run(channel chan bool, wr *sync.WaitGroup) {
return 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 { func inArray(str string, list []string) bool {
for _, v := range list { for _, v := range list {
if v == str { if v == str {
@ -167,20 +183,16 @@ func inArray(str string, list []string) bool {
return false return false
} }
func ignore(str string, list []string) bool { func slash(str string) string{
base, _ := os.Getwd() if string(str[0]) != "/" {
for _, v := range list { str = "/"+str
_, v = slash(v) }
if strings.Contains(str, base + v) { if string(str[len(str)-1]) == "/"{
return true if(string(str) == "/"){
str = ""
}else {
str = str[0:len(str) - 2]
} }
} }
return false return str
}
func slash(str string) (bool, string){
if string(str[0]) == "/" {
return true, str
}
return false, "/"+str
} }