commit
13ee93c5f7
41
realize.go
41
realize.go
|
@ -38,6 +38,7 @@ func main() {
|
||||||
&cli.BoolFlag{Name: "install", Aliases: []string{"i"}, Value: false, Usage: "Enable go install"},
|
&cli.BoolFlag{Name: "install", Aliases: []string{"i"}, Value: false, Usage: "Enable go install"},
|
||||||
&cli.BoolFlag{Name: "build", Aliases: []string{"b"}, Value: false, Usage: "Enable go build"},
|
&cli.BoolFlag{Name: "build", Aliases: []string{"b"}, Value: false, Usage: "Enable go build"},
|
||||||
&cli.BoolFlag{Name: "run", Aliases: []string{"nr"}, Value: false, Usage: "Enable go run"},
|
&cli.BoolFlag{Name: "run", Aliases: []string{"nr"}, Value: false, Usage: "Enable go run"},
|
||||||
|
&cli.BoolFlag{Name: "legacy", Aliases: []string{"l"}, Value: false, Usage: "Legacy watch by polling instead fsnotify"},
|
||||||
&cli.BoolFlag{Name: "no-config", Aliases: []string{"nc"}, Value: false, Usage: "Ignore existing config and doesn't create a new one"},
|
&cli.BoolFlag{Name: "no-config", Aliases: []string{"nc"}, Value: false, Usage: "Ignore existing config and doesn't create a new one"},
|
||||||
},
|
},
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
|
@ -794,7 +795,7 @@ func setup(c *cli.Context) (err error) {
|
||||||
Resolve: func(d interact.Context) bool {
|
Resolve: func(d interact.Context) bool {
|
||||||
val, _ := d.Ans().Bool()
|
val, _ := d.Ans().Bool()
|
||||||
if val {
|
if val {
|
||||||
r.Schema.Projects[len(r.Schema.Projects)-1].Watcher.Ignore = r.Schema.Projects[len(r.Schema.Projects)-1].Watcher.Ignore[:len(r.Schema.Projects[len(r.Schema.Projects)-1].Watcher.Ignore)-1]
|
r.Schema.Projects[len(r.Schema.Projects)-1].Watcher.Ignore.Paths = r.Schema.Projects[len(r.Schema.Projects)-1].Watcher.Ignore.Paths[:len(r.Schema.Projects[len(r.Schema.Projects)-1].Watcher.Ignore.Paths)-1]
|
||||||
}
|
}
|
||||||
return val
|
return val
|
||||||
},
|
},
|
||||||
|
@ -814,7 +815,7 @@ func setup(c *cli.Context) (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return d.Err()
|
return d.Err()
|
||||||
}
|
}
|
||||||
r.Schema.Projects[len(r.Schema.Projects)-1].Watcher.Ignore = append(r.Schema.Projects[len(r.Schema.Projects)-1].Watcher.Ignore, val)
|
r.Schema.Projects[len(r.Schema.Projects)-1].Watcher.Ignore.Paths = append(r.Schema.Projects[len(r.Schema.Projects)-1].Watcher.Ignore.Paths, val)
|
||||||
d.Reload()
|
d.Reload()
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -1080,7 +1081,7 @@ func setup(c *cli.Context) (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return d.Err()
|
return d.Err()
|
||||||
}
|
}
|
||||||
r.Schema.Projects[len(r.Schema.Projects)-1].ErrorOutputPattern = val
|
r.Schema.Projects[len(r.Schema.Projects)-1].ErrPattern = val
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1116,7 +1117,14 @@ func setup(c *cli.Context) (err error) {
|
||||||
|
|
||||||
// Start realize workflow
|
// Start realize workflow
|
||||||
func start(c *cli.Context) (err error) {
|
func start(c *cli.Context) (err error) {
|
||||||
r.Server = realize.Server{Parent: &r, Status: false, Open: false, Port: realize.Port, Host: realize.Host}
|
// set legacy watcher
|
||||||
|
if c.Bool("legacy") {
|
||||||
|
r.Settings.Legacy.Set(c.Bool("legacy"), 1)
|
||||||
|
}
|
||||||
|
// set server
|
||||||
|
if c.Bool("server") {
|
||||||
|
r.Server.Set(c.Bool("server"), c.Bool("open"), realize.Port, realize.Host)
|
||||||
|
}
|
||||||
// check no-config and read
|
// check no-config and read
|
||||||
if !c.Bool("no-config") {
|
if !c.Bool("no-config") {
|
||||||
// read a config if exist
|
// read a config if exist
|
||||||
|
@ -1133,20 +1141,9 @@ func start(c *cli.Context) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// config and start server
|
|
||||||
if c.Bool("server") || r.Server.Status {
|
|
||||||
r.Server.Status = true
|
|
||||||
if c.Bool("open") || r.Server.Open {
|
|
||||||
r.Server.Open = true
|
|
||||||
r.Server.OpenURL()
|
|
||||||
}
|
|
||||||
err = r.Server.Start()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// check project list length
|
// check project list length
|
||||||
if len(r.Schema.Projects) <= 0 {
|
if len(r.Schema.Projects) <= 0 {
|
||||||
|
println("len", r.Schema.Projects)
|
||||||
// create a new project based on given params
|
// create a new project based on given params
|
||||||
project := r.Schema.New(c)
|
project := r.Schema.New(c)
|
||||||
// Add to projects list
|
// Add to projects list
|
||||||
|
@ -1159,6 +1156,18 @@ func start(c *cli.Context) (err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Start web server
|
||||||
|
if r.Server.Status {
|
||||||
|
r.Server.Parent = &r
|
||||||
|
err = r.Server.Start()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = r.Server.OpenURL()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
// start workflow
|
// start workflow
|
||||||
return r.Start()
|
return r.Start()
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ var (
|
||||||
// RPrefix tool name
|
// RPrefix tool name
|
||||||
RPrefix = "realize"
|
RPrefix = "realize"
|
||||||
// RVersion current version
|
// RVersion current version
|
||||||
RVersion = "2.0.1"
|
RVersion = "2.1"
|
||||||
// RExt file extension
|
// RExt file extension
|
||||||
RExt = ".yaml"
|
RExt = ".yaml"
|
||||||
// RFile config file name
|
// RFile config file name
|
||||||
|
@ -34,7 +34,7 @@ type (
|
||||||
// Realize main struct
|
// Realize main struct
|
||||||
Realize struct {
|
Realize struct {
|
||||||
Settings Settings `yaml:"settings" json:"settings"`
|
Settings Settings `yaml:"settings" json:"settings"`
|
||||||
Server Server `yaml:"server" json:"server"`
|
Server Server `yaml:"server,omitempty" json:"server,omitempty"`
|
||||||
Schema `yaml:",inline" json:",inline"`
|
Schema `yaml:",inline" json:",inline"`
|
||||||
Sync chan string `yaml:"-" json:"-"`
|
Sync chan string `yaml:"-" json:"-"`
|
||||||
Err Func `yaml:"-" json:"-"`
|
Err Func `yaml:"-" json:"-"`
|
||||||
|
|
|
@ -2,7 +2,7 @@ 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
|
||||||
// i have just added only walk methods and some little changes to polling interval, originally set as static.
|
// i have just added only the walk methods and some little changes to polling interval, originally set as static.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -57,7 +57,7 @@ type (
|
||||||
// PollingWatcher returns a poll-based file watcher
|
// PollingWatcher returns a poll-based file watcher
|
||||||
func PollingWatcher(interval time.Duration) FileWatcher {
|
func PollingWatcher(interval time.Duration) FileWatcher {
|
||||||
if interval == 0 {
|
if interval == 0 {
|
||||||
interval = 100 * time.Millisecond
|
interval = time.Duration(1) * time.Second
|
||||||
}
|
}
|
||||||
return &filePoller{
|
return &filePoller{
|
||||||
interval: interval,
|
interval: interval,
|
||||||
|
@ -67,13 +67,13 @@ func PollingWatcher(interval time.Duration) FileWatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFileWatcher tries to use an fs-event watcher, and falls back to the poller if there is an error
|
// NewFileWatcher tries to use an fs-event watcher, and falls back to the poller if there is an error
|
||||||
func NewFileWatcher(force bool, interval time.Duration) (FileWatcher, error) {
|
func NewFileWatcher(l Legacy) (FileWatcher, error) {
|
||||||
if !force {
|
if !l.Force {
|
||||||
if w, err := EventWatcher(); err == nil {
|
if w, err := EventWatcher(); err == nil {
|
||||||
return w, nil
|
return w, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PollingWatcher(interval), nil
|
return PollingWatcher(l.Interval), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EventWatcher returns an fs-event based file watcher
|
// EventWatcher returns an fs-event based file watcher
|
||||||
|
|
|
@ -26,17 +26,22 @@ var (
|
||||||
|
|
||||||
// Watch info
|
// Watch info
|
||||||
type Watch struct {
|
type Watch struct {
|
||||||
Paths []string `yaml:"paths" json:"paths"`
|
|
||||||
Exts []string `yaml:"extensions" json:"extensions"`
|
Exts []string `yaml:"extensions" json:"extensions"`
|
||||||
Ignore []string `yaml:"ignored_paths,omitempty" json:"ignored_paths,omitempty"`
|
Paths []string `yaml:"paths" json:"paths"`
|
||||||
Scripts []Command `yaml:"scripts,omitempty" json:"scripts,omitempty"`
|
Scripts []Command `yaml:"scripts,omitempty" json:"scripts,omitempty"`
|
||||||
Hidden bool `yaml:"skip_hidden,omitempty" json:"skip_hidden,omitempty"`
|
Hidden bool `yaml:"hidden,omitempty" json:"hidden,omitempty"`
|
||||||
|
Ignore Ignore `yaml:"ignore,omitempty" json:"ignore,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Ignore struct{
|
||||||
|
Exts []string `yaml:"exts,omitempty" json:"exts,omitempty"`
|
||||||
|
Paths []string `yaml:"paths,omitempty" json:"paths,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command fields
|
// Command fields
|
||||||
type Command struct {
|
type Command struct {
|
||||||
Type string `yaml:"type" json:"type"`
|
|
||||||
Cmd string `yaml:"command" json:"command"`
|
Cmd string `yaml:"command" json:"command"`
|
||||||
|
Type string `yaml:"type" json:"type"`
|
||||||
Path string `yaml:"path,omitempty" json:"path,omitempty"`
|
Path string `yaml:"path,omitempty" json:"path,omitempty"`
|
||||||
Global bool `yaml:"global,omitempty" json:"global,omitempty"`
|
Global bool `yaml:"global,omitempty" json:"global,omitempty"`
|
||||||
Output bool `yaml:"output,omitempty" json:"output,omitempty"`
|
Output bool `yaml:"output,omitempty" json:"output,omitempty"`
|
||||||
|
@ -46,21 +51,21 @@ type Command struct {
|
||||||
type Project struct {
|
type Project struct {
|
||||||
parent *Realize
|
parent *Realize
|
||||||
watcher FileWatcher
|
watcher FileWatcher
|
||||||
init bool
|
|
||||||
exit chan os.Signal
|
|
||||||
stop chan bool
|
stop chan bool
|
||||||
|
exit chan os.Signal
|
||||||
|
paths []string
|
||||||
|
last last
|
||||||
files int64
|
files int64
|
||||||
folders int64
|
folders int64
|
||||||
last last
|
init bool
|
||||||
paths []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"`
|
||||||
Environment map[string]string `yaml:"environment,omitempty" json:"environment,omitempty"`
|
Env map[string]string `yaml:"env,omitempty" json:"env,omitempty"`
|
||||||
Tools Tools `yaml:"commands" json:"commands"`
|
|
||||||
Args []string `yaml:"args,omitempty" json:"args,omitempty"`
|
Args []string `yaml:"args,omitempty" json:"args,omitempty"`
|
||||||
|
Tools Tools `yaml:"commands" json:"commands"`
|
||||||
Watcher Watch `yaml:"watcher" json:"watcher"`
|
Watcher Watch `yaml:"watcher" json:"watcher"`
|
||||||
Buffer Buffer `yaml:"-" json:"buffer"`
|
Buffer Buffer `yaml:"-" json:"buffer"`
|
||||||
ErrorOutputPattern string `yaml:"errorOutputPattern,omitempty" json:"errorOutputPattern,omitempty"`
|
ErrPattern string `yaml:"pattern,omitempty" json:"pattern,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last is used to save info about last file changed
|
// Last is used to save info about last file changed
|
||||||
|
@ -111,7 +116,7 @@ func (p *Project) Before() {
|
||||||
// setup go tools
|
// setup go tools
|
||||||
p.Tools.Setup()
|
p.Tools.Setup()
|
||||||
// set env const
|
// set env const
|
||||||
for key, item := range p.Environment {
|
for key, item := range p.Env {
|
||||||
if err := os.Setenv(key, item); err != nil {
|
if err := os.Setenv(key, item); err != nil {
|
||||||
p.Buffer.StdErr = append(p.Buffer.StdErr, BufferOut{Time: time.Now(), Text: err.Error(), Type: "Env error", Stream: ""})
|
p.Buffer.StdErr = append(p.Buffer.StdErr, BufferOut{Time: time.Now(), Text: err.Error(), Type: "Env error", Stream: ""})
|
||||||
}
|
}
|
||||||
|
@ -191,7 +196,7 @@ func (p *Project) Reload(path string, stop <-chan bool) {
|
||||||
}
|
}
|
||||||
// Go supported tools
|
// Go supported tools
|
||||||
if len(path) > 0 {
|
if len(path) > 0 {
|
||||||
fi, err := os.Stat(filepath.Dir(path))
|
fi, err := os.Stat(path)
|
||||||
if filepath.Ext(path) == "" {
|
if filepath.Ext(path) == "" {
|
||||||
fi, err = os.Stat(path)
|
fi, err = os.Stat(path)
|
||||||
}
|
}
|
||||||
|
@ -274,7 +279,7 @@ func (p *Project) Watch(wg *sync.WaitGroup) {
|
||||||
// change channel
|
// change channel
|
||||||
p.stop = make(chan bool)
|
p.stop = make(chan bool)
|
||||||
// init a new watcher
|
// init a new watcher
|
||||||
p.watcher, err = NewFileWatcher(p.parent.Settings.Legacy.Force, p.parent.Settings.Legacy.Interval)
|
p.watcher, err = NewFileWatcher(p.parent.Settings.Legacy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -347,14 +352,28 @@ func (p *Project) Validate(path string, fcheck bool) bool {
|
||||||
}
|
}
|
||||||
// check for a valid ext or path
|
// check for a valid ext or path
|
||||||
if e := ext(path); e != "" {
|
if e := ext(path); e != "" {
|
||||||
// supported exts
|
if len(p.Watcher.Exts) == 0{
|
||||||
if !array(e, p.Watcher.Exts) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
// check ignored
|
||||||
|
for _, v := range p.Watcher.Ignore.Exts {
|
||||||
|
if v == e {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// supported extensions
|
||||||
|
for index, v := range p.Watcher.Exts{
|
||||||
|
if e == v {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if index == len(p.Watcher.Exts)-1{
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
separator := string(os.PathSeparator)
|
separator := string(os.PathSeparator)
|
||||||
// supported paths
|
// supported paths
|
||||||
for _, v := range p.Watcher.Ignore {
|
for _, v := range p.Watcher.Ignore.Paths {
|
||||||
s := append([]string{p.Path}, strings.Split(v, separator)...)
|
s := append([]string{p.Path}, strings.Split(v, separator)...)
|
||||||
abs, _ := filepath.Abs(filepath.Join(s...))
|
abs, _ := filepath.Abs(filepath.Join(s...))
|
||||||
if path == abs || strings.HasPrefix(path, abs+separator) {
|
if path == abs || strings.HasPrefix(path, abs+separator) {
|
||||||
|
@ -364,16 +383,9 @@ func (p *Project) Validate(path string, fcheck bool) bool {
|
||||||
// file check
|
// file check
|
||||||
if fcheck {
|
if fcheck {
|
||||||
fi, err := os.Stat(path)
|
fi, err := os.Stat(path)
|
||||||
if err != nil {
|
if err != nil || fi.Mode()&os.ModeSymlink != 0 || !fi.IsDir() && ext(path) == "" || fi.Size() <= 0{
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if !fi.IsDir() && ext(path) == "" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if fi.Size() > 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
@ -465,8 +477,8 @@ 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("\""))
|
||||||
if r.Err != nil {
|
if r.Err != nil {
|
||||||
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, msg, fmt.Sprint(Red.Regular(r.Err.Error())))
|
p.stamp("error", out, msg, fmt.Sprint(Red.Regular(r.Err.Error())))
|
||||||
} else {
|
} else {
|
||||||
|
@ -485,9 +497,9 @@ func (p *Project) walk(path string, info os.FileInfo, err error) error {
|
||||||
if p.parent.Settings.Recovery.Index {
|
if p.parent.Settings.Recovery.Index {
|
||||||
log.Println("Indexing", path)
|
log.Println("Indexing", path)
|
||||||
}
|
}
|
||||||
|
p.tools(p.stop, path, info)
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
// tools dir
|
// tools dir
|
||||||
p.tools(p.stop, path, info)
|
|
||||||
p.folders++
|
p.folders++
|
||||||
} else {
|
} else {
|
||||||
// tools files
|
// tools files
|
||||||
|
@ -532,7 +544,7 @@ 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.Fprintln(Output, stream)
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
p.parent.Sync <- "sync"
|
p.parent.Sync <- "sync"
|
||||||
|
@ -547,14 +559,16 @@ func (p *Project) run(path string, stream chan Response, stop <-chan bool) (err
|
||||||
defer func() {
|
defer func() {
|
||||||
// https://github.com/golang/go/issues/5615
|
// https://github.com/golang/go/issues/5615
|
||||||
// https://github.com/golang/go/issues/6720
|
// https://github.com/golang/go/issues/6720
|
||||||
build.Process.Signal(os.Interrupt)
|
if build != nil {
|
||||||
|
build.Process.Signal(os.Interrupt)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// custom error pattern
|
// custom error pattern
|
||||||
isErrorText := func(string) bool {
|
isErrorText := func(string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
errRegexp, err := regexp.Compile(p.ErrorOutputPattern)
|
errRegexp, err := regexp.Compile(p.ErrPattern)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Err = err
|
r.Err = err
|
||||||
stream <- r
|
stream <- r
|
||||||
|
|
|
@ -48,7 +48,7 @@ func TestProject_Before(t *testing.T) {
|
||||||
r = Realize{}
|
r = Realize{}
|
||||||
r.Projects = append(r.Projects, Project{
|
r.Projects = append(r.Projects, Project{
|
||||||
parent: &r,
|
parent: &r,
|
||||||
Environment: map[string]string{
|
Env: map[string]string{
|
||||||
input: input,
|
input: input,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -100,7 +100,9 @@ func TestProject_Reload(t *testing.T) {
|
||||||
parent: &r,
|
parent: &r,
|
||||||
})
|
})
|
||||||
input := "test/path"
|
input := "test/path"
|
||||||
r.Projects[0].watcher, _ = NewFileWatcher(false, 0)
|
r.Settings.Legacy.Force = false
|
||||||
|
r.Settings.Legacy.Interval = 0
|
||||||
|
r.Projects[0].watcher, _ = NewFileWatcher(r.Settings.Legacy)
|
||||||
r.Reload = func(context Context) {
|
r.Reload = func(context Context) {
|
||||||
log.Println(context.Path)
|
log.Println(context.Path)
|
||||||
}
|
}
|
||||||
|
@ -126,12 +128,16 @@ func TestProject_Validate(t *testing.T) {
|
||||||
r.Projects = append(r.Projects, Project{
|
r.Projects = append(r.Projects, Project{
|
||||||
parent: &r,
|
parent: &r,
|
||||||
Watcher: Watch{
|
Watcher: Watch{
|
||||||
Ignore: []string{"/test/ignore"},
|
Exts: []string{},
|
||||||
|
Ignore: Ignore{
|
||||||
|
Paths:[]string{"/test/ignore"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
for i, v := range data {
|
for i, v := range data {
|
||||||
if r.Projects[0].Validate(i, false) != v {
|
result := r.Projects[0].Validate(i, false)
|
||||||
t.Error("Unexpected error", i, "expected", v)
|
if result != v {
|
||||||
|
t.Error("Unexpected error", i, "expected", v, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,9 @@ func (s *Schema) New(c *cli.Context) Project {
|
||||||
Args: params(c),
|
Args: params(c),
|
||||||
Watcher: Watch{
|
Watcher: Watch{
|
||||||
Paths: []string{"/"},
|
Paths: []string{"/"},
|
||||||
Ignore: []string{".git", ".realize", "vendor"},
|
Ignore: Ignore{
|
||||||
|
Paths:[]string{".git", ".realize", "vendor"},
|
||||||
|
},
|
||||||
Exts: []string{"go"},
|
Exts: []string{"go"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,12 @@ import (
|
||||||
"github.com/labstack/echo"
|
"github.com/labstack/echo"
|
||||||
"github.com/labstack/echo/middleware"
|
"github.com/labstack/echo/middleware"
|
||||||
"golang.org/x/net/websocket"
|
"golang.org/x/net/websocket"
|
||||||
"io"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"github.com/go-siris/siris/core/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Dafault host and port
|
// Dafault host and port
|
||||||
|
@ -98,65 +98,74 @@ func (s *Server) render(c echo.Context, path string, mime int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) Set(status bool, open bool, port int, host string) {
|
||||||
|
s.Open = open
|
||||||
|
s.Port = port
|
||||||
|
s.Host = host
|
||||||
|
s.Status = status
|
||||||
|
}
|
||||||
|
|
||||||
// Start the web server
|
// Start the web server
|
||||||
func (s *Server) Start() (err error) {
|
func (s *Server) Start() (err error) {
|
||||||
e := echo.New()
|
if s.Status {
|
||||||
e.Use(middleware.GzipWithConfig(middleware.GzipConfig{
|
e := echo.New()
|
||||||
Level: 2,
|
e.Use(middleware.GzipWithConfig(middleware.GzipConfig{
|
||||||
}))
|
Level: 2,
|
||||||
e.Use(middleware.Recover())
|
}))
|
||||||
|
e.Use(middleware.Recover())
|
||||||
|
|
||||||
// web panel
|
// web panel
|
||||||
e.GET("/", func(c echo.Context) error {
|
e.GET("/", func(c echo.Context) error {
|
||||||
return s.render(c, "assets/index.html", 1)
|
return s.render(c, "assets/index.html", 1)
|
||||||
})
|
})
|
||||||
e.GET("/assets/js/all.min.js", func(c echo.Context) error {
|
e.GET("/assets/js/all.min.js", func(c echo.Context) error {
|
||||||
return s.render(c, "assets/assets/js/all.min.js", 2)
|
return s.render(c, "assets/assets/js/all.min.js", 2)
|
||||||
})
|
})
|
||||||
e.GET("/assets/css/app.css", func(c echo.Context) error {
|
e.GET("/assets/css/app.css", func(c echo.Context) error {
|
||||||
return s.render(c, "assets/assets/css/app.css", 3)
|
return s.render(c, "assets/assets/css/app.css", 3)
|
||||||
})
|
})
|
||||||
e.GET("/app/components/settings/index.html", func(c echo.Context) error {
|
e.GET("/app/components/settings/index.html", func(c echo.Context) error {
|
||||||
return s.render(c, "assets/app/components/settings/index.html", 1)
|
return s.render(c, "assets/app/components/settings/index.html", 1)
|
||||||
})
|
})
|
||||||
e.GET("/app/components/project/index.html", func(c echo.Context) error {
|
e.GET("/app/components/project/index.html", func(c echo.Context) error {
|
||||||
return s.render(c, "assets/app/components/project/index.html", 1)
|
return s.render(c, "assets/app/components/project/index.html", 1)
|
||||||
})
|
})
|
||||||
e.GET("/app/components/index.html", func(c echo.Context) error {
|
e.GET("/app/components/index.html", func(c echo.Context) error {
|
||||||
return s.render(c, "assets/app/components/index.html", 1)
|
return s.render(c, "assets/app/components/index.html", 1)
|
||||||
})
|
})
|
||||||
e.GET("/assets/img/logo.png", func(c echo.Context) error {
|
e.GET("/assets/img/logo.png", func(c echo.Context) error {
|
||||||
return s.render(c, "assets/assets/img/logo.png", 5)
|
return s.render(c, "assets/assets/img/logo.png", 5)
|
||||||
})
|
})
|
||||||
e.GET("/assets/img/svg/github-logo.svg", func(c echo.Context) error {
|
e.GET("/assets/img/svg/github-logo.svg", func(c echo.Context) error {
|
||||||
return s.render(c, "assets/assets/img/svg/github-logo.svg", 4)
|
return s.render(c, "assets/assets/img/svg/github-logo.svg", 4)
|
||||||
})
|
})
|
||||||
e.GET("/assets/img/svg/ic_arrow_back_black_48px.svg", func(c echo.Context) error {
|
e.GET("/assets/img/svg/ic_arrow_back_black_48px.svg", func(c echo.Context) error {
|
||||||
return s.render(c, "assets/assets/img/svg/ic_arrow_back_black_48px.svg", 4)
|
return s.render(c, "assets/assets/img/svg/ic_arrow_back_black_48px.svg", 4)
|
||||||
})
|
})
|
||||||
e.GET("/assets/img/svg/ic_clear_white_48px.svg", func(c echo.Context) error {
|
e.GET("/assets/img/svg/ic_clear_white_48px.svg", func(c echo.Context) error {
|
||||||
return s.render(c, "assets/assets/img/svg/ic_clear_white_48px.svg", 4)
|
return s.render(c, "assets/assets/img/svg/ic_clear_white_48px.svg", 4)
|
||||||
})
|
})
|
||||||
e.GET("/assets/img/svg/ic_menu_white_48px.svg", func(c echo.Context) error {
|
e.GET("/assets/img/svg/ic_menu_white_48px.svg", func(c echo.Context) error {
|
||||||
return s.render(c, "assets/assets/img/svg/ic_menu_white_48px.svg", 4)
|
return s.render(c, "assets/assets/img/svg/ic_menu_white_48px.svg", 4)
|
||||||
})
|
})
|
||||||
e.GET("/assets/img/svg/ic_settings_black_48px.svg", func(c echo.Context) error {
|
e.GET("/assets/img/svg/ic_settings_black_48px.svg", func(c echo.Context) error {
|
||||||
return s.render(c, "assets/assets/img/svg/ic_settings_black_48px.svg", 4)
|
return s.render(c, "assets/assets/img/svg/ic_settings_black_48px.svg", 4)
|
||||||
})
|
})
|
||||||
|
|
||||||
//websocket
|
//websocket
|
||||||
e.GET("/ws", s.projects)
|
e.GET("/ws", s.projects)
|
||||||
// e.HideBanner = true
|
e.HideBanner = true
|
||||||
e.Debug = false
|
e.Debug = false
|
||||||
go func() {
|
go func() {
|
||||||
log.Println(s.Parent.Prefix("Started on " + string(s.Host) + ":" + strconv.Itoa(s.Port)))
|
log.Println(s.Parent.Prefix("Started on " + string(s.Host) + ":" + strconv.Itoa(s.Port)))
|
||||||
e.Start(string(s.Host) + ":" + strconv.Itoa(s.Port))
|
e.Start(string(s.Host) + ":" + strconv.Itoa(s.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() 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{
|
||||||
|
@ -167,13 +176,13 @@ func (s *Server) OpenURL() (io.Writer, error) {
|
||||||
if s.Open {
|
if s.Open {
|
||||||
open, err := cmd[runtime.GOOS]
|
open, err := cmd[runtime.GOOS]
|
||||||
if !err {
|
if !err {
|
||||||
return nil, fmt.Errorf("operating system %q is not supported", runtime.GOOS)
|
return fmt.Errorf("operating system %q is not supported", runtime.GOOS)
|
||||||
}
|
}
|
||||||
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 errors.New(stderr.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,12 @@ type Resource struct {
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set legacy watcher with an interval
|
||||||
|
func (l *Legacy) Set(status bool, interval int){
|
||||||
|
l.Force = true
|
||||||
|
l.Interval = time.Duration(interval) * time.Second
|
||||||
|
}
|
||||||
|
|
||||||
// Remove realize folder
|
// Remove realize folder
|
||||||
func (s *Settings) Remove(d string) error {
|
func (s *Settings) Remove(d string) error {
|
||||||
_, err := os.Stat(d)
|
_, err := os.Stat(d)
|
||||||
|
|
|
@ -43,7 +43,7 @@ func (t *Tools) Setup() {
|
||||||
if t.Clean.Status {
|
if t.Clean.Status {
|
||||||
t.Clean.name = "Clean"
|
t.Clean.name = "Clean"
|
||||||
t.Clean.isTool = true
|
t.Clean.isTool = true
|
||||||
t.Clean.cmd = replace([]string{"go clean"}, t.Clean.Method)
|
t.Clean.cmd = replace([]string{"go", "clean"}, t.Clean.Method)
|
||||||
t.Clean.Args = split([]string{}, t.Clean.Args)
|
t.Clean.Args = split([]string{}, t.Clean.Args)
|
||||||
}
|
}
|
||||||
// go generate
|
// go generate
|
||||||
|
@ -134,7 +134,12 @@ func (t *Tool) Exec(path string, stop <-chan bool) (response Response) {
|
||||||
cmd.Stdout = &out
|
cmd.Stdout = &out
|
||||||
cmd.Stderr = &stderr
|
cmd.Stderr = &stderr
|
||||||
// Start command
|
// Start command
|
||||||
cmd.Start()
|
err := cmd.Start()
|
||||||
|
if err != nil{
|
||||||
|
response.Name = t.name
|
||||||
|
response.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
go func() { done <- cmd.Wait() }()
|
go func() { done <- cmd.Wait() }()
|
||||||
// Wait a result
|
// Wait a result
|
||||||
select {
|
select {
|
||||||
|
@ -145,7 +150,7 @@ func (t *Tool) Exec(path string, stop <-chan bool) (response Response) {
|
||||||
// Command completed
|
// Command completed
|
||||||
response.Name = t.name
|
response.Name = t.name
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.Err = errors.New(stderr.String() + out.String())
|
response.Err = errors.New(stderr.String() + out.String() + err.Error())
|
||||||
} else {
|
} else {
|
||||||
if t.Output {
|
if t.Output {
|
||||||
response.Out = out.String()
|
response.Out = out.String()
|
||||||
|
|
|
@ -8,16 +8,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Array check if a string is in given array
|
|
||||||
func array(str string, list []string) bool {
|
|
||||||
for _, v := range list {
|
|
||||||
if v == str {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Params parse one by one the given argumentes
|
// Params parse one by one the given argumentes
|
||||||
func params(params *cli.Context) []string {
|
func params(params *cli.Context) []string {
|
||||||
argsN := params.NArg()
|
argsN := params.NArg()
|
||||||
|
|
|
@ -43,16 +43,6 @@ func TestDuplicates(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArray(t *testing.T) {
|
|
||||||
arr := []string{"a", "b", "c"}
|
|
||||||
if !array(arr[0], arr) {
|
|
||||||
t.Fatal("Unexpected", arr[0], "should be in", arr)
|
|
||||||
}
|
|
||||||
if array("d", arr) {
|
|
||||||
t.Fatal("Unexpected", "d", "shouldn't be in", arr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWdir(t *testing.T) {
|
func TestWdir(t *testing.T) {
|
||||||
expected, err := os.Getwd()
|
expected, err := os.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue