commit
e68331b6d1
110
cmd.go
110
cmd.go
|
@ -6,6 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Tool options customizable, should be moved in Cmd
|
// Tool options customizable, should be moved in Cmd
|
||||||
|
@ -50,20 +51,11 @@ func (r *realize) clean() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether there is a project
|
|
||||||
func (r *realize) check() error {
|
|
||||||
if len(r.Schema) > 0 {
|
|
||||||
r.clean()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return errors.New("there are no projects")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a new project
|
// Add a new project
|
||||||
func (r *realize) add(p *cli.Context) error {
|
func (r *realize) add(p *cli.Context) error {
|
||||||
project := Project{
|
project := Project{
|
||||||
Name: r.Settings.name(p.String("name"), p.String("path")),
|
Name: filepath.Base(filepath.Clean(p.String("path"))),
|
||||||
Path: r.Settings.path(p.String("path")),
|
Path: filepath.Clean(p.String("path")),
|
||||||
Cmds: Cmds{
|
Cmds: Cmds{
|
||||||
Vet: Cmd{
|
Vet: Cmd{
|
||||||
Status: p.Bool("vet"),
|
Status: p.Bool("vet"),
|
||||||
|
@ -88,7 +80,7 @@ func (r *realize) add(p *cli.Context) error {
|
||||||
Args: params(p),
|
Args: params(p),
|
||||||
Watcher: Watch{
|
Watcher: Watch{
|
||||||
Paths: []string{"/"},
|
Paths: []string{"/"},
|
||||||
Ignore: []string{"vendor"},
|
Ignore: []string{".git",".realize","vendor"},
|
||||||
Exts: []string{"go"},
|
Exts: []string{"go"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -101,8 +93,18 @@ func (r *realize) add(p *cli.Context) error {
|
||||||
|
|
||||||
// Run launches the toolchain for each project
|
// Run launches the toolchain for each project
|
||||||
func (r *realize) run(p *cli.Context) error {
|
func (r *realize) run(p *cli.Context) error {
|
||||||
err := r.check()
|
var match bool
|
||||||
if err == nil {
|
// check projects and remove duplicates
|
||||||
|
if len(r.Schema) > 0 {
|
||||||
|
r.clean()
|
||||||
|
}else{
|
||||||
|
return errors.New("there are no projects")
|
||||||
|
}
|
||||||
|
// set gobin
|
||||||
|
err := os.Setenv("GOBIN", filepath.Join(os.Getenv("GOPATH"), "bin"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
// loop projects
|
// loop projects
|
||||||
if p.String("name") != "" {
|
if p.String("name") != "" {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
@ -114,27 +116,45 @@ func (r *realize) run(p *cli.Context) error {
|
||||||
if p.String("name") != "" && r.Schema[k].Name != p.String("name") {
|
if p.String("name") != "" && r.Schema[k].Name != p.String("name") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
//fields := reflect.Indirect(reflect.ValueOf(&r.Schema[k].Cmds))
|
// validate project path, if invalid get wdir or clean current
|
||||||
//// Loop struct Cmds fields
|
if !filepath.IsAbs(elm.Path){
|
||||||
//for i := 0; i < fields.NumField(); i++ {
|
r.Schema[k].Path = wdir()
|
||||||
// field := fields.Type().Field(i).Name
|
}else{
|
||||||
// if fields.FieldByName(field).Type().Name() == "Cmd" {
|
r.Schema[k].Path = filepath.Clean(elm.Path)
|
||||||
// v := fields.FieldByName(field)
|
}
|
||||||
// // Loop struct Cmd
|
// env variables
|
||||||
// for i := 0; i < v.NumField(); i++ {
|
for key, item := range r.Schema[k].Environment {
|
||||||
// f := v.Field(i)
|
if err := os.Setenv(key, item); err != nil {
|
||||||
|
r.Schema[k].Buffer.StdErr = append(r.Schema[k].Buffer.StdErr, BufferOut{Time: time.Now(), Text: err.Error(), Type: "Env error", Stream: ""})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// get basepath name
|
||||||
|
r.Schema[k].name = filepath.Base(r.Schema[k].Path)
|
||||||
|
|
||||||
|
fields := reflect.Indirect(reflect.ValueOf(&r.Schema[k].Cmds))
|
||||||
|
// Loop struct Cmds fields
|
||||||
|
for i := 0; i < fields.NumField(); i++ {
|
||||||
|
field := fields.Type().Field(i).Name
|
||||||
|
if fields.FieldByName(field).Type().Name() == "Cmd" {
|
||||||
|
v := fields.FieldByName(field)
|
||||||
|
// Loop struct Cmd
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
//f := v.Type().Field(i).Name
|
||||||
|
//fmt.Println(f)
|
||||||
//if f.IsValid() {
|
//if f.IsValid() {
|
||||||
// if f.CanSet() {
|
// if f.CanSet() {
|
||||||
// switch f.Kind() {
|
// fmt.Println(f.)
|
||||||
// case reflect.Bool:
|
// //switch f.Kind() {
|
||||||
// case reflect.String:
|
// //case reflect.Bool:
|
||||||
// case reflect.Slice:
|
// //case reflect.String:
|
||||||
// }
|
// //case reflect.Slice:
|
||||||
// }
|
// //}
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if elm.Cmds.Fmt.Status {
|
if elm.Cmds.Fmt.Status {
|
||||||
if len(elm.Cmds.Fmt.Args) == 0 {
|
if len(elm.Cmds.Fmt.Args) == 0 {
|
||||||
elm.Cmds.Fmt.Args = []string{"-s", "-w", "-e", "./"}
|
elm.Cmds.Fmt.Args = []string{"-s", "-w", "-e", "./"}
|
||||||
|
@ -190,35 +210,15 @@ func (r *realize) run(p *cli.Context) error {
|
||||||
startTxt: "Building...",
|
startTxt: "Building...",
|
||||||
endTxt: "Built",
|
endTxt: "Built",
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Schema[k].parent = r
|
r.Schema[k].parent = r
|
||||||
r.Schema[k].path = r.Schema[k].Path
|
|
||||||
|
|
||||||
// env variables
|
match = true
|
||||||
for key, item := range r.Schema[k].Environment {
|
|
||||||
if err := os.Setenv(key, item); err != nil {
|
|
||||||
r.Schema[k].Buffer.StdErr = append(r.Schema[k].Buffer.StdErr, BufferOut{Time: time.Now(), Text: err.Error(), Type: "Env error", Stream: ""})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// base path of the project
|
|
||||||
wd, err := os.Getwd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if elm.path == "." || elm.path == "/" {
|
|
||||||
r.Schema[k].base = wd
|
|
||||||
r.Schema[k].path = elm.wdir()
|
|
||||||
} else if filepath.IsAbs(elm.path) {
|
|
||||||
r.Schema[k].base = elm.path
|
|
||||||
} else {
|
|
||||||
r.Schema[k].base = filepath.Join(wd, elm.path)
|
|
||||||
}
|
|
||||||
go r.Schema[k].watch()
|
go r.Schema[k].watch()
|
||||||
}
|
}
|
||||||
wg.Wait()
|
if !match {
|
||||||
return nil
|
return errors.New("there is no project with the given name")
|
||||||
}
|
}
|
||||||
|
wg.Wait()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
24
cmd_test.go
24
cmd_test.go
|
@ -8,6 +8,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
type loggerT struct{}
|
type loggerT struct{}
|
||||||
|
@ -39,19 +40,6 @@ func TestRealize_Clean(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRealize_Check(t *testing.T) {
|
|
||||||
r := realize{}
|
|
||||||
err := r.check()
|
|
||||||
if err == nil {
|
|
||||||
t.Error("There is no project, error expected")
|
|
||||||
}
|
|
||||||
r.Schema = append(r.Schema, Project{Name: "test0"})
|
|
||||||
err = r.check()
|
|
||||||
if err != nil {
|
|
||||||
t.Error("There is a project, error unexpected", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRealize_Add(t *testing.T) {
|
func TestRealize_Add(t *testing.T) {
|
||||||
r := realize{}
|
r := realize{}
|
||||||
// add all flags, test with expected
|
// add all flags, test with expected
|
||||||
|
@ -63,13 +51,13 @@ func TestRealize_Add(t *testing.T) {
|
||||||
set.Bool("run", false, "")
|
set.Bool("run", false, "")
|
||||||
set.Bool("build", false, "")
|
set.Bool("build", false, "")
|
||||||
set.Bool("generate", false, "")
|
set.Bool("generate", false, "")
|
||||||
set.String("path", "", "")
|
set.String("path", wdir(), "")
|
||||||
c := cli.NewContext(nil, set, nil)
|
c := cli.NewContext(nil, set, nil)
|
||||||
set.Parse([]string{"--path=test_path", "--fmt", "--install", "--run", "--build", "--generate", "--test", "--vet"})
|
set.Parse([]string{"--fmt", "--install", "--run", "--build", "--generate", "--test", "--vet"})
|
||||||
r.add(c)
|
r.add(c)
|
||||||
expected := Project{
|
expected := Project{
|
||||||
Name: "test_path",
|
Name: filepath.Base(wdir()),
|
||||||
Path: "test_path",
|
Path: wdir(),
|
||||||
Cmds: Cmds{
|
Cmds: Cmds{
|
||||||
Fmt: Cmd{
|
Fmt: Cmd{
|
||||||
Status: true,
|
Status: true,
|
||||||
|
@ -93,7 +81,7 @@ func TestRealize_Add(t *testing.T) {
|
||||||
},
|
},
|
||||||
Watcher: Watch{
|
Watcher: Watch{
|
||||||
Paths: []string{"/"},
|
Paths: []string{"/"},
|
||||||
Ignore: []string{"vendor"},
|
Ignore: []string{".git",".realize","vendor"},
|
||||||
Exts: []string{"go"},
|
Exts: []string{"go"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
42
exec.go
42
exec.go
|
@ -12,6 +12,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GoCompile is used for compile a project
|
// GoCompile is used for compile a project
|
||||||
|
@ -19,16 +20,9 @@ func (p *Project) goCompile(stop <-chan bool, method []string, args []string) (s
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
var stderr bytes.Buffer
|
var stderr bytes.Buffer
|
||||||
done := make(chan error)
|
done := make(chan error)
|
||||||
err := os.Setenv("GOBIN", filepath.Join(getEnvPath("GOPATH"), "bin"))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
args = append(method, args...)
|
args = append(method, args...)
|
||||||
cmd := exec.Command(args[0], args[1:]...)
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
if _, err := os.Stat(filepath.Join(p.base, p.path)); err == nil {
|
cmd.Dir = p.Path
|
||||||
p.path = filepath.Join(p.base, p.path)
|
|
||||||
}
|
|
||||||
cmd.Dir = p.path
|
|
||||||
cmd.Stdout = &out
|
cmd.Stdout = &out
|
||||||
cmd.Stderr = &stderr
|
cmd.Stderr = &stderr
|
||||||
// Start command
|
// Start command
|
||||||
|
@ -53,6 +47,8 @@ func (p *Project) goCompile(stop <-chan bool, method []string, args []string) (s
|
||||||
func (p *Project) goRun(stop <-chan bool, runner chan bool) {
|
func (p *Project) goRun(stop <-chan bool, runner chan bool) {
|
||||||
var build *exec.Cmd
|
var build *exec.Cmd
|
||||||
var args []string
|
var args []string
|
||||||
|
|
||||||
|
// custom error pattern
|
||||||
isErrorText := func(string) bool {
|
isErrorText := func(string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -67,29 +63,33 @@ func (p *Project) goRun(stop <-chan bool, runner chan bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add additional arguments
|
||||||
for _, arg := range p.Args {
|
for _, arg := range p.Args {
|
||||||
a := strings.FieldsFunc(arg, func(i rune) bool {
|
a := strings.FieldsFunc(arg, func(i rune) bool {
|
||||||
return i == '"' || i == '=' || i == '\''
|
return i == '"' || i == '=' || i == '\''
|
||||||
})
|
})
|
||||||
args = append(args, a...)
|
args = append(args, a...)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := os.Stat(filepath.Join(getEnvPath("GOBIN"), filepath.Base(p.base))); err == nil {
|
|
||||||
build = exec.Command(filepath.Join(getEnvPath("GOBIN"), filepath.Base(p.base)), args...)
|
gobin := os.Getenv("GOBIN")
|
||||||
} else if _, err := os.Stat(filepath.Join(getEnvPath("GOBIN"), filepath.Base(p.base)) + extWindows); err == nil {
|
path := filepath.Join(gobin, p.name)
|
||||||
build = exec.Command(filepath.Join(getEnvPath("GOBIN"), filepath.Base(p.base))+extWindows, args...)
|
if _, err := os.Stat(path); err == nil {
|
||||||
|
build = exec.Command(path, args...)
|
||||||
|
} else if _, err := os.Stat(path + extWindows); err == nil {
|
||||||
|
build = exec.Command(path+extWindows, args...)
|
||||||
} else {
|
} else {
|
||||||
path := filepath.Join(p.base, filepath.Base(p.base))
|
path := filepath.Join(p.Path, p.name)
|
||||||
if _, err = os.Stat(path); err == nil {
|
if _, err = os.Stat(path); err == nil {
|
||||||
build = exec.Command(path, args...)
|
build = exec.Command(path, args...)
|
||||||
} else if _, err = os.Stat(path + extWindows); err == nil {
|
} else if _, err = os.Stat(path + extWindows); err == nil {
|
||||||
build = exec.Command(path+extWindows, args...)
|
build = exec.Command(path+extWindows, args...)
|
||||||
} else {
|
} else {
|
||||||
p.Buffer.StdLog = append(p.Buffer.StdLog, BufferOut{Time: time.Now(), Text: "Can't run a not compiled project"})
|
p.err(errors.New("Build not found"))
|
||||||
p.fatal(nil, "Can't run a not compiled project", ":")
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := build.Process.Kill(); err != nil {
|
if err := build.Process.Kill(); err != nil {
|
||||||
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()})
|
||||||
|
@ -100,6 +100,7 @@ func (p *Project) goRun(stop <-chan bool, runner chan bool) {
|
||||||
p.stamp("log", out, msg, "")
|
p.stamp("log", out, msg, "")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// scan project stream
|
||||||
stdout, err := build.StdoutPipe()
|
stdout, err := build.StdoutPipe()
|
||||||
stderr, err := build.StderrPipe()
|
stderr, err := build.StderrPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -149,12 +150,13 @@ func (p *Project) command(stop <-chan bool, cmd Command) (string, string) {
|
||||||
done := make(chan error)
|
done := make(chan error)
|
||||||
args := strings.Split(strings.Replace(strings.Replace(cmd.Command, "'", "", -1), "\"", "", -1), " ")
|
args := strings.Split(strings.Replace(strings.Replace(cmd.Command, "'", "", -1), "\"", "", -1), " ")
|
||||||
exec := exec.Command(args[0], args[1:]...)
|
exec := exec.Command(args[0], args[1:]...)
|
||||||
exec.Dir = p.base
|
exec.Dir = p.Path
|
||||||
|
// make cmd path
|
||||||
if cmd.Path != "" {
|
if cmd.Path != "" {
|
||||||
if strings.Contains(cmd.Path, p.base) {
|
if strings.Contains(cmd.Path, p.Path) {
|
||||||
exec.Dir = cmd.Path
|
exec.Dir = cmd.Path
|
||||||
} else {
|
} else {
|
||||||
exec.Dir = filepath.Join(p.base, cmd.Path)
|
exec.Dir = filepath.Join(p.Path, cmd.Path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exec.Stdout = &stdout
|
exec.Stdout = &stdout
|
||||||
|
@ -187,7 +189,7 @@ func (p *Project) goTool(wg *sync.WaitGroup, stop <-chan bool, result chan<- too
|
||||||
if strings.HasSuffix(path, ".go") || strings.HasSuffix(path, "") {
|
if strings.HasSuffix(path, ".go") || strings.HasSuffix(path, "") {
|
||||||
if strings.HasSuffix(path, ".go") {
|
if strings.HasSuffix(path, ".go") {
|
||||||
tool.options = append(tool.options, path)
|
tool.options = append(tool.options, path)
|
||||||
path = p.base
|
path = p.Path
|
||||||
}
|
}
|
||||||
if s := ext(path); s == "" || s == "go" {
|
if s := ext(path); s == "" || s == "go" {
|
||||||
var out, stderr bytes.Buffer
|
var out, stderr bytes.Buffer
|
||||||
|
|
49
realize.go
49
realize.go
|
@ -5,15 +5,17 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/tockins/interact"
|
"github.com/tockins/interact"
|
||||||
|
"go/build"
|
||||||
"gopkg.in/urfave/cli.v2"
|
"gopkg.in/urfave/cli.v2"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
version = "1.5.0"
|
version = "1.5.1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// New realize instance
|
// New realize instance
|
||||||
|
@ -52,7 +54,7 @@ func main() {
|
||||||
Aliases: []string{"r"},
|
Aliases: []string{"r"},
|
||||||
Description: "Start a toolchain on a project or a list of projects. If not exist a config file it creates a new one",
|
Description: "Start a toolchain on a project or a list of projects. If not exist a config file it creates a new one",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{Name: "path", Aliases: []string{"p"}, Value: "", Usage: "Project base path"},
|
&cli.StringFlag{Name: "path", Aliases: []string{"p"}, Value: wdir(), Usage: "Project base path"},
|
||||||
&cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: "", Usage: "Run a project by its name"},
|
&cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: "", Usage: "Run a project by its name"},
|
||||||
&cli.BoolFlag{Name: "fmt", Aliases: []string{"f"}, Value: false, Usage: "Enable go fmt"},
|
&cli.BoolFlag{Name: "fmt", Aliases: []string{"f"}, Value: false, Usage: "Enable go fmt"},
|
||||||
&cli.BoolFlag{Name: "vet", Aliases: []string{"v"}, Value: false, Usage: "Enable go vet"},
|
&cli.BoolFlag{Name: "vet", Aliases: []string{"v"}, Value: false, Usage: "Enable go vet"},
|
||||||
|
@ -68,7 +70,7 @@ func main() {
|
||||||
if err := r.insert(p); err != nil {
|
if err := r.insert(p); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !p.Bool("no-config") {
|
if !p.Bool("no-config") && p.String("name") == ""{
|
||||||
if err := r.Settings.record(r); err != nil {
|
if err := r.Settings.record(r); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -86,7 +88,7 @@ func main() {
|
||||||
Aliases: []string{"a"},
|
Aliases: []string{"a"},
|
||||||
Description: "Add a project to an existing config file or create a new one",
|
Description: "Add a project to an existing config file or create a new one",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{Name: "path", Aliases: []string{"p"}, Value: "", Usage: "Project base path"},
|
&cli.StringFlag{Name: "path", Aliases: []string{"p"}, Value: wdir(), Usage: "Project base path"},
|
||||||
&cli.BoolFlag{Name: "fmt", Aliases: []string{"f"}, Value: false, Usage: "Enable go fmt"},
|
&cli.BoolFlag{Name: "fmt", Aliases: []string{"f"}, Value: false, Usage: "Enable go fmt"},
|
||||||
&cli.BoolFlag{Name: "vet", Aliases: []string{"v"}, Value: false, Usage: "Enable go vet"},
|
&cli.BoolFlag{Name: "vet", Aliases: []string{"v"}, Value: false, Usage: "Enable go vet"},
|
||||||
&cli.BoolFlag{Name: "test", Aliases: []string{"t"}, Value: false, Usage: "Enable go test"},
|
&cli.BoolFlag{Name: "test", Aliases: []string{"t"}, Value: false, Usage: "Enable go test"},
|
||||||
|
@ -102,7 +104,7 @@ func main() {
|
||||||
if err := r.Settings.record(r); err != nil {
|
if err := r.Settings.record(r); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintln(output, prefix(green.bold("Your project was successfully added")))
|
log.Println(prefix(green.bold("Your project was successfully added")))
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Before: before,
|
Before: before,
|
||||||
|
@ -110,13 +112,13 @@ func main() {
|
||||||
{
|
{
|
||||||
Name: "init",
|
Name: "init",
|
||||||
Category: "Configuration",
|
Category: "Configuration",
|
||||||
Aliases: []string{"a"},
|
Aliases: []string{"i"},
|
||||||
Description: "Define a new config file with all options step by step",
|
Description: "Define a new config file with all options step by step",
|
||||||
Action: func(p *cli.Context) (actErr error) {
|
Action: func(p *cli.Context) (actErr error) {
|
||||||
interact.Run(&interact.Interact{
|
interact.Run(&interact.Interact{
|
||||||
Before: func(context interact.Context) error {
|
Before: func(context interact.Context) error {
|
||||||
context.SetErr(red.bold("INVALID INPUT"))
|
context.SetErr(red.bold("INVALID INPUT"))
|
||||||
context.SetPrfx(color.Output, yellow.bold("[")+"REALIZE"+yellow.bold("]"))
|
context.SetPrfx(color.Output, yellow.regular("[") + time.Now().Format("15:04:05") + yellow.regular("]") + yellow.bold("[")+"REALIZE"+yellow.bold("]"))
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Questions: []*interact.Question{
|
Questions: []*interact.Question{
|
||||||
|
@ -343,7 +345,7 @@ func main() {
|
||||||
Subs: []*interact.Question{
|
Subs: []*interact.Question{
|
||||||
{
|
{
|
||||||
Before: func(d interact.Context) error {
|
Before: func(d interact.Context) error {
|
||||||
d.SetDef(r.Settings.wdir(), green.regular("("+r.Settings.wdir()+")"))
|
d.SetDef(wdir(), green.regular("("+wdir()+")"))
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Quest: interact.Quest{
|
Quest: interact.Quest{
|
||||||
|
@ -361,7 +363,7 @@ func main() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Before: func(d interact.Context) error {
|
Before: func(d interact.Context) error {
|
||||||
dir, _ := os.Getwd()
|
dir := wdir()
|
||||||
d.SetDef(dir, green.regular("("+dir+")"))
|
d.SetDef(dir, green.regular("("+dir+")"))
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -374,7 +376,7 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return d.Err()
|
return d.Err()
|
||||||
}
|
}
|
||||||
r.Schema[len(r.Schema)-1].Path = r.Settings.path(val)
|
r.Schema[len(r.Schema)-1].Path = filepath.Clean(val)
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1045,7 +1047,7 @@ func main() {
|
||||||
if err := r.Settings.record(r); err != nil {
|
if err := r.Settings.record(r); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintln(output, prefix(green.bold(" Your configuration was successful")))
|
log.Println(prefix(green.bold("Your configuration was successful")))
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Before: before,
|
Before: before,
|
||||||
|
@ -1065,7 +1067,7 @@ func main() {
|
||||||
if err := r.Settings.record(r); err != nil {
|
if err := r.Settings.record(r); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintln(output, prefix(green.bold("Your project was successfully removed")))
|
log.Println(prefix(green.bold("Your project was successfully removed")))
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Before: before,
|
Before: before,
|
||||||
|
@ -1079,7 +1081,17 @@ func main() {
|
||||||
if err := r.Settings.del(directory); err != nil {
|
if err := r.Settings.del(directory); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintln(output, prefix(green.bold("Realize folder successfully removed")))
|
log.Println(prefix(green.bold("Realize folder successfully removed")))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Before: before,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "version",
|
||||||
|
Aliases: []string{"v"},
|
||||||
|
Description: "Realize version",
|
||||||
|
Action: func(p *cli.Context) error {
|
||||||
|
log.Println(prefix(green.bold(version)))
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Before: before,
|
Before: before,
|
||||||
|
@ -1087,7 +1099,7 @@ func main() {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if err := app.Run(os.Args); err != nil {
|
if err := app.Run(os.Args); err != nil {
|
||||||
fmt.Fprintln(output, prefix(red.bold(err)))
|
log.Println(prefix(red.bold(err)))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1115,7 +1127,7 @@ func new() realize {
|
||||||
// Prefix a given string
|
// Prefix a given string
|
||||||
func prefix(s string) string {
|
func prefix(s string) string {
|
||||||
if s != "" {
|
if s != "" {
|
||||||
return fmt.Sprint(yellow.bold("["), "REALIZE", yellow.bold("]"), s)
|
return fmt.Sprint(yellow.bold("["), "REALIZE", yellow.bold("]"), " : ", s)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -1126,10 +1138,13 @@ func before(*cli.Context) error {
|
||||||
log.SetFlags(0)
|
log.SetFlags(0)
|
||||||
log.SetOutput(logWriter{})
|
log.SetOutput(logWriter{})
|
||||||
// Before of every exec of a cli method
|
// Before of every exec of a cli method
|
||||||
gopath := os.Getenv("GOPATH")
|
gopath := build.Default.GOPATH
|
||||||
if gopath == "" {
|
if gopath == "" {
|
||||||
return errors.New("$GOPATH isn't set properly")
|
return errors.New("$GOPATH isn't set properly")
|
||||||
}
|
}
|
||||||
|
if err := os.Setenv("GOPATH", gopath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
// new realize instance
|
// new realize instance
|
||||||
r = new()
|
r = new()
|
||||||
// read if exist
|
// read if exist
|
||||||
|
@ -1145,5 +1160,5 @@ func before(*cli.Context) error {
|
||||||
|
|
||||||
// Rewrite the layout of the log timestamp
|
// Rewrite the layout of the log timestamp
|
||||||
func (w logWriter) Write(bytes []byte) (int, error) {
|
func (w logWriter) Write(bytes []byte) (int, error) {
|
||||||
return fmt.Fprint(output, yellow.regular("["), time.Now().Format("15:04:05"), yellow.regular("]")+string(bytes))
|
return fmt.Fprint(output, yellow.regular("["), time.Now().Format("15:04:05"), yellow.regular("]"), string(bytes))
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
func TestPrefix(t *testing.T) {
|
func TestPrefix(t *testing.T) {
|
||||||
input := random(10)
|
input := random(10)
|
||||||
value := fmt.Sprint(yellow.bold("[")+"REALIZE"+yellow.bold("]"), input)
|
value := fmt.Sprint(yellow.bold("["), "REALIZE", yellow.bold("]"), " : ", input)
|
||||||
result := prefix(input)
|
result := prefix(input)
|
||||||
if result == "" {
|
if result == "" {
|
||||||
t.Fatal("Expected a string")
|
t.Fatal("Expected a string")
|
||||||
|
@ -28,7 +28,6 @@ func TestBefore(t *testing.T) {
|
||||||
|
|
||||||
func TestNew(t *testing.T) {
|
func TestNew(t *testing.T) {
|
||||||
r := new()
|
r := new()
|
||||||
t.Log(reflect.TypeOf(r).String())
|
|
||||||
if reflect.TypeOf(r).String() != "main.realize" {
|
if reflect.TypeOf(r).String() != "main.realize" {
|
||||||
t.Error("Expected a realize struct")
|
t.Error("Expected a realize struct")
|
||||||
}
|
}
|
||||||
|
|
23
settings.go
23
settings.go
|
@ -7,7 +7,6 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -77,13 +76,6 @@ func random(n int) string {
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wdir return the current working directory
|
|
||||||
func (s Settings) wdir() string {
|
|
||||||
dir, err := os.Getwd()
|
|
||||||
s.validate(err)
|
|
||||||
return filepath.Base(dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 {
|
||||||
var rLimit syscall.Rlimit
|
var rLimit syscall.Rlimit
|
||||||
|
@ -102,11 +94,6 @@ func (s *Settings) del(d string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Path cleaner
|
|
||||||
func (s Settings) path(path string) string {
|
|
||||||
return strings.Replace(filepath.Clean(path), "\\", "/", -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate checks a fatal error
|
// 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 {
|
||||||
|
@ -171,16 +158,6 @@ func (s Settings) write(name string, data []byte) error {
|
||||||
return s.validate(err)
|
return s.validate(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name return the project name or the path of the working dir
|
|
||||||
func (s Settings) name(name string, path string) string {
|
|
||||||
if name == "" && path == "" {
|
|
||||||
return s.wdir()
|
|
||||||
} else if path != "/" {
|
|
||||||
return filepath.Base(path)
|
|
||||||
}
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new file and return its pointer
|
// Create a new file and return its pointer
|
||||||
func (s Settings) create(path string, name string) *os.File {
|
func (s Settings) create(path string, name string) *os.File {
|
||||||
var file string
|
var file string
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -100,18 +99,6 @@ func TestSettings_Record(t *testing.T) {
|
||||||
s.del(filepath.Join(directory, s.file))
|
s.del(filepath.Join(directory, s.file))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSettings_Wdir(t *testing.T) {
|
|
||||||
s := Settings{}
|
|
||||||
expected, err := os.Getwd()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
result := s.wdir()
|
|
||||||
if result != filepath.Base(expected) {
|
|
||||||
t.Error("Expected", filepath.Base(expected), "instead", result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSettings_Validate(t *testing.T) {
|
func TestSettings_Validate(t *testing.T) {
|
||||||
s := Settings{}
|
s := Settings{}
|
||||||
input := errors.New("")
|
input := errors.New("")
|
||||||
|
@ -121,28 +108,7 @@ func TestSettings_Validate(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSettings_Name(t *testing.T) {
|
func TestSettings_Fatal(t *testing.T){
|
||||||
s := Settings{}
|
s := Settings{}
|
||||||
name := random(8)
|
s.fatal(nil,"test")
|
||||||
path := random(5)
|
|
||||||
dir, err := os.Getwd()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
result := s.name(name, path)
|
|
||||||
if result != dir && result != filepath.Base(path) {
|
|
||||||
t.Fatal("Expected", dir, "or", filepath.Base(path), "instead", result)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSettings_Path(t *testing.T) {
|
|
||||||
s := Settings{}
|
|
||||||
path := random(5)
|
|
||||||
expected := strings.Replace(filepath.Clean(path), "\\", "/", -1)
|
|
||||||
result := s.path(path)
|
|
||||||
if result != expected {
|
|
||||||
t.Fatal("Expected", expected, "instead", result)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
20
utils.go
20
utils.go
|
@ -4,19 +4,10 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"gopkg.in/urfave/cli.v2"
|
"gopkg.in/urfave/cli.v2"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// getEnvPath returns the first path found in env or empty string
|
|
||||||
func getEnvPath(env string) string {
|
|
||||||
path := filepath.SplitList(os.Getenv(env))
|
|
||||||
if len(path) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return path[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Array check if a string is in given array
|
// Array check if a string is in given array
|
||||||
func array(str string, list []string) bool {
|
func array(str string, list []string) bool {
|
||||||
for _, v := range list {
|
for _, v := range list {
|
||||||
|
@ -83,3 +74,12 @@ func replace(a []string, b string) []string {
|
||||||
}
|
}
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wdir return current working directory
|
||||||
|
func wdir() string {
|
||||||
|
dir, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(prefix(err.Error()))
|
||||||
|
}
|
||||||
|
return dir
|
||||||
|
}
|
||||||
|
|
|
@ -53,10 +53,13 @@ func TestInArray(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetEnvPath(t *testing.T) {
|
func TestWdir(t *testing.T) {
|
||||||
expected := filepath.SplitList(os.Getenv("GOPATH"))[0]
|
expected, err := os.Getwd()
|
||||||
result := getEnvPath("GOPATH")
|
if err != nil {
|
||||||
if expected != result {
|
t.Error(err)
|
||||||
t.Fatal("Expected", expected, "instead", result)
|
}
|
||||||
|
result := wdir()
|
||||||
|
if result != expected {
|
||||||
|
t.Error("Expected", filepath.Base(expected), "instead", result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
watcher.go
15
watcher.go
|
@ -55,7 +55,7 @@ type Project struct {
|
||||||
watcher FileWatcher
|
watcher FileWatcher
|
||||||
init bool
|
init bool
|
||||||
files, folders int64
|
files, folders int64
|
||||||
base, path, lastFile string
|
name, lastFile string
|
||||||
tools []tool
|
tools []tool
|
||||||
paths []string
|
paths []string
|
||||||
lastTime time.Time
|
lastTime time.Time
|
||||||
|
@ -98,7 +98,7 @@ func (p *Project) watch() {
|
||||||
p.cmd(stop, "before", true)
|
p.cmd(stop, "before", true)
|
||||||
// indexing files and dirs
|
// indexing files and dirs
|
||||||
for _, dir := range p.Watcher.Paths {
|
for _, dir := range p.Watcher.Paths {
|
||||||
base := filepath.Join(p.base, dir)
|
base := filepath.Join(p.Path, dir)
|
||||||
if _, err := os.Stat(base); err == nil {
|
if _, err := os.Stat(base); err == nil {
|
||||||
if err := filepath.Walk(base, p.walk); err == nil {
|
if err := filepath.Walk(base, p.walk); err == nil {
|
||||||
p.tool(stop, base)
|
p.tool(stop, base)
|
||||||
|
@ -312,7 +312,8 @@ func (p *Project) changed(event fsnotify.Event, stop chan bool) {
|
||||||
// Watch the files tree of a project
|
// Watch the files tree of a project
|
||||||
func (p *Project) walk(path string, info os.FileInfo, err error) error {
|
func (p *Project) walk(path string, info os.FileInfo, err error) error {
|
||||||
for _, v := range p.Watcher.Ignore {
|
for _, v := range p.Watcher.Ignore {
|
||||||
if strings.Contains(path, filepath.Join(p.base, v)) {
|
s := append([]string{p.Path},strings.Split(v,string(os.PathSeparator))...)
|
||||||
|
if strings.Contains(path, filepath.Join(s...)) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -338,7 +339,7 @@ func (p *Project) stamp(t string, o BufferOut, msg string, stream string) {
|
||||||
case "out":
|
case "out":
|
||||||
p.Buffer.StdOut = append(p.Buffer.StdOut, o)
|
p.Buffer.StdOut = append(p.Buffer.StdOut, o)
|
||||||
if p.Files.Outputs.Status {
|
if p.Files.Outputs.Status {
|
||||||
f := p.create(p.base, p.Files.Outputs.Name)
|
f := p.create(p.Path, p.Files.Outputs.Name)
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
s := []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Text, "\r\n"}
|
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 {
|
if _, err := f.WriteString(strings.Join(s, " ")); err != nil {
|
||||||
|
@ -348,7 +349,7 @@ func (p *Project) stamp(t string, o BufferOut, msg string, stream string) {
|
||||||
case "log":
|
case "log":
|
||||||
p.Buffer.StdLog = append(p.Buffer.StdLog, o)
|
p.Buffer.StdLog = append(p.Buffer.StdLog, o)
|
||||||
if p.Files.Logs.Status {
|
if p.Files.Logs.Status {
|
||||||
f := p.create(p.base, p.Files.Logs.Name)
|
f := p.create(p.Path, p.Files.Logs.Name)
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
s := []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Text, "\r\n"}
|
s := []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Text, "\r\n"}
|
||||||
if stream != "" {
|
if stream != "" {
|
||||||
|
@ -361,7 +362,7 @@ func (p *Project) stamp(t string, o BufferOut, msg string, stream string) {
|
||||||
case "error":
|
case "error":
|
||||||
p.Buffer.StdErr = append(p.Buffer.StdErr, o)
|
p.Buffer.StdErr = append(p.Buffer.StdErr, o)
|
||||||
if p.Files.Errors.Status {
|
if p.Files.Errors.Status {
|
||||||
f := p.create(p.base, p.Files.Errors.Name)
|
f := p.create(p.Path, p.Files.Errors.Name)
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
s := []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Type, o.Text, o.Path, "\r\n"}
|
s := []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Type, o.Text, o.Path, "\r\n"}
|
||||||
if stream != "" {
|
if stream != "" {
|
||||||
|
@ -407,7 +408,7 @@ func (p *Project) routines(stop <-chan bool, watcher FileWatcher, path string) {
|
||||||
p.init = true
|
p.init = true
|
||||||
}
|
}
|
||||||
// prevent errors using realize without config with only run flag
|
// prevent errors using realize without config with only run flag
|
||||||
if !p.Cmds.Install.Status && !p.Cmds.Build.Status {
|
if p.Cmds.Run && !p.Cmds.Install.Status && !p.Cmds.Build.Status {
|
||||||
p.Cmds.Install.Status = true
|
p.Cmds.Install.Status = true
|
||||||
}
|
}
|
||||||
if !done {
|
if !done {
|
||||||
|
|
|
@ -29,7 +29,7 @@ func TestWalk(t *testing.T) {
|
||||||
Ignore: []string{"vendor"},
|
Ignore: []string{"vendor"},
|
||||||
Exts: []string{"go"},
|
Exts: []string{"go"},
|
||||||
},
|
},
|
||||||
base: "/go/project",
|
Path: "/go/project",
|
||||||
watcher: &fileWatcherMock{},
|
watcher: &fileWatcherMock{},
|
||||||
init: true,
|
init: true,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue