realize core moved in a separate dir
This commit is contained in:
parent
02b4e7bb79
commit
813f4303ed
136
cli_test.go
136
cli_test.go
|
@ -1,136 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (m *mockRealize) add() error{
|
|
||||||
if mockResponse != nil {
|
|
||||||
return mockResponse.(error)
|
|
||||||
}
|
|
||||||
m.Projects = append(m.Projects, Project{Name:"One"})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockRealize) setup() error{
|
|
||||||
if mockResponse != nil {
|
|
||||||
return mockResponse.(error)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockRealize) start() error{
|
|
||||||
if mockResponse != nil {
|
|
||||||
return mockResponse.(error)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockRealize) clean() error{
|
|
||||||
if mockResponse != nil {
|
|
||||||
return mockResponse.(error)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockRealize) remove() error{
|
|
||||||
if mockResponse != nil {
|
|
||||||
return mockResponse.(error)
|
|
||||||
}
|
|
||||||
m.Projects = []Project{}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAdd(t *testing.T) {
|
|
||||||
m := mockRealize{}
|
|
||||||
mockResponse = nil
|
|
||||||
if err := m.add(); err != nil{
|
|
||||||
t.Fatal("Unexpected error")
|
|
||||||
}
|
|
||||||
if len(m.Projects) <= 0{
|
|
||||||
t.Fatal("Unexpected error")
|
|
||||||
}
|
|
||||||
|
|
||||||
m = mockRealize{}
|
|
||||||
m.Projects = []Project{{Name:"Default"}}
|
|
||||||
mockResponse = nil
|
|
||||||
if err := m.add(); err != nil{
|
|
||||||
t.Fatal("Unexpected error")
|
|
||||||
}
|
|
||||||
if len(m.Projects) != 2{
|
|
||||||
t.Fatal("Unexpected error")
|
|
||||||
}
|
|
||||||
|
|
||||||
m = mockRealize{}
|
|
||||||
mockResponse = errors.New("error")
|
|
||||||
if err := m.clean(); err == nil{
|
|
||||||
t.Fatal("Expected error")
|
|
||||||
}
|
|
||||||
if len(m.Projects) != 0{
|
|
||||||
t.Fatal("Unexpected error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStart(t *testing.T) {
|
|
||||||
m := mockRealize{}
|
|
||||||
mockResponse = nil
|
|
||||||
if err := m.add(); err != nil{
|
|
||||||
t.Fatal("Unexpected error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetup(t *testing.T) {
|
|
||||||
m := mockRealize{}
|
|
||||||
mockResponse = nil
|
|
||||||
if err := m.setup(); err != nil{
|
|
||||||
t.Fatal("Unexpected error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClean(t *testing.T) {
|
|
||||||
m := mockRealize{}
|
|
||||||
mockResponse = nil
|
|
||||||
if err := m.clean(); err != nil{
|
|
||||||
t.Fatal("Unexpected error")
|
|
||||||
}
|
|
||||||
mockResponse = errors.New("error")
|
|
||||||
if err := m.clean(); err == nil{
|
|
||||||
t.Fatal("Expected error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRemove(t *testing.T) {
|
|
||||||
m := mockRealize{}
|
|
||||||
mockResponse = nil
|
|
||||||
if err := m.remove(); err != nil{
|
|
||||||
t.Fatal("Unexpected error")
|
|
||||||
}
|
|
||||||
|
|
||||||
m = mockRealize{}
|
|
||||||
mockResponse = nil
|
|
||||||
m.Projects = []Project{{Name:"Default"},{Name:"Default"}}
|
|
||||||
if err := m.remove(); err != nil{
|
|
||||||
t.Fatal("Unexpected error")
|
|
||||||
}
|
|
||||||
if len(m.Projects) != 0{
|
|
||||||
t.Fatal("Unexpected error")
|
|
||||||
}
|
|
||||||
|
|
||||||
mockResponse = errors.New("error")
|
|
||||||
if err := m.clean(); err == nil{
|
|
||||||
t.Fatal("Expected error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVersion(t *testing.T) {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
log.SetOutput(&buf)
|
|
||||||
r.version()
|
|
||||||
if !strings.Contains(buf.String(), RVersion) {
|
|
||||||
t.Fatal("Version expted", RVersion)
|
|
||||||
}
|
|
||||||
}
|
|
1211
realize.go
1211
realize.go
File diff suppressed because it is too large
Load Diff
|
@ -18,7 +18,7 @@
|
||||||
// assets/index.html
|
// assets/index.html
|
||||||
// DO NOT EDIT!
|
// DO NOT EDIT!
|
||||||
|
|
||||||
package main
|
package realize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
|
@ -0,0 +1,81 @@
|
||||||
|
package realize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
"fmt"
|
||||||
|
"go/build"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
RPrefix = "realize"
|
||||||
|
RVersion = "2.0"
|
||||||
|
RExt = ".yaml"
|
||||||
|
RFile = RPrefix + RExt
|
||||||
|
RDir = "." + RPrefix
|
||||||
|
RExtWin = ".exe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Realize struct {
|
||||||
|
Settings Settings `yaml:"settings" json:"settings"`
|
||||||
|
Server Server `yaml:"server" json:"server"`
|
||||||
|
Schema `yaml:",inline"`
|
||||||
|
sync chan string
|
||||||
|
exit chan os.Signal
|
||||||
|
}
|
||||||
|
LogWriter struct{}
|
||||||
|
)
|
||||||
|
|
||||||
|
// init check
|
||||||
|
func init() {
|
||||||
|
// custom log
|
||||||
|
log.SetFlags(0)
|
||||||
|
log.SetOutput(LogWriter{})
|
||||||
|
if build.Default.GOPATH == "" {
|
||||||
|
log.Fatal("$GOPATH isn't set properly")
|
||||||
|
}
|
||||||
|
if err := os.Setenv("GOBIN", filepath.Join(build.Default.GOPATH, "bin")); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop realize workflow
|
||||||
|
func (r *Realize) Stop() {
|
||||||
|
close(r.exit)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run realize workflow
|
||||||
|
func (r *Realize) Start() {
|
||||||
|
r.exit = make(chan os.Signal, 2)
|
||||||
|
signal.Notify(r.exit, os.Interrupt, syscall.SIGTERM)
|
||||||
|
for k := range r.Schema.Projects {
|
||||||
|
r.Schema.Projects[k].parent = r
|
||||||
|
r.Schema.Projects[k].Setup()
|
||||||
|
go r.Schema.Projects[k].Watch(r.exit)
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-r.exit:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prefix a given string with tool name
|
||||||
|
func (r *Realize) Prefix(input string) string {
|
||||||
|
if len(input) > 0 {
|
||||||
|
return fmt.Sprint(Yellow.Bold("["), strings.ToUpper(RPrefix), Yellow.Bold("]"), " : ", input)
|
||||||
|
}
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rewrite the layout of the log timestamp
|
||||||
|
func (w LogWriter) Write(bytes []byte) (int, error) {
|
||||||
|
return fmt.Fprint(Output, Yellow.Regular("["), time.Now().Format("15:04:05"), Yellow.Regular("]"), string(bytes))
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package realize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockRealize struct {
|
||||||
|
Settings Settings `yaml:"settings" json:"settings"`
|
||||||
|
Server Server `yaml:"server" json:"server"`
|
||||||
|
Schema `yaml:",inline"`
|
||||||
|
sync chan string
|
||||||
|
exit chan os.Signal
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRealize_Stop(t *testing.T) {
|
||||||
|
m := mockRealize{}
|
||||||
|
m.exit = make(chan os.Signal, 2)
|
||||||
|
close(m.exit)
|
||||||
|
_, ok := <-m.exit
|
||||||
|
if !ok {
|
||||||
|
t.Error("Unexpected error", "channel should be closed")
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package realize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
|
@ -0,0 +1 @@
|
||||||
|
package realize
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package realize
|
||||||
|
|
||||||
// this code is imported from moby, unfortunately i can't import it directly as dependencies from its repo,
|
// this code is imported from moby, unfortunately i can't import it directly as dependencies from its repo,
|
||||||
// cause there was a problem between moby vendor and fsnotify
|
// cause there was a problem between moby vendor and fsnotify
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package realize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package realize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
@ -75,6 +75,10 @@ type BufferOut struct {
|
||||||
Errors []string `json:"errors"`
|
Errors []string `json:"errors"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Reload interface{
|
||||||
|
Restart(FileWatcher,string,<-chan bool)
|
||||||
|
}
|
||||||
|
|
||||||
// Setup a project
|
// Setup a project
|
||||||
func (p *Project) Setup() {
|
func (p *Project) Setup() {
|
||||||
// get base path
|
// get base path
|
||||||
|
@ -113,11 +117,11 @@ func (p *Project) Watch(exit chan os.Signal) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// start message
|
// start message
|
||||||
msg = fmt.Sprintln(p.pname(p.Name, 1), ":", blue.bold("Watching"), magenta.bold(p.files), "file/s", magenta.bold(p.folders), "folder/s")
|
msg = fmt.Sprintln(p.pname(p.Name, 1), ":", Blue.Bold("Watching"), Magenta.Bold(p.files), "file/s", Magenta.Bold(p.folders), "folder/s")
|
||||||
out = BufferOut{Time: time.Now(), Text: "Watching " + strconv.FormatInt(p.files, 10) + " files/s " + strconv.FormatInt(p.folders, 10) + " folder/s"}
|
out = BufferOut{Time: time.Now(), Text: "Watching " + strconv.FormatInt(p.files, 10) + " files/s " + strconv.FormatInt(p.folders, 10) + " folder/s"}
|
||||||
p.stamp("log", out, msg, "")
|
p.stamp("log", out, msg, "")
|
||||||
// start watcher
|
// start watcher
|
||||||
go p.Reload(p.watcher, "", stop)
|
go p.Restart(p.watcher, "", stop)
|
||||||
L:
|
L:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
@ -131,7 +135,7 @@ L:
|
||||||
ext = "DIR"
|
ext = "DIR"
|
||||||
}
|
}
|
||||||
// change message
|
// change message
|
||||||
msg = fmt.Sprintln(p.pname(p.Name, 4), ":", magenta.bold(strings.ToUpper(ext)), "changed", magenta.bold(event.Name))
|
msg = fmt.Sprintln(p.pname(p.Name, 4), ":", Magenta.Bold(strings.ToUpper(ext)), "changed", Magenta.Bold(event.Name))
|
||||||
out = BufferOut{Time: time.Now(), Text: ext + " changed " + event.Name}
|
out = BufferOut{Time: time.Now(), Text: ext + " changed " + event.Name}
|
||||||
// switch event type
|
// switch event type
|
||||||
switch event.Op {
|
switch event.Op {
|
||||||
|
@ -142,7 +146,7 @@ L:
|
||||||
close(stop)
|
close(stop)
|
||||||
stop = make(chan bool)
|
stop = make(chan bool)
|
||||||
p.stamp("log", out, msg, "")
|
p.stamp("log", out, msg, "")
|
||||||
go p.Reload(p.watcher, "", stop)
|
go p.Restart(p.watcher, "", stop)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
file, err := os.Stat(event.Name)
|
file, err := os.Stat(event.Name)
|
||||||
|
@ -160,7 +164,7 @@ L:
|
||||||
stop = make(chan bool)
|
stop = make(chan bool)
|
||||||
// stop and start again
|
// stop and start again
|
||||||
p.stamp("log", out, msg, "")
|
p.stamp("log", out, msg, "")
|
||||||
go p.Reload(p.watcher, event.Name, stop)
|
go p.Restart(p.watcher, event.Name, stop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.lastTime = time.Now().Truncate(time.Second)
|
p.lastTime = time.Now().Truncate(time.Second)
|
||||||
|
@ -178,7 +182,7 @@ L:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reload launches the toolchain run, build, install
|
// Reload launches the toolchain run, build, install
|
||||||
func (p *Project) Reload(watcher FileWatcher, path string, stop <-chan bool) {
|
func (p *Project) Restart(watcher FileWatcher, path string, stop <-chan bool) {
|
||||||
var done bool
|
var done bool
|
||||||
var install, build Response
|
var install, build Response
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -210,7 +214,7 @@ func (p *Project) Reload(watcher FileWatcher, path string, stop <-chan bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if p.Tools.Install.Status {
|
if p.Tools.Install.Status {
|
||||||
msg = fmt.Sprintln(p.pname(p.Name, 1), ":", green.regular(p.Tools.Install.name), "started")
|
msg = fmt.Sprintln(p.pname(p.Name, 1), ":", Green.Regular(p.Tools.Install.name), "started")
|
||||||
out = BufferOut{Time: time.Now(), Text: p.Tools.Install.name + " started"}
|
out = BufferOut{Time: time.Now(), Text: p.Tools.Install.name + " started"}
|
||||||
p.stamp("log", out, msg, "")
|
p.stamp("log", out, msg, "")
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
@ -221,7 +225,7 @@ func (p *Project) Reload(watcher FileWatcher, path string, stop <-chan bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if p.Tools.Build.Status {
|
if p.Tools.Build.Status {
|
||||||
msg = fmt.Sprintln(p.pname(p.Name, 1), ":", green.regular(p.Tools.Build.name), "started")
|
msg = fmt.Sprintln(p.pname(p.Name, 1), ":", Green.Regular(p.Tools.Build.name), "started")
|
||||||
out = BufferOut{Time: time.Now(), Text: p.Tools.Build.name + " started"}
|
out = BufferOut{Time: time.Now(), Text: p.Tools.Build.name + " started"}
|
||||||
p.stamp("log", out, msg, "")
|
p.stamp("log", out, msg, "")
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
@ -241,12 +245,12 @@ func (p *Project) Reload(watcher FileWatcher, path string, stop <-chan bool) {
|
||||||
return
|
return
|
||||||
case r := <-result:
|
case r := <-result:
|
||||||
if r.Err != nil {
|
if r.Err != nil {
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", red.regular(r.Err))
|
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", Red.Regular(r.Err))
|
||||||
out := BufferOut{Time: time.Now(), Text: r.Err.Error(), Type: "Go Run"}
|
out := BufferOut{Time: time.Now(), Text: r.Err.Error(), Type: "Go Run"}
|
||||||
p.stamp("error", out, msg, "")
|
p.stamp("error", out, msg, "")
|
||||||
}
|
}
|
||||||
if r.Out != "" {
|
if r.Out != "" {
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 3), ":", blue.regular(r.Out))
|
msg := fmt.Sprintln(p.pname(p.Name, 3), ":", Blue.Regular(r.Out))
|
||||||
out := BufferOut{Time: time.Now(), Text: r.Out, Type: "Go Run"}
|
out := BufferOut{Time: time.Now(), Text: r.Out, Type: "Go Run"}
|
||||||
p.stamp("out", out, msg, "")
|
p.stamp("out", out, msg, "")
|
||||||
}
|
}
|
||||||
|
@ -258,7 +262,7 @@ func (p *Project) Reload(watcher FileWatcher, path string, stop <-chan bool) {
|
||||||
start = time.Now()
|
start = time.Now()
|
||||||
err := p.Run(p.Path, result, stop)
|
err := p.Run(p.Path, result, stop)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", red.regular(err))
|
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", Red.Regular(err))
|
||||||
out := BufferOut{Time: time.Now(), Text: err.Error(), Type: "Go Run"}
|
out := BufferOut{Time: time.Now(), Text: err.Error(), Type: "Go Run"}
|
||||||
p.stamp("error", out, msg, "")
|
p.stamp("error", out, msg, "")
|
||||||
}
|
}
|
||||||
|
@ -305,7 +309,7 @@ func (p *Project) Run(path string, stream chan Response, stop <-chan bool) (err
|
||||||
gobin := os.Getenv("GOBIN")
|
gobin := os.Getenv("GOBIN")
|
||||||
dirPath := filepath.Base(path)
|
dirPath := filepath.Base(path)
|
||||||
if path == "." {
|
if path == "." {
|
||||||
dirPath = filepath.Base(wdir())
|
dirPath = filepath.Base(Wdir())
|
||||||
}
|
}
|
||||||
path = filepath.Join(gobin, dirPath)
|
path = filepath.Join(gobin, dirPath)
|
||||||
if _, err := os.Stat(path); err == nil {
|
if _, err := os.Stat(path); err == nil {
|
||||||
|
@ -363,7 +367,7 @@ func (p *Project) Run(path string, stream chan Response, stop <-chan bool) (err
|
||||||
|
|
||||||
// Error occurred
|
// Error occurred
|
||||||
func (p *Project) err(err error) {
|
func (p *Project) err(err error) {
|
||||||
msg = fmt.Sprintln(p.pname(p.Name, 2), ":", red.regular(err.Error()))
|
msg = fmt.Sprintln(p.pname(p.Name, 2), ":", Red.Regular(err.Error()))
|
||||||
out = BufferOut{Time: time.Now(), Text: err.Error()}
|
out = BufferOut{Time: time.Now(), Text: err.Error()}
|
||||||
p.stamp("error", out, msg, "")
|
p.stamp("error", out, msg, "")
|
||||||
}
|
}
|
||||||
|
@ -372,19 +376,19 @@ func (p *Project) err(err error) {
|
||||||
func (p *Project) pname(name string, color int) string {
|
func (p *Project) pname(name string, color int) string {
|
||||||
switch color {
|
switch color {
|
||||||
case 1:
|
case 1:
|
||||||
name = yellow.regular("[") + strings.ToUpper(name) + yellow.regular("]")
|
name = Yellow.Regular("[") + strings.ToUpper(name) + Yellow.Regular("]")
|
||||||
break
|
break
|
||||||
case 2:
|
case 2:
|
||||||
name = yellow.regular("[") + red.bold(strings.ToUpper(name)) + yellow.regular("]")
|
name = Yellow.Regular("[") + Red.Bold(strings.ToUpper(name)) + Yellow.Regular("]")
|
||||||
break
|
break
|
||||||
case 3:
|
case 3:
|
||||||
name = yellow.regular("[") + blue.bold(strings.ToUpper(name)) + yellow.regular("]")
|
name = Yellow.Regular("[") + Blue.Bold(strings.ToUpper(name)) + Yellow.Regular("]")
|
||||||
break
|
break
|
||||||
case 4:
|
case 4:
|
||||||
name = yellow.regular("[") + magenta.bold(strings.ToUpper(name)) + yellow.regular("]")
|
name = Yellow.Regular("[") + Magenta.Bold(strings.ToUpper(name)) + Yellow.Regular("]")
|
||||||
break
|
break
|
||||||
case 5:
|
case 5:
|
||||||
name = yellow.regular("[") + green.bold(strings.ToUpper(name)) + yellow.regular("]")
|
name = Yellow.Regular("[") + Green.Bold(strings.ToUpper(name)) + Yellow.Regular("]")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return name
|
return name
|
||||||
|
@ -413,11 +417,11 @@ func (p *Project) tools(stop <-chan bool, path string) {
|
||||||
return
|
return
|
||||||
case r := <-result:
|
case r := <-result:
|
||||||
if r.Err != nil {
|
if r.Err != nil {
|
||||||
msg = fmt.Sprintln(p.pname(p.Name, 2), ":", red.bold(r.Name), red.regular("there are some errors in"), ":", magenta.bold(path))
|
msg = fmt.Sprintln(p.pname(p.Name, 2), ":", Red.Bold(r.Name), Red.Regular("there are some errors in"), ":", Magenta.Bold(path))
|
||||||
buff := BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: r.Name, Stream: r.Err.Error()}
|
buff := BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: r.Name, Stream: r.Err.Error()}
|
||||||
p.stamp("error", buff, msg, r.Err.Error())
|
p.stamp("error", buff, msg, r.Err.Error())
|
||||||
} else if r.Out != "" {
|
} else if r.Out != "" {
|
||||||
msg = fmt.Sprintln(p.pname(p.Name, 3), ":", red.bold(r.Name), red.regular("outputs"), ":", blue.bold(path))
|
msg = fmt.Sprintln(p.pname(p.Name, 3), ":", Red.Bold(r.Name), Red.Regular("outputs"), ":", Blue.Bold(path))
|
||||||
buff := BufferOut{Time: time.Now(), Text: "outputs", Path: path, Type: r.Name, Stream: r.Out}
|
buff := BufferOut{Time: time.Now(), Text: "outputs", Path: path, Type: r.Name, Stream: r.Out}
|
||||||
p.stamp("out", buff, msg, r.Out)
|
p.stamp("out", buff, msg, r.Out)
|
||||||
}
|
}
|
||||||
|
@ -446,12 +450,12 @@ func (p *Project) cmd(stop <-chan bool, flag string, global bool) {
|
||||||
case <-done:
|
case <-done:
|
||||||
return
|
return
|
||||||
case r := <-result:
|
case r := <-result:
|
||||||
msg = fmt.Sprintln(p.pname(p.Name, 5), ":", green.bold("Command"), green.bold("\"")+r.Name+green.bold("\""))
|
msg = fmt.Sprintln(p.pname(p.Name, 5), ":", Green.Bold("Command"), Green.Bold("\"")+r.Name+Green.Bold("\""))
|
||||||
out = BufferOut{Time: time.Now(), Text: r.Name, Type: flag}
|
out = BufferOut{Time: time.Now(), Text: r.Name, Type: flag}
|
||||||
if r.Err != nil {
|
if r.Err != nil {
|
||||||
p.stamp("error", out, msg, "")
|
p.stamp("error", out, msg, "")
|
||||||
out = BufferOut{Time: time.Now(), Text: r.Err.Error(), Type: flag}
|
out = BufferOut{Time: time.Now(), Text: r.Err.Error(), Type: flag}
|
||||||
p.stamp("error", out, "", fmt.Sprintln(red.regular(r.Err.Error())))
|
p.stamp("error", out, "", fmt.Sprintln(Red.Regular(r.Err.Error())))
|
||||||
}
|
}
|
||||||
if r.Out != "" {
|
if r.Out != "" {
|
||||||
out = BufferOut{Time: time.Now(), Text: r.Out, Type: flag}
|
out = BufferOut{Time: time.Now(), Text: r.Out, Type: flag}
|
||||||
|
@ -486,8 +490,8 @@ func (p *Project) walk(path string, info os.FileInfo, err error) error {
|
||||||
|
|
||||||
// Print on files, cli, ws
|
// Print on files, cli, ws
|
||||||
func (p *Project) stamp(t string, o BufferOut, msg string, stream string) {
|
func (p *Project) stamp(t string, o BufferOut, msg string, stream string) {
|
||||||
time := time.Now()
|
ctime := time.Now()
|
||||||
content := []string{time.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Text, "\r\n", stream}
|
content := []string{ctime.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Text, "\r\n", stream}
|
||||||
switch t {
|
switch t {
|
||||||
case "out":
|
case "out":
|
||||||
p.Buffer.StdOut = append(p.Buffer.StdOut, o)
|
p.Buffer.StdOut = append(p.Buffer.StdOut, o)
|
||||||
|
@ -518,18 +522,18 @@ func (p *Project) stamp(t string, o BufferOut, msg string, stream string) {
|
||||||
log.Print(msg)
|
log.Print(msg)
|
||||||
}
|
}
|
||||||
if stream != "" {
|
if stream != "" {
|
||||||
fmt.Fprint(output, stream)
|
fmt.Fprint(Output, stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print with time after
|
// Print with time after
|
||||||
func (r *Response) print(start time.Time, p *Project) {
|
func (r *Response) print(start time.Time, p *Project) {
|
||||||
if r.Err != nil {
|
if r.Err != nil {
|
||||||
msg = fmt.Sprintln(p.pname(p.Name, 2), ":", red.bold(r.Name), "\n", r.Err.Error())
|
msg = fmt.Sprintln(p.pname(p.Name, 2), ":", Red.Bold(r.Name), "\n", r.Err.Error())
|
||||||
out = BufferOut{Time: time.Now(), Text: r.Err.Error(), Type: r.Name, Stream: r.Out}
|
out = BufferOut{Time: time.Now(), Text: r.Err.Error(), Type: r.Name, Stream: r.Out}
|
||||||
p.stamp("error", out, msg, r.Out)
|
p.stamp("error", out, msg, r.Out)
|
||||||
} else {
|
} else {
|
||||||
msg = fmt.Sprintln(p.pname(p.Name, 5), ":", green.bold(r.Name), "completed in", magenta.regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s"))
|
msg = fmt.Sprintln(p.pname(p.Name, 5), ":", Green.Bold(r.Name), "completed in", Magenta.Regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s"))
|
||||||
out = BufferOut{Time: time.Now(), Text: r.Name + " in " + big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3) + " s"}
|
out = BufferOut{Time: time.Now(), Text: r.Name + " in " + big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3) + " s"}
|
||||||
p.stamp("log", out, msg, r.Out)
|
p.stamp("log", out, msg, r.Out)
|
||||||
}
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
package realize
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package realize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -37,7 +37,7 @@ func (s *Schema) Remove(name string) error {
|
||||||
func (s *Schema) New(c *cli.Context) Project {
|
func (s *Schema) New(c *cli.Context) Project {
|
||||||
name := filepath.Base(c.String("path"))
|
name := filepath.Base(c.String("path"))
|
||||||
if name == "." {
|
if name == "." {
|
||||||
name = filepath.Base(wdir())
|
name = filepath.Base(Wdir())
|
||||||
}
|
}
|
||||||
project := Project{
|
project := Project{
|
||||||
Name: name,
|
Name: name,
|
|
@ -0,0 +1 @@
|
||||||
|
package realize
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package realize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -20,7 +20,7 @@ const (
|
||||||
|
|
||||||
// Server settings
|
// Server settings
|
||||||
type Server struct {
|
type Server struct {
|
||||||
parent *Realize
|
Parent *Realize
|
||||||
Status bool `yaml:"status" json:"status"`
|
Status bool `yaml:"status" json:"status"`
|
||||||
Open bool `yaml:"open" json:"open"`
|
Open bool `yaml:"open" json:"open"`
|
||||||
Port int `yaml:"port" json:"port"`
|
Port int `yaml:"port" json:"port"`
|
||||||
|
@ -152,13 +152,13 @@ func (s *Server) Start() (err error) {
|
||||||
e.GET("/ws", s.projects)
|
e.GET("/ws", s.projects)
|
||||||
e.HideBanner = true
|
e.HideBanner = true
|
||||||
e.Debug = false
|
e.Debug = false
|
||||||
go e.Start(string(s.parent.Server.Host) + ":" + strconv.Itoa(s.parent.Server.Port))
|
go e.Start(string(s.Parent.Server.Host) + ":" + strconv.Itoa(s.Parent.Server.Port))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenURL in a new tab of default browser
|
// OpenURL in a new tab of default browser
|
||||||
func (s *Server) OpenURL() (io.Writer, error) {
|
func (s *Server) OpenURL() (io.Writer, error) {
|
||||||
url := "http://" + string(s.parent.Server.Host) + ":" + strconv.Itoa(s.parent.Server.Port)
|
url := "http://" + string(s.Parent.Server.Host) + ":" + strconv.Itoa(s.Parent.Server.Port)
|
||||||
stderr := bytes.Buffer{}
|
stderr := bytes.Buffer{}
|
||||||
cmd := map[string]string{
|
cmd := map[string]string{
|
||||||
"windows": "start",
|
"windows": "start",
|
|
@ -0,0 +1 @@
|
||||||
|
package realize
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package realize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
@ -130,7 +130,7 @@ func (s Settings) Stream(file string) ([]byte, error) {
|
||||||
func (s Settings) Fatal(err error, msg ...interface{}) {
|
func (s Settings) Fatal(err error, msg ...interface{}) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if len(msg) > 0 {
|
if len(msg) > 0 {
|
||||||
log.Fatalln(red.regular(msg...), err.Error())
|
log.Fatalln(Red.Regular(msg...), err.Error())
|
||||||
} else {
|
} else {
|
||||||
log.Fatalln(err.Error())
|
log.Fatalln(err.Error())
|
||||||
}
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
package realize
|
|
@ -1,6 +1,6 @@
|
||||||
// +build !windows
|
// +build !windows
|
||||||
|
|
||||||
package main
|
package realize
|
||||||
|
|
||||||
import "syscall"
|
import "syscall"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package main
|
package realize
|
||||||
|
|
||||||
// Flimit defines the max number of watched files
|
// Flimit defines the max number of watched files
|
||||||
func (s *Settings) Flimit() error {
|
func (s *Settings) Flimit() error {
|
|
@ -0,0 +1,27 @@
|
||||||
|
package realize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/fatih/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Output = color.Output
|
||||||
|
Red = colorBase(color.FgHiRed)
|
||||||
|
Blue = colorBase(color.FgHiBlue)
|
||||||
|
Green = colorBase(color.FgHiGreen)
|
||||||
|
Yellow = colorBase(color.FgHiYellow)
|
||||||
|
Magenta = colorBase(color.FgHiMagenta)
|
||||||
|
)
|
||||||
|
|
||||||
|
// ColorBase type
|
||||||
|
type colorBase color.Attribute
|
||||||
|
|
||||||
|
// Regular font with a color
|
||||||
|
func (c colorBase) Regular(a ...interface{}) string {
|
||||||
|
return color.New(color.Attribute(c)).Sprint(a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bold font with a color
|
||||||
|
func (c colorBase) Bold(a ...interface{}) string {
|
||||||
|
return color.New(color.Attribute(c), color.Bold).Sprint(a...)
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package realize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -13,7 +13,7 @@ func TestStyle_Regular(t *testing.T) {
|
||||||
for i, s := range strs {
|
for i, s := range strs {
|
||||||
input[i] = s
|
input[i] = s
|
||||||
}
|
}
|
||||||
result := red.regular(input)
|
result := Red.Regular(input)
|
||||||
c := color.New(color.FgHiRed).SprintFunc()
|
c := color.New(color.FgHiRed).SprintFunc()
|
||||||
expected := fmt.Sprint(c(input))
|
expected := fmt.Sprint(c(input))
|
||||||
if !bytes.Equal([]byte(result), []byte(expected)) {
|
if !bytes.Equal([]byte(result), []byte(expected)) {
|
||||||
|
@ -27,7 +27,7 @@ func TestStyle_Bold(t *testing.T) {
|
||||||
for i, s := range strs {
|
for i, s := range strs {
|
||||||
input[i] = s
|
input[i] = s
|
||||||
}
|
}
|
||||||
result := red.bold(input)
|
result := Red.Bold(input)
|
||||||
c := color.New(color.FgHiRed, color.Bold).SprintFunc()
|
c := color.New(color.FgHiRed, color.Bold).SprintFunc()
|
||||||
expected := fmt.Sprint(c(input))
|
expected := fmt.Sprint(c(input))
|
||||||
if !bytes.Equal([]byte(result), []byte(expected)) {
|
if !bytes.Equal([]byte(result), []byte(expected)) {
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package realize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
|
@ -0,0 +1 @@
|
||||||
|
package realize
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package realize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -73,7 +73,7 @@ func replace(a []string, b string) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wdir return current working directory
|
// Wdir return current working directory
|
||||||
func wdir() string {
|
func Wdir() string {
|
||||||
dir, err := os.Getwd()
|
dir, err := os.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err.Error())
|
log.Fatal(err.Error())
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package realize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
143
realize_test.go
143
realize_test.go
|
@ -1,13 +1,148 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "os"
|
import (
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
rc "github.com/tockins/realize/realize"
|
||||||
|
"github.com/go-siris/siris/core/errors"
|
||||||
|
"bytes"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
var mockResponse interface{}
|
var mockResponse interface{}
|
||||||
|
|
||||||
type mockRealize struct {
|
type mockRealize struct {
|
||||||
Settings Settings `yaml:"settings" json:"settings"`
|
Settings rc.Settings `yaml:"settings" json:"settings"`
|
||||||
Server Server `yaml:"server" json:"server"`
|
Server rc.Server `yaml:"server" json:"server"`
|
||||||
Schema `yaml:",inline"`
|
rc.Schema `yaml:",inline"`
|
||||||
sync chan string
|
sync chan string
|
||||||
exit chan os.Signal
|
exit chan os.Signal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *mockRealize) add() error{
|
||||||
|
if mockResponse != nil {
|
||||||
|
return mockResponse.(error)
|
||||||
|
}
|
||||||
|
m.Projects = append(m.Projects, rc.Project{Name:"One"})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockRealize) setup() error{
|
||||||
|
if mockResponse != nil {
|
||||||
|
return mockResponse.(error)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockRealize) start() error{
|
||||||
|
if mockResponse != nil {
|
||||||
|
return mockResponse.(error)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockRealize) clean() error{
|
||||||
|
if mockResponse != nil {
|
||||||
|
return mockResponse.(error)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockRealize) remove() error{
|
||||||
|
if mockResponse != nil {
|
||||||
|
return mockResponse.(error)
|
||||||
|
}
|
||||||
|
m.Projects = []rc.Project{}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRealize_add(t *testing.T) {
|
||||||
|
m := mockRealize{}
|
||||||
|
mockResponse = nil
|
||||||
|
if err := m.add(); err != nil{
|
||||||
|
t.Fatal("Unexpected error")
|
||||||
|
}
|
||||||
|
if len(m.Projects) <= 0{
|
||||||
|
t.Fatal("Unexpected error")
|
||||||
|
}
|
||||||
|
|
||||||
|
m = mockRealize{}
|
||||||
|
m.Projects = []rc.Project{{Name:"Default"}}
|
||||||
|
mockResponse = nil
|
||||||
|
if err := m.add(); err != nil{
|
||||||
|
t.Fatal("Unexpected error")
|
||||||
|
}
|
||||||
|
if len(m.Projects) != 2{
|
||||||
|
t.Fatal("Unexpected error")
|
||||||
|
}
|
||||||
|
|
||||||
|
m = mockRealize{}
|
||||||
|
mockResponse = errors.New("error")
|
||||||
|
if err := m.clean(); err == nil{
|
||||||
|
t.Fatal("Expected error")
|
||||||
|
}
|
||||||
|
if len(m.Projects) != 0{
|
||||||
|
t.Fatal("Unexpected error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRealize_start(t *testing.T) {
|
||||||
|
m := mockRealize{}
|
||||||
|
mockResponse = nil
|
||||||
|
if err := m.add(); err != nil{
|
||||||
|
t.Fatal("Unexpected error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRealize_setup(t *testing.T) {
|
||||||
|
m := mockRealize{}
|
||||||
|
mockResponse = nil
|
||||||
|
if err := m.setup(); err != nil{
|
||||||
|
t.Fatal("Unexpected error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRealize_clean(t *testing.T) {
|
||||||
|
m := mockRealize{}
|
||||||
|
mockResponse = nil
|
||||||
|
if err := m.clean(); err != nil{
|
||||||
|
t.Fatal("Unexpected error")
|
||||||
|
}
|
||||||
|
mockResponse = errors.New("error")
|
||||||
|
if err := m.clean(); err == nil{
|
||||||
|
t.Fatal("Expected error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRealize_remove(t *testing.T) {
|
||||||
|
m := mockRealize{}
|
||||||
|
mockResponse = nil
|
||||||
|
if err := m.remove(); err != nil{
|
||||||
|
t.Fatal("Unexpected error")
|
||||||
|
}
|
||||||
|
|
||||||
|
m = mockRealize{}
|
||||||
|
mockResponse = nil
|
||||||
|
m.Projects = []rc.Project{{Name:"Default"},{Name:"Default"}}
|
||||||
|
if err := m.remove(); err != nil{
|
||||||
|
t.Fatal("Unexpected error")
|
||||||
|
}
|
||||||
|
if len(m.Projects) != 0{
|
||||||
|
t.Fatal("Unexpected error")
|
||||||
|
}
|
||||||
|
|
||||||
|
mockResponse = errors.New("error")
|
||||||
|
if err := m.clean(); err == nil{
|
||||||
|
t.Fatal("Expected error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRealize_version(t *testing.T) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
log.SetOutput(&buf)
|
||||||
|
version()
|
||||||
|
if !strings.Contains(buf.String(), rc.RVersion) {
|
||||||
|
t.Fatal("Version expted", rc.RVersion)
|
||||||
|
}
|
||||||
|
}
|
27
style.go
27
style.go
|
@ -1,27 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/fatih/color"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
output = color.Output
|
|
||||||
red = colorBase(color.FgHiRed)
|
|
||||||
blue = colorBase(color.FgHiBlue)
|
|
||||||
green = colorBase(color.FgHiGreen)
|
|
||||||
yellow = colorBase(color.FgHiYellow)
|
|
||||||
magenta = colorBase(color.FgHiMagenta)
|
|
||||||
)
|
|
||||||
|
|
||||||
// ColorBase type
|
|
||||||
type colorBase color.Attribute
|
|
||||||
|
|
||||||
// Regular font with a color
|
|
||||||
func (c colorBase) regular(a ...interface{}) string {
|
|
||||||
return color.New(color.Attribute(c)).Sprint(a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bold font with a color
|
|
||||||
func (c colorBase) bold(a ...interface{}) string {
|
|
||||||
return color.New(color.Attribute(c), color.Bold).Sprint(a...)
|
|
||||||
}
|
|
Loading…
Reference in New Issue