commit
e18815df46
@ -38,11 +38,11 @@ A Go build system with file watchers, output streams and live reload. Run, build
|
|||||||
$ realize add
|
$ realize add
|
||||||
```
|
```
|
||||||
|
|
||||||
It will create a realize.yaml file if it doesn't exist already and adds the working directory as the project.
|
It will create a realize.yaml file if it doesn't exist already and adds the working directory as project.
|
||||||
|
|
||||||
Otherwise if a config file already exists it adds the working project to the existing config file.
|
Otherwise if a config file already exists it adds the working project to the existing config file.
|
||||||
|
|
||||||
The add command supports the following custom parameters:
|
The Add command supports the following custom parameters:
|
||||||
|
|
||||||
```
|
```
|
||||||
--name="Project Name" -> Name, if not specified takes the working directory name
|
--name="Project Name" -> Name, if not specified takes the working directory name
|
||||||
|
17
realize.go
17
realize.go
@ -15,10 +15,11 @@ const (
|
|||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
description = "A Go build system with file watchers, output streams and live reload. Run, build and watch file changes with custom paths"
|
description = "A Go build system with file watchers, output streams and live reload. Run, build and watch file changes with custom paths"
|
||||||
config = "realize.yaml"
|
config = "realize.yaml"
|
||||||
output = "outputs.log"
|
streams = "streams.log"
|
||||||
log = "logs.log"
|
errs = "errors.log"
|
||||||
|
logs = "logs.log"
|
||||||
host = "localhost"
|
host = "localhost"
|
||||||
port = 5000
|
port = 5001
|
||||||
server = true
|
server = true
|
||||||
open = false
|
open = false
|
||||||
)
|
)
|
||||||
@ -48,8 +49,9 @@ func init() {
|
|||||||
},
|
},
|
||||||
Resources: c.Resources{
|
Resources: c.Resources{
|
||||||
Config: config,
|
Config: config,
|
||||||
Output: output,
|
Streams: streams,
|
||||||
Log: log,
|
Logs: logs,
|
||||||
|
Errors: errs,
|
||||||
},
|
},
|
||||||
Server: c.Server{
|
Server: c.Server{
|
||||||
Enabled: server,
|
Enabled: server,
|
||||||
@ -138,8 +140,9 @@ func main() {
|
|||||||
},
|
},
|
||||||
Resources: c.Resources{
|
Resources: c.Resources{
|
||||||
Config: config,
|
Config: config,
|
||||||
Output: output,
|
Streams: streams,
|
||||||
Log: log,
|
Logs: logs,
|
||||||
|
Errors: errs,
|
||||||
},
|
},
|
||||||
Server: c.Server{
|
Server: c.Server{
|
||||||
Enabled: server,
|
Enabled: server,
|
||||||
|
File diff suppressed because one or more lines are too long
@ -12,13 +12,14 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Server struct contains server informations
|
// Server settings
|
||||||
type Server struct {
|
type Server struct {
|
||||||
*c.Settings `yaml:"-"`
|
*c.Settings `yaml:"-"`
|
||||||
*w.Blueprint `yaml:"-"`
|
*w.Blueprint `yaml:"-"`
|
||||||
Sync chan string `yaml:"-"`
|
Sync chan string `yaml:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render return a web pages defined in bindata
|
||||||
func render(c echo.Context, path string, mime int) error {
|
func render(c echo.Context, path string, mime int) error {
|
||||||
data, err := Asset(path)
|
data, err := Asset(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -45,7 +46,7 @@ func render(c echo.Context, path string, mime int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server starting
|
// Start the web server
|
||||||
func (s *Server) Start(p *cli.Context) (err error) {
|
func (s *Server) Start(p *cli.Context) (err error) {
|
||||||
if !p.Bool("no-server") && s.Enabled {
|
if !p.Bool("no-server") && s.Enabled {
|
||||||
e := echo.New()
|
e := echo.New()
|
||||||
@ -82,8 +83,7 @@ func (s *Server) Start(p *cli.Context) (err error) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
//websocket
|
//websocket
|
||||||
//e.GET("/ws", echo.WrapHandler(s.projects()))
|
e.GET("/ws", s.projects)
|
||||||
e.GET("/ws", s.hello)
|
|
||||||
|
|
||||||
go e.Start(string(s.Settings.Server.Host) + ":" + strconv.Itoa(s.Settings.Server.Port))
|
go e.Start(string(s.Settings.Server.Host) + ":" + strconv.Itoa(s.Settings.Server.Port))
|
||||||
if s.Open || p.Bool("open") {
|
if s.Open || p.Bool("open") {
|
||||||
@ -98,22 +98,24 @@ func (s *Server) Start(p *cli.Context) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) hello(c echo.Context) error {
|
func (s *Server) projects(c echo.Context) error {
|
||||||
websocket.Handler(func(ws *websocket.Conn) {
|
websocket.Handler(func(ws *websocket.Conn) {
|
||||||
defer ws.Close()
|
defer ws.Close()
|
||||||
msg, _ := json.Marshal(s.Blueprint.Projects)
|
msg, _ := json.Marshal(s.Blueprint.Projects)
|
||||||
err := websocket.Message.Send(ws, string(msg))
|
err := websocket.Message.Send(ws, string(msg))
|
||||||
|
go func() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-s.Sync:
|
case <-s.Sync:
|
||||||
msg, _ := json.Marshal(s.Blueprint.Projects)
|
msg, _ := json.Marshal(s.Blueprint.Projects)
|
||||||
err = websocket.Message.Send(ws, string(msg))
|
err = websocket.Message.Send(ws, string(msg))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//log.Println(err)
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
for {
|
||||||
// Read
|
// Read
|
||||||
text := ""
|
text := ""
|
||||||
err := websocket.Message.Receive(ws, &text)
|
err := websocket.Message.Receive(ws, &text)
|
||||||
@ -123,7 +125,6 @@ func (s *Server) hello(c echo.Context) error {
|
|||||||
} else {
|
} else {
|
||||||
err := json.Unmarshal([]byte(text), &s.Blueprint.Projects)
|
err := json.Unmarshal([]byte(text), &s.Blueprint.Projects)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//log.Println(err)
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
var cmd map[string]string
|
var cmd map[string]string
|
||||||
var stderr bytes.Buffer
|
var stderr bytes.Buffer
|
||||||
|
|
||||||
|
// Init an associative array with the os supported
|
||||||
func init() {
|
func init() {
|
||||||
cmd = map[string]string{
|
cmd = map[string]string{
|
||||||
"windows": "start",
|
"windows": "start",
|
||||||
@ -19,15 +20,17 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Open a url in the default browser
|
||||||
func Open(url string) (io.Writer, error) {
|
func Open(url string) (io.Writer, error) {
|
||||||
if open, err := cmd[runtime.GOOS]; !err {
|
open, err := cmd[runtime.GOOS]
|
||||||
|
if !err {
|
||||||
return nil, errors.New("This operating system is not supported.")
|
return nil, errors.New("This operating system is not supported.")
|
||||||
} else {
|
}
|
||||||
cmd := exec.Command(open, url)
|
cmd := exec.Command(open, url)
|
||||||
cmd.Stderr = &stderr
|
cmd.Stderr = &stderr
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
return cmd.Stderr, err
|
return cmd.Stderr, err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Colors allowed
|
||||||
type Colors struct {
|
type Colors struct {
|
||||||
Red
|
Red
|
||||||
Blue
|
Blue
|
||||||
@ -11,57 +12,77 @@ type Colors struct {
|
|||||||
Magenta
|
Magenta
|
||||||
Green
|
Green
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Red color
|
||||||
type Red struct{}
|
type Red struct{}
|
||||||
|
|
||||||
|
// Blue color
|
||||||
type Blue struct{}
|
type Blue struct{}
|
||||||
|
|
||||||
|
// Yellow color
|
||||||
type Yellow struct{}
|
type Yellow struct{}
|
||||||
|
|
||||||
|
// Magenta color
|
||||||
type Magenta struct{}
|
type Magenta struct{}
|
||||||
|
|
||||||
|
// Green color
|
||||||
type Green struct{}
|
type Green struct{}
|
||||||
|
|
||||||
|
// Regular font in red
|
||||||
func (c Red) Regular(t ...interface{}) string {
|
func (c Red) Regular(t ...interface{}) string {
|
||||||
r := color.New(color.FgRed).SprintFunc()
|
r := color.New(color.FgRed).SprintFunc()
|
||||||
return r(t...)
|
return r(t...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bold font in red
|
||||||
func (c Red) Bold(t ...interface{}) string {
|
func (c Red) Bold(t ...interface{}) string {
|
||||||
r := color.New(color.FgRed, color.Bold).SprintFunc()
|
r := color.New(color.FgRed, color.Bold).SprintFunc()
|
||||||
return r(t...)
|
return r(t...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regular font in blue
|
||||||
func (c Blue) Regular(t ...interface{}) string {
|
func (c Blue) Regular(t ...interface{}) string {
|
||||||
r := color.New(color.FgBlue).SprintFunc()
|
r := color.New(color.FgBlue).SprintFunc()
|
||||||
return r(t...)
|
return r(t...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bold font in blue
|
||||||
func (c Blue) Bold(t ...interface{}) string {
|
func (c Blue) Bold(t ...interface{}) string {
|
||||||
r := color.New(color.FgBlue, color.Bold).SprintFunc()
|
r := color.New(color.FgBlue, color.Bold).SprintFunc()
|
||||||
return r(t...)
|
return r(t...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regular font in yellow
|
||||||
func (c Yellow) Regular(t ...interface{}) string {
|
func (c Yellow) Regular(t ...interface{}) string {
|
||||||
r := color.New(color.FgYellow).SprintFunc()
|
r := color.New(color.FgYellow).SprintFunc()
|
||||||
return r(t...)
|
return r(t...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bold font in red
|
||||||
func (c Yellow) Bold(t ...interface{}) string {
|
func (c Yellow) Bold(t ...interface{}) string {
|
||||||
r := color.New(color.FgYellow, color.Bold).SprintFunc()
|
r := color.New(color.FgYellow, color.Bold).SprintFunc()
|
||||||
return r(t...)
|
return r(t...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regular font in magenta
|
||||||
func (c Magenta) Regular(t ...interface{}) string {
|
func (c Magenta) Regular(t ...interface{}) string {
|
||||||
r := color.New(color.FgMagenta).SprintFunc()
|
r := color.New(color.FgMagenta).SprintFunc()
|
||||||
return r(t...)
|
return r(t...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bold font in magenta
|
||||||
func (c Magenta) Bold(t ...interface{}) string {
|
func (c Magenta) Bold(t ...interface{}) string {
|
||||||
r := color.New(color.FgMagenta, color.Bold).SprintFunc()
|
r := color.New(color.FgMagenta, color.Bold).SprintFunc()
|
||||||
return r(t...)
|
return r(t...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regular font in green
|
||||||
func (c Green) Regular(t ...interface{}) string {
|
func (c Green) Regular(t ...interface{}) string {
|
||||||
r := color.New(color.FgGreen).SprintFunc()
|
r := color.New(color.FgGreen).SprintFunc()
|
||||||
return r(t...)
|
return r(t...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bold font in red
|
||||||
func (c Green) Bold(t ...interface{}) string {
|
func (c Green) Bold(t ...interface{}) string {
|
||||||
r := color.New(color.FgGreen, color.Bold).SprintFunc()
|
r := color.New(color.FgGreen, color.Bold).SprintFunc()
|
||||||
return r(t...)
|
return r(t...)
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Scan return a byte stream of a given file
|
// Stream return a byte stream of a given file
|
||||||
func (s Settings) Stream(file string) ([]byte, error) {
|
func (s Settings) Stream(file string) ([]byte, error) {
|
||||||
_, err := os.Stat(file)
|
_, err := os.Stat(file)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Settings defines a group of general settings
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
Colors `yaml:"-"`
|
Colors `yaml:"-"`
|
||||||
Resources `yaml:"resources" json:"resources"`
|
Resources `yaml:"resources" json:"resources"`
|
||||||
@ -12,10 +13,12 @@ type Settings struct {
|
|||||||
Config `yaml:"config" json:"config"`
|
Config `yaml:"config" json:"config"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Config defines structural options
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Flimit uint64 `yaml:"flimit" json:"flimit"`
|
Flimit uint64 `yaml:"flimit" json:"flimit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Server settings, used for the web panel
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Enabled bool `yaml:"enable" json:"enable"`
|
Enabled bool `yaml:"enable" json:"enable"`
|
||||||
Open bool `yaml:"open" json:"open"`
|
Open bool `yaml:"open" json:"open"`
|
||||||
@ -23,10 +26,12 @@ type Server struct {
|
|||||||
Port int `yaml:"port" json:"port"`
|
Port int `yaml:"port" json:"port"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resources defines the files generated by realize
|
||||||
type Resources struct {
|
type Resources struct {
|
||||||
Config string `yaml:"-" json:"-"`
|
Config string `yaml:"-" json:"-"`
|
||||||
Output string `yaml:"output" json:"output"`
|
Streams string `yaml:"streams" json:"output"`
|
||||||
Log string `yaml:"log" json:"log"`
|
Logs string `yaml:"logs" json:"log"`
|
||||||
|
Errors string `yaml:"errors" json:"error"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read from config file
|
// Read from config file
|
||||||
|
@ -6,12 +6,14 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Wdir return the current working directory
|
||||||
func (s Settings) Wdir() string {
|
func (s Settings) Wdir() string {
|
||||||
dir, err := os.Getwd()
|
dir, err := os.Getwd()
|
||||||
s.Validate(err)
|
s.Validate(err)
|
||||||
return filepath.Base(dir)
|
return filepath.Base(dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate checks a fatal error
|
||||||
func (s Settings) Validate(err error) error {
|
func (s Settings) Validate(err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Fatal(err, "")
|
s.Fatal(err, "")
|
||||||
@ -19,6 +21,7 @@ func (s Settings) Validate(err error) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fatal prints a fatal error with its additional messages
|
||||||
func (s Settings) Fatal(err error, msg ...interface{}) {
|
func (s Settings) Fatal(err error, msg ...interface{}) {
|
||||||
if len(msg) > 0 {
|
if len(msg) > 0 {
|
||||||
log.Fatalln(s.Red.Regular(msg...), err.Error())
|
log.Fatalln(s.Red.Regular(msg...), err.Error())
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Watch method adds the given paths on the Watcher
|
// Run launches the toolchain for each project
|
||||||
func (h *Blueprint) Run() error {
|
func (h *Blueprint) Run() error {
|
||||||
err := h.check()
|
err := h.check()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -68,7 +68,7 @@ func (h *Blueprint) Clean() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inserts a new project in the list
|
// Insert a new project in projects list
|
||||||
func (h *Blueprint) Insert(p *cli.Context) error {
|
func (h *Blueprint) Insert(p *cli.Context) error {
|
||||||
err := h.Add(p)
|
err := h.Add(p)
|
||||||
return err
|
return err
|
||||||
@ -134,9 +134,8 @@ func (h *Blueprint) check() error {
|
|||||||
if len(h.Projects) > 0 {
|
if len(h.Projects) > 0 {
|
||||||
h.Clean()
|
h.Clean()
|
||||||
return nil
|
return nil
|
||||||
} else {
|
|
||||||
return errors.New("There are no projects. The config file is empty.")
|
|
||||||
}
|
}
|
||||||
|
return errors.New("There are no projects. The config file is empty.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// NameParam check the project name presence. If empty takes the working directory name
|
// NameParam check the project name presence. If empty takes the working directory name
|
||||||
|
104
watcher/exec.go
104
watcher/exec.go
@ -3,6 +3,7 @@ package cli
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@ -14,11 +15,9 @@ import (
|
|||||||
|
|
||||||
// GoRun is an implementation of the bin execution
|
// GoRun is an implementation of the bin execution
|
||||||
func (p *Project) goRun(channel chan bool, runner chan bool, wr *sync.WaitGroup) error {
|
func (p *Project) goRun(channel chan bool, runner chan bool, wr *sync.WaitGroup) error {
|
||||||
|
|
||||||
var build *exec.Cmd
|
var build *exec.Cmd
|
||||||
var params []string
|
var params []string
|
||||||
var path = ""
|
var path = ""
|
||||||
|
|
||||||
for _, param := range p.Params {
|
for _, param := range p.Params {
|
||||||
arr := strings.Fields(param)
|
arr := strings.Fields(param)
|
||||||
params = append(params, arr...)
|
params = append(params, arr...)
|
||||||
@ -45,15 +44,14 @@ func (p *Project) goRun(channel chan bool, runner chan bool, wr *sync.WaitGroup)
|
|||||||
p.Buffer.StdLog = append(p.Buffer.StdLog, BufferOut{Time: time.Now(), Text: "Failed to stop: " + err.Error()})
|
p.Buffer.StdLog = append(p.Buffer.StdLog, BufferOut{Time: time.Now(), Text: "Failed to stop: " + err.Error()})
|
||||||
p.Fatal(err, "Failed to stop", ":")
|
p.Fatal(err, "Failed to stop", ":")
|
||||||
}
|
}
|
||||||
p.Buffer.StdLog = append(p.Buffer.StdLog, BufferOut{Time: time.Now(), Text: "Ended"})
|
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Regular("Ended"))
|
||||||
log.Println(p.pname(p.Name, 2), ":", p.Red.Regular("Ended"))
|
out := BufferOut{Time: time.Now(), Text: "Ended", Type: "Go Run"}
|
||||||
p.sync()
|
p.print("log", out, msg, "")
|
||||||
wr.Done()
|
wr.Done()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
stdout, err := build.StdoutPipe()
|
stdout, err := build.StdoutPipe()
|
||||||
stderr, err := build.StderrPipe()
|
stderr, err := build.StderrPipe()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(p.Red.Bold(err.Error()))
|
log.Println(p.Red.Bold(err.Error()))
|
||||||
return err
|
return err
|
||||||
@ -66,35 +64,24 @@ func (p *Project) goRun(channel chan bool, runner chan bool, wr *sync.WaitGroup)
|
|||||||
|
|
||||||
execOutput, execError := bufio.NewScanner(stdout), bufio.NewScanner(stderr)
|
execOutput, execError := bufio.NewScanner(stdout), bufio.NewScanner(stderr)
|
||||||
stopOutput, stopError := make(chan bool, 1), make(chan bool, 1)
|
stopOutput, stopError := make(chan bool, 1), make(chan bool, 1)
|
||||||
|
|
||||||
scanner := func(stop chan bool, output *bufio.Scanner, isError bool) {
|
scanner := func(stop chan bool, output *bufio.Scanner, isError bool) {
|
||||||
for output.Scan() {
|
for output.Scan() {
|
||||||
select {
|
select {
|
||||||
default:
|
default:
|
||||||
|
msg := fmt.Sprintln(p.pname(p.Name, 3), ":", p.Blue.Regular(output.Text()))
|
||||||
if isError {
|
if isError {
|
||||||
p.Buffer.StdErr = append(p.Buffer.StdErr, BufferOut{Time: time.Now(), Text: output.Text(), Type: "Go Run"})
|
out := BufferOut{Time: time.Now(), Text: output.Text(), Type: "Go Run"}
|
||||||
|
p.print("error", out, msg, "")
|
||||||
} else {
|
} else {
|
||||||
p.Buffer.StdOut = append(p.Buffer.StdOut, BufferOut{Time: time.Now(), Text: output.Text()})
|
out := BufferOut{Time: time.Now(), Text: output.Text()}
|
||||||
}
|
p.print("out", out, msg, "")
|
||||||
p.sync()
|
|
||||||
if p.Cli.Streams {
|
|
||||||
log.Println(p.pname(p.Name, 3), ":", p.Blue.Regular(output.Text()))
|
|
||||||
}
|
|
||||||
if p.File.Streams {
|
|
||||||
f := p.Create(p.base, p.parent.Resources.Output)
|
|
||||||
t := time.Now()
|
|
||||||
if _, err := f.WriteString(t.Format("2006-01-02 15:04:05") + " : " + output.Text() + "\r\n"); err != nil {
|
|
||||||
p.Fatal(err, "")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(stop)
|
close(stop)
|
||||||
}
|
}
|
||||||
p.Buffer.StdLog = append(p.Buffer.StdLog, BufferOut{Time: time.Now(), Text: "Started"})
|
|
||||||
go scanner(stopOutput, execOutput, false)
|
go scanner(stopOutput, execOutput, false)
|
||||||
go scanner(stopError, execError, true)
|
go scanner(stopError, execError, true)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-channel:
|
case <-channel:
|
||||||
@ -109,9 +96,6 @@ func (p *Project) goRun(channel chan bool, runner chan bool, wr *sync.WaitGroup)
|
|||||||
|
|
||||||
// GoBuild is an implementation of the "go build"
|
// GoBuild is an implementation of the "go build"
|
||||||
func (p *Project) goBuild() (string, error) {
|
func (p *Project) goBuild() (string, error) {
|
||||||
defer func() {
|
|
||||||
p.sync()
|
|
||||||
}()
|
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
var stderr bytes.Buffer
|
var stderr bytes.Buffer
|
||||||
build := exec.Command("go", "build")
|
build := exec.Command("go", "build")
|
||||||
@ -126,9 +110,6 @@ func (p *Project) goBuild() (string, error) {
|
|||||||
|
|
||||||
// GoInstall is an implementation of the "go install"
|
// GoInstall is an implementation of the "go install"
|
||||||
func (p *Project) goInstall() (string, error) {
|
func (p *Project) goInstall() (string, error) {
|
||||||
defer func() {
|
|
||||||
p.sync()
|
|
||||||
}()
|
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
var stderr bytes.Buffer
|
var stderr bytes.Buffer
|
||||||
err := os.Setenv("GOBIN", filepath.Join(os.Getenv("GOPATH"), "bin"))
|
err := os.Setenv("GOBIN", filepath.Join(os.Getenv("GOPATH"), "bin"))
|
||||||
@ -145,37 +126,11 @@ func (p *Project) goInstall() (string, error) {
|
|||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GoFmt is an implementation of the gofmt
|
// GoTools is used for run go methods such as fmt, test, generate...
|
||||||
func (p *Project) goFmt(path string) (string, error) {
|
func (p *Project) goTools(dir string, name string, cmd ...string) (string, error) {
|
||||||
var out, stderr bytes.Buffer
|
var out, stderr bytes.Buffer
|
||||||
build := exec.Command("gofmt", "-s", "-w", "-e", path)
|
build := exec.Command(name, cmd...)
|
||||||
build.Dir = p.base
|
build.Dir = dir
|
||||||
build.Stdout = &out
|
|
||||||
build.Stderr = &stderr
|
|
||||||
if err := build.Run(); err != nil {
|
|
||||||
return stderr.String(), err
|
|
||||||
}
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GoTest is an implementation of the go test
|
|
||||||
func (p *Project) goTest(path string) (string, error) {
|
|
||||||
var out, stderr bytes.Buffer
|
|
||||||
build := exec.Command("go", "test")
|
|
||||||
build.Dir = path
|
|
||||||
build.Stdout = &out
|
|
||||||
build.Stderr = &stderr
|
|
||||||
if err := build.Run(); err != nil {
|
|
||||||
return stderr.String(), err
|
|
||||||
}
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GoGenerate is an implementation of the go test
|
|
||||||
func (p *Project) goGenerate(path string) (string, error) {
|
|
||||||
var out, stderr bytes.Buffer
|
|
||||||
build := exec.Command("go", "generate")
|
|
||||||
build.Dir = path
|
|
||||||
build.Stdout = &out
|
build.Stdout = &out
|
||||||
build.Stderr = &stderr
|
build.Stderr = &stderr
|
||||||
if err := build.Run(); err != nil {
|
if err := build.Run(); err != nil {
|
||||||
@ -185,30 +140,21 @@ func (p *Project) goGenerate(path string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cmds exec a list of defined commands
|
// Cmds exec a list of defined commands
|
||||||
func (p *Project) cmds(cmds []string) (errors []string) {
|
func (p *Project) afterBefore(command string) (errors string, logs string) {
|
||||||
defer func() {
|
var stdout bytes.Buffer
|
||||||
p.sync()
|
|
||||||
}()
|
|
||||||
for _, cmd := range cmds {
|
|
||||||
var out bytes.Buffer
|
|
||||||
var stderr bytes.Buffer
|
var stderr bytes.Buffer
|
||||||
cmd := strings.Replace(strings.Replace(cmd, "'", "", -1), "\"", "", -1)
|
command = strings.Replace(strings.Replace(command, "'", "", -1), "\"", "", -1)
|
||||||
c := strings.Split(cmd, " ")
|
c := strings.Split(command, " ")
|
||||||
build := exec.Command(c[0], c[1:]...)
|
build := exec.Command(c[0], c[1:]...)
|
||||||
build.Dir = p.base
|
build.Dir = p.base
|
||||||
build.Stdout = &out
|
build.Stdout = &stdout
|
||||||
build.Stderr = &stderr
|
build.Stderr = &stderr
|
||||||
if err := build.Run(); err != nil {
|
err := build.Run()
|
||||||
errors = append(errors, stderr.String())
|
// check if log
|
||||||
return errors
|
logs = stdout.String()
|
||||||
|
if err != nil {
|
||||||
|
errors = stderr.String()
|
||||||
|
return errors, logs
|
||||||
}
|
}
|
||||||
}
|
return "", logs
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync datas with the web server
|
|
||||||
func (p *Project) sync() {
|
|
||||||
go func() {
|
|
||||||
p.parent.Sync <- "sync"
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ type logWriter struct {
|
|||||||
c.Colors
|
c.Colors
|
||||||
}
|
}
|
||||||
|
|
||||||
// Projects struct contains a projects list
|
// Blueprint struct contains a projects list
|
||||||
type Blueprint struct {
|
type Blueprint struct {
|
||||||
*c.Settings `yaml:"-"`
|
*c.Settings `yaml:"-"`
|
||||||
Projects []Project `yaml:"projects,omitempty" json:"projects,omitempty"`
|
Projects []Project `yaml:"projects,omitempty" json:"projects,omitempty"`
|
||||||
@ -28,12 +28,12 @@ type Project struct {
|
|||||||
base string
|
base string
|
||||||
Name string `yaml:"name" json:"name"`
|
Name string `yaml:"name" json:"name"`
|
||||||
Path string `yaml:"path" json:"path"`
|
Path string `yaml:"path" json:"path"`
|
||||||
Run bool `yaml:"run" json:"run"`
|
|
||||||
Bin bool `yaml:"bin" json:"bin"`
|
|
||||||
Generate bool `yaml:"generate" json:"generate"`
|
|
||||||
Build bool `yaml:"build" json:"build"`
|
|
||||||
Fmt bool `yaml:"fmt" json:"fmt"`
|
Fmt bool `yaml:"fmt" json:"fmt"`
|
||||||
Test bool `yaml:"test" json:"test"`
|
Test bool `yaml:"test" json:"test"`
|
||||||
|
Generate bool `yaml:"generate" json:"generate"`
|
||||||
|
Bin bool `yaml:"bin" json:"bin"`
|
||||||
|
Build bool `yaml:"build" json:"build"`
|
||||||
|
Run bool `yaml:"run" json:"run"`
|
||||||
Params []string `yaml:"params" json:"params"`
|
Params []string `yaml:"params" json:"params"`
|
||||||
Watcher Watcher `yaml:"watcher" json:"watcher"`
|
Watcher Watcher `yaml:"watcher" json:"watcher"`
|
||||||
Cli Cli `yaml:"cli" json:"cli"`
|
Cli Cli `yaml:"cli" json:"cli"`
|
||||||
@ -54,23 +54,26 @@ type Watcher struct {
|
|||||||
Preview bool `yaml:"preview" json:"preview"`
|
Preview bool `yaml:"preview" json:"preview"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cli output status, enables or disables
|
||||||
type Cli struct {
|
type Cli struct {
|
||||||
Streams bool `yaml:"streams" json:"streams"`
|
Streams bool `yaml:"streams" json:"streams"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// File determinates the status of each log files (streams, logs, errors)
|
||||||
type File struct {
|
type File struct {
|
||||||
Streams bool `yaml:"streams" json:"streams"`
|
Streams bool `yaml:"streams" json:"streams"`
|
||||||
Logs bool `yaml:"logs" json:"logs"`
|
Logs bool `yaml:"logs" json:"logs"`
|
||||||
Errors bool `yaml:"errors" json:"errors"`
|
Errors bool `yaml:"errors" json:"errors"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer struct for buffering outputs
|
// Buffer define an array buffer for each log files
|
||||||
type Buffer struct {
|
type Buffer struct {
|
||||||
StdOut []BufferOut `json:"stdOut"`
|
StdOut []BufferOut `json:"stdOut"`
|
||||||
StdLog []BufferOut `json:"stdLog"`
|
StdLog []BufferOut `json:"stdLog"`
|
||||||
StdErr []BufferOut `json:"stdErr"`
|
StdErr []BufferOut `json:"stdErr"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BufferOut is used for exchange information between "realize cli" and "web realize"
|
||||||
type BufferOut struct {
|
type BufferOut struct {
|
||||||
Time time.Time `json:"time"`
|
Time time.Time `json:"time"`
|
||||||
Text string `json:"text"`
|
Text string `json:"text"`
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -56,11 +57,9 @@ func (p *Project) watching() {
|
|||||||
file := event.Name[:i] + ext
|
file := event.Name[:i] + ext
|
||||||
path := filepath.Dir(event.Name[:i])
|
path := filepath.Dir(event.Name[:i])
|
||||||
if event.Name[:i] != "" && inArray(ext, p.Watcher.Exts) {
|
if event.Name[:i] != "" && inArray(ext, p.Watcher.Exts) {
|
||||||
p.Buffer.StdLog = append(p.Buffer.StdLog, BufferOut{Time: time.Now(), Text: strings.ToUpper(ext[1:]) + " changed " + file})
|
msg := fmt.Sprintln(p.pname(p.Name, 4), ":", p.Magenta.Bold(strings.ToUpper(ext[1:])+" changed"), p.Magenta.Bold(file))
|
||||||
go func() {
|
out := BufferOut{Time: time.Now(), Text: strings.ToUpper(ext[1:]) + " changed " + file}
|
||||||
p.parent.Sync <- "sync"
|
p.print("log", out, msg, "")
|
||||||
}()
|
|
||||||
log.Println(p.pname(p.Name, 4), ":", p.Magenta.Bold(strings.ToUpper(ext[1:])+" changed"), p.Magenta.Bold(file))
|
|
||||||
// stop and run again
|
// stop and run again
|
||||||
if p.Run {
|
if p.Run {
|
||||||
close(channel)
|
close(channel)
|
||||||
@ -83,25 +82,27 @@ func (p *Project) watching() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install calls an implementation of the "go install"
|
// Install calls an implementation of "go install"
|
||||||
func (p *Project) install() {
|
func (p *Project) install() error {
|
||||||
if p.Bin {
|
if p.Bin {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
log.Println(p.pname(p.Name, 1), ":", "Installing..")
|
log.Println(p.pname(p.Name, 1), ":", "Installing..")
|
||||||
if stream, err := p.goInstall(); err != nil {
|
stream, err := p.goInstall()
|
||||||
|
if err != nil {
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Install"), p.Red.Regular(err.Error()))
|
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Install"), p.Red.Regular(err.Error()))
|
||||||
out := BufferOut{Time: time.Now(), Text: err.Error(), Type: "Go Install", Stream: stream}
|
out := BufferOut{Time: time.Now(), Text: err.Error(), Type: "Go Install", Stream: stream}
|
||||||
p.print("error", out, msg, stream)
|
p.print("error", out, msg, stream)
|
||||||
} else {
|
} else {
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Regular("Installed")+" after", p.Magenta.Regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s"))
|
msg := fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Regular("Installed")+" after", p.Magenta.Regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s"))
|
||||||
out := BufferOut{Time: time.Now(), Text: "Installed"}
|
out := BufferOut{Time: time.Now(), Text: "Installed after " + big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3) + " s"}
|
||||||
p.print("log", out, msg, stream)
|
p.print("log", out, msg, stream)
|
||||||
}
|
}
|
||||||
p.sync()
|
return err
|
||||||
}
|
}
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Install calls an implementation of "go run"
|
||||||
func (p *Project) run(channel chan bool, wr *sync.WaitGroup) {
|
func (p *Project) run(channel chan bool, wr *sync.WaitGroup) {
|
||||||
if p.Run {
|
if p.Run {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
@ -112,7 +113,7 @@ func (p *Project) run(channel chan bool, wr *sync.WaitGroup) {
|
|||||||
select {
|
select {
|
||||||
case <-runner:
|
case <-runner:
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Regular("Has been run")+" after", p.Magenta.Regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s"))
|
msg := fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Regular("Has been run")+" after", p.Magenta.Regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s"))
|
||||||
out := BufferOut{Time: time.Now(), Text: "Has been run"}
|
out := BufferOut{Time: time.Now(), Text: "Has been run after " + big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3) + " s"}
|
||||||
p.print("log", out, msg, "")
|
p.print("log", out, msg, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -121,31 +122,29 @@ func (p *Project) run(channel chan bool, wr *sync.WaitGroup) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build calls an implementation of the "go build"
|
// Build calls an implementation of the "go build"
|
||||||
func (p *Project) build() {
|
func (p *Project) build() error {
|
||||||
if p.Build {
|
if p.Build {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
log.Println(p.pname(p.Name, 1), ":", "Building..")
|
log.Println(p.pname(p.Name, 1), ":", "Building..")
|
||||||
if stream, err := p.goBuild(); err != nil {
|
stream, err := p.goBuild()
|
||||||
|
if err != nil {
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Build"), p.Red.Regular(err.Error()))
|
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Build"), p.Red.Regular(err.Error()))
|
||||||
out := BufferOut{Time: time.Now(), Text: err.Error(), Type: "Go Build", Stream: stream}
|
out := BufferOut{Time: time.Now(), Text: err.Error(), Type: "Go Build", Stream: stream}
|
||||||
p.print("error", out, msg, stream)
|
p.print("error", out, msg, stream)
|
||||||
} else {
|
} else {
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Regular("Builded")+" after", p.Magenta.Regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s"))
|
msg := fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Regular("Builded")+" after", p.Magenta.Regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s"))
|
||||||
out := BufferOut{Time: time.Now(), Text: "Builded"}
|
out := BufferOut{Time: time.Now(), Text: "Builded after " + big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3) + " s"}
|
||||||
p.print("log", out, msg, stream)
|
p.print("log", out, msg, stream)
|
||||||
}
|
}
|
||||||
p.sync()
|
return err
|
||||||
}
|
}
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fmt calls an implementation of the "go fmt"
|
// Fmt calls an implementation of the "go fmt"
|
||||||
func (p *Project) fmt(path string) error {
|
func (p *Project) fmt(path string) error {
|
||||||
defer func() {
|
if p.Fmt {
|
||||||
p.sync()
|
if stream, err := p.goTools(p.base, "gofmt", "-s", "-w", "-e", path); err != nil {
|
||||||
}()
|
|
||||||
if p.Fmt && strings.HasSuffix(path, ".go") {
|
|
||||||
if stream, err := p.goFmt(path); err != nil {
|
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Fmt"), p.Red.Regular("there are some errors in"), ":", p.Magenta.Bold(path))
|
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Fmt"), p.Red.Regular("there are some errors in"), ":", p.Magenta.Bold(path))
|
||||||
out := BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: "Go Fmt", Stream: stream}
|
out := BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: "Go Fmt", Stream: stream}
|
||||||
p.print("error", out, msg, stream)
|
p.print("error", out, msg, stream)
|
||||||
@ -157,11 +156,8 @@ func (p *Project) fmt(path string) error {
|
|||||||
|
|
||||||
// Generate calls an implementation of the "go generate"
|
// Generate calls an implementation of the "go generate"
|
||||||
func (p *Project) generate(path string) error {
|
func (p *Project) generate(path string) error {
|
||||||
defer func() {
|
|
||||||
p.sync()
|
|
||||||
}()
|
|
||||||
if p.Generate {
|
if p.Generate {
|
||||||
if stream, err := p.goGenerate(path); err != nil {
|
if stream, err := p.goTools(path, "go", "generate"); err != nil {
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Generate"), p.Red.Regular("there are some errors in"), ":", p.Magenta.Bold(path))
|
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Generate"), p.Red.Regular("there are some errors in"), ":", p.Magenta.Bold(path))
|
||||||
out := BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: "Go Generate", Stream: stream}
|
out := BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: "Go Generate", Stream: stream}
|
||||||
p.print("error", out, msg, stream)
|
p.print("error", out, msg, stream)
|
||||||
@ -171,17 +167,44 @@ func (p *Project) generate(path string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test calls an implementation of the "go test"
|
||||||
|
func (p *Project) test(path string) error {
|
||||||
|
if p.Test {
|
||||||
|
if stream, err := p.goTools(path, "go", "test"); err != nil {
|
||||||
|
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Test"), p.Red.Regular("there are some errors in "), ":", p.Magenta.Bold(path))
|
||||||
|
out := BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: "Go Test", Stream: stream}
|
||||||
|
p.print("error", out, msg, stream)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Cmd calls an wrapper for execute the commands after/before
|
// Cmd calls an wrapper for execute the commands after/before
|
||||||
func (p *Project) cmd(exit chan bool) {
|
func (p *Project) cmd(exit chan bool) {
|
||||||
c := make(chan os.Signal, 2)
|
c := make(chan os.Signal, 2)
|
||||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||||
cast := func(commands []string) {
|
cast := func(commands []string) {
|
||||||
if errs := p.cmds(commands); errs != nil {
|
for _, command := range commands {
|
||||||
for _, err := range errs {
|
errors, logs := p.afterBefore(command)
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold(err))
|
msg := fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Bold("Command"), p.Green.Bold("\"")+command+p.Green.Bold("\""))
|
||||||
out := BufferOut{Time: time.Now(), Text: err, Type: "After/Before"}
|
out := BufferOut{Time: time.Now(), Text: command, Type: "After/Before"}
|
||||||
|
if logs != "" {
|
||||||
|
p.print("log", out, msg, "")
|
||||||
|
}
|
||||||
|
if errors != "" {
|
||||||
p.print("error", out, msg, "")
|
p.print("error", out, msg, "")
|
||||||
}
|
}
|
||||||
|
if logs != "" {
|
||||||
|
msg = fmt.Sprintln(logs)
|
||||||
|
out = BufferOut{Time: time.Now(), Text: logs, Type: "After/Before"}
|
||||||
|
p.print("log", out, "", msg)
|
||||||
|
}
|
||||||
|
if errors != "" {
|
||||||
|
msg = fmt.Sprintln(p.Red.Regular(errors))
|
||||||
|
out = BufferOut{Time: time.Now(), Text: errors, Type: "After/Before"}
|
||||||
|
p.print("error", out, "", msg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,22 +225,6 @@ func (p *Project) cmd(exit chan bool) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test calls an implementation of the "go test"
|
|
||||||
func (p *Project) test(path string) error {
|
|
||||||
defer func() {
|
|
||||||
p.sync()
|
|
||||||
}()
|
|
||||||
if p.Test {
|
|
||||||
if stream, err := p.goTest(path); err != nil {
|
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Test"), p.Red.Regular("there are some errors in "), ":", p.Magenta.Bold(path))
|
|
||||||
out := BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: "Go Test", Stream: stream}
|
|
||||||
p.print("error", out, msg, stream)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Walks the file tree of a project
|
// Walks the file tree of a project
|
||||||
func (p *Project) walks(watcher *fsnotify.Watcher) error {
|
func (p *Project) walks(watcher *fsnotify.Watcher) error {
|
||||||
var files, folders int64
|
var files, folders int64
|
||||||
@ -262,11 +269,13 @@ func (p *Project) walks(watcher *fsnotify.Watcher) error {
|
|||||||
return errors.New(base + " path doesn't exist")
|
return errors.New(base + " path doesn't exist")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Println(p.pname(p.Name, 1), ":", p.Blue.Bold("Watching"), p.Magenta.Bold(files), "file/s", p.Magenta.Bold(folders), "folder/s")
|
msg := fmt.Sprintln(p.pname(p.Name, 1), ":", p.Blue.Bold("Watching"), p.Magenta.Bold(files), "file/s", p.Magenta.Bold(folders), "folder/s")
|
||||||
|
out := BufferOut{Time: time.Now(), Text: "Watching " + strconv.FormatInt(files, 10) + " files/s " + strconv.FormatInt(folders, 10) + " folder/s"}
|
||||||
|
p.print("log", out, msg, "")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore validates a path
|
// Ignore and validate a path
|
||||||
func (p *Project) ignore(str string) bool {
|
func (p *Project) ignore(str string) bool {
|
||||||
for _, v := range p.Watcher.Ignore {
|
for _, v := range p.Watcher.Ignore {
|
||||||
if strings.Contains(str, filepath.Join(p.base, v)) {
|
if strings.Contains(str, filepath.Join(p.base, v)) {
|
||||||
@ -276,12 +285,14 @@ func (p *Project) ignore(str string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routines launches the following methods: run, build, install
|
// Routines launches the toolchain run, build, install
|
||||||
func (p *Project) routines(channel chan bool, wr *sync.WaitGroup) {
|
func (p *Project) routines(channel chan bool, wr *sync.WaitGroup) {
|
||||||
p.install()
|
install := p.install()
|
||||||
p.build()
|
build := p.build()
|
||||||
wr.Add(1)
|
wr.Add(1)
|
||||||
|
if install == nil && build == nil {
|
||||||
go p.run(channel, wr)
|
go p.run(channel, wr)
|
||||||
|
}
|
||||||
wr.Wait()
|
wr.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,39 +318,59 @@ func (p *Project) pname(name string, color int) string {
|
|||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Print on files, cli, ws
|
||||||
func (p *Project) print(t string, o BufferOut, msg string, stream string) {
|
func (p *Project) print(t string, o BufferOut, msg string, stream string) {
|
||||||
switch t {
|
switch t {
|
||||||
case "out":
|
case "out":
|
||||||
p.Buffer.StdOut = append(p.Buffer.StdOut, o)
|
p.Buffer.StdOut = append(p.Buffer.StdOut, o)
|
||||||
if p.File.Streams {
|
if p.File.Streams {
|
||||||
f := p.Create(p.base, p.parent.Resources.Output)
|
f := p.Create(p.base, p.parent.Resources.Streams)
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
if _, err := f.WriteString(t.Format("2006-01-02 15:04:05") + " : " + o.Text + "\r\n"); err != nil {
|
s := []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Text, "\r\n"}
|
||||||
|
if _, err := f.WriteString(strings.Join(s, " ")); err != nil {
|
||||||
p.Fatal(err, "")
|
p.Fatal(err, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if msg != "" && p.Cli.Streams {
|
||||||
|
log.Print(msg)
|
||||||
|
}
|
||||||
case "log":
|
case "log":
|
||||||
p.Buffer.StdLog = append(p.Buffer.StdLog, o)
|
p.Buffer.StdLog = append(p.Buffer.StdLog, o)
|
||||||
if p.File.Logs {
|
if p.File.Logs {
|
||||||
f := p.Create(p.base, p.parent.Resources.Log)
|
f := p.Create(p.base, p.parent.Resources.Logs)
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
if _, err := f.WriteString(t.Format("2006-01-02 15:04:05") + " : " + o.Text + "\r\n"); err != nil {
|
s := []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Text, "\r\n"}
|
||||||
|
if stream != "" {
|
||||||
|
s = []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Text, "\r\n", stream}
|
||||||
|
}
|
||||||
|
if _, err := f.WriteString(strings.Join(s, " ")); err != nil {
|
||||||
p.Fatal(err, "")
|
p.Fatal(err, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if msg != "" {
|
||||||
|
log.Print(msg)
|
||||||
|
}
|
||||||
case "error":
|
case "error":
|
||||||
p.Buffer.StdErr = append(p.Buffer.StdErr, o)
|
p.Buffer.StdErr = append(p.Buffer.StdErr, o)
|
||||||
if p.File.Errors {
|
if p.File.Errors {
|
||||||
f := p.Create(p.base, p.parent.Resources.Log)
|
f := p.Create(p.base, p.parent.Resources.Errors)
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
if _, err := f.WriteString(t.Format("2006-01-02 15:04:05") + " : " + o.Text + "\r\n"); err != nil {
|
s := []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Type, o.Text, o.Path, "\r\n"}
|
||||||
|
if stream != "" {
|
||||||
|
s = []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Type, o.Text, o.Path, "\r\n", stream}
|
||||||
|
}
|
||||||
|
if _, err := f.WriteString(strings.Join(s, " ")); err != nil {
|
||||||
p.Fatal(err, "")
|
p.Fatal(err, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if msg != "" {
|
||||||
}
|
|
||||||
log.Print(msg)
|
log.Print(msg)
|
||||||
if stream != "" {
|
|
||||||
fmt.Println(stream)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if stream != "" {
|
||||||
|
fmt.Print(stream)
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
p.parent.Sync <- "sync"
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user