v1.0 beta
This commit is contained in:
parent
12781ca855
commit
d277650646
47
README.md
47
README.md
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
for in.Scan(){
|
go func() {
|
||||||
|
for in.Scan() {
|
||||||
|
select {
|
||||||
|
default:
|
||||||
|
log.Println(p.Name + ":", in.Text())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for{
|
||||||
select {
|
select {
|
||||||
default:
|
case <-channel:
|
||||||
log.Println(p.Name + ":", in.Text())
|
|
||||||
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
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue