app interface, bug fix, no-server flag

This commit is contained in:
alessio 2016-09-18 13:50:15 +02:00
parent a4b0bcaeca
commit 0d908d675b
7 changed files with 156 additions and 80 deletions

View File

@ -1,45 +1,76 @@
package app package app
import ( import (
"fmt"
c "github.com/tockins/realize/cli" c "github.com/tockins/realize/cli"
s "github.com/tockins/realize/server" s "github.com/tockins/realize/server"
"gopkg.in/urfave/cli.v2"
"log"
"os"
"syscall" "syscall"
"fmt"
) )
var R Realize const (
Name = "Realize"
Version = "1.1"
Description = "A Go build system with file watchers, output streams and live reload. Run, build and watch file changes with custom paths"
Limit = 10000
Config = "r.config.yaml"
Output = "r.output.log"
)
var r realize
var R Realizer
// Realizer interface for wrap the cli, app and server functions
type Realizer interface {
Wdir() string
Before() error
Red(string) string
Blue(string) string
BlueS(string) string
Handle(error) error
Serve(*cli.Context)
Fast(*cli.Context) error
Run(p *cli.Context) error
Add(p *cli.Context) error
Remove(p *cli.Context) error
List(p *cli.Context) error
}
// Realize struct contains the general app informations // Realize struct contains the general app informations
type Realize struct { type realize struct {
Name, Description, Author, Email string Name, Description, Author, Email string
Version string Version string
Limit uint64 Limit uint64
Blueprint c.Blueprint Blueprint c.Blueprint
Server s.Server Server s.Server
Files map[string]string
} }
// Application initialization // Application initialization
func init(){ func init() {
R = Realize{ r = realize{
Name: "Realize", Name: Name,
Version: "1.0", Version: Version,
Description: "A Go build system with file watchers, output streams and live reload. Run, build and watch file changes with custom paths", Description: Description,
Limit: 10000, Limit: Limit,
Blueprint: c.Blueprint{
Files: map[string]string{ Files: map[string]string{
"config": "r.config.yaml", "config": Config,
"output": "r.output.log", "output": Output,
},
},
Server: s.Server{
Blueprint: &R.Blueprint,
}, },
} }
R.Increases() r.Blueprint = c.Blueprint{Files: r.Files}
r.Server = s.Server{
Blueprint: &r.Blueprint,
Files: r.Files,
}
r.Increase()
R = &r
} }
// Flimit defines the max number of watched files // Flimit defines the max number of watched files
func (r *Realize) Increases() { func (r *realize) Increase() {
// increases the files limit // increases the files limit
var rLimit syscall.Rlimit var rLimit syscall.Rlimit
rLimit.Max = r.Limit rLimit.Max = r.Limit
@ -49,3 +80,66 @@ func (r *Realize) Increases() {
fmt.Println(c.Red("Error Setting Rlimit "), err) fmt.Println(c.Red("Error Setting Rlimit "), err)
} }
} }
func (r *realize) Red(s string) string {
return c.Red(s)
}
func (r *realize) Blue(s string) string {
return c.Blue(s)
}
func (r *realize) BlueS(s string) string {
return c.BlueS(s)
}
func (r *realize) Wdir() string {
return c.WorkingDir()
}
func (r *realize) Serve(p *cli.Context) {
if !p.Bool("no-server") {
r.Server.Start()
}
}
func (r *realize) Run(p *cli.Context) error {
r.Serve(p)
return r.Blueprint.Run()
}
func (r *realize) Fast(p *cli.Context) error {
r.Blueprint.Add(p)
r.Serve(p)
return r.Blueprint.Fast(p)
}
func (r *realize) Add(p *cli.Context) error {
return r.Blueprint.Insert(p)
}
func (r *realize) Remove(p *cli.Context) error {
return r.Blueprint.Insert(p)
}
func (r *realize) List(p *cli.Context) error {
return r.Blueprint.List()
}
func (r *realize) Before() error {
fmt.Println(r.Blue(r.Name) + " - " + r.Blue(r.Version))
fmt.Println(r.BlueS(r.Description) + "\n")
gopath := os.Getenv("GOPATH")
if gopath == "" {
log.Fatal(r.Red("$GOPATH isn't set up properly"))
}
return nil
}
func (r *realize) Handle(err error) error {
if err != nil {
fmt.Println(r.Red(err.Error()))
return nil
}
return nil
}

View File

@ -15,7 +15,8 @@ func (h *Blueprint) Run() error {
if err == nil { if err == nil {
// loop projects // loop projects
wg.Add(len(h.Projects)) wg.Add(len(h.Projects))
for _,v := range h.Projects { for _, v := range h.Projects {
v.parent = h
go v.watching() go v.watching()
} }
wg.Wait() wg.Wait()
@ -30,10 +31,15 @@ func (h *Blueprint) Fast(params *cli.Context) error {
wg.Add(1) wg.Add(1)
for i := 0; i < len(h.Projects); i++ { for i := 0; i < len(h.Projects); i++ {
v := &h.Projects[i] v := &h.Projects[i]
v.parent = h
if params.Bool("config") { if params.Bool("config") {
if err := h.Read(); err == nil { if err := h.Read(); err == nil {
for l := 0; l < len(h.Projects); l++ { for l := 0; l < len(h.Projects); l++ {
l := &h.Projects[l] l := &h.Projects[l]
if l.Path == "/" {
l.Path = "."
l.parent = v.parent
}
if v.Path == l.Path { if v.Path == l.Path {
v = l v = l
} }
@ -41,7 +47,6 @@ func (h *Blueprint) Fast(params *cli.Context) error {
} }
} }
go v.watching() go v.watching()
} }
wg.Wait() wg.Wait()
return nil return nil

View File

@ -60,7 +60,7 @@ func (p *Project) GoRun(channel chan bool, runner chan bool, wr *sync.WaitGroup)
log.Println(pname(p.Name, 3), ":", BlueS(output.Text())) log.Println(pname(p.Name, 3), ":", BlueS(output.Text()))
} }
if p.Watcher.Output["file"] { if p.Watcher.Output["file"] {
path := filepath.Join(p.base, B.Files["output"]) path := filepath.Join(p.base, p.parent.Files["output"])
f := create(path) f := create(path)
t := time.Now() t := time.Now()
if _, err := f.WriteString(t.Format("2006-01-02 15:04:05") + " : " + output.Text() + "\r\n"); err != nil { if _, err := f.WriteString(t.Format("2006-01-02 15:04:05") + " : " + output.Text() + "\r\n"); err != nil {

View File

@ -1,18 +1,15 @@
package cli package cli
import ( import (
"github.com/fatih/color"
"log" "log"
"sync" "sync"
"time" "time"
"github.com/fatih/color"
) )
var B *Blueprint
var wg sync.WaitGroup var wg sync.WaitGroup
var Green, Red, RedS, Blue, BlueS, Yellow, YellowS, Magenta, MagentaS = var Green, Red, RedS, Blue, BlueS, Yellow, YellowS, Magenta, MagentaS = color.New(color.FgGreen, color.Bold).SprintFunc(),
color.New(color.FgGreen, color.Bold).SprintFunc(),
color.New(color.FgRed, color.Bold).SprintFunc(), color.New(color.FgRed, color.Bold).SprintFunc(),
color.New(color.FgRed).SprintFunc(), color.New(color.FgRed).SprintFunc(),
color.New(color.FgBlue, color.Bold).SprintFunc(), color.New(color.FgBlue, color.Bold).SprintFunc(),
@ -22,9 +19,12 @@ var Green, Red, RedS, Blue, BlueS, Yellow, YellowS, Magenta, MagentaS =
color.New(color.FgMagenta, color.Bold).SprintFunc(), color.New(color.FgMagenta, color.Bold).SprintFunc(),
color.New(color.FgMagenta).SprintFunc() color.New(color.FgMagenta).SprintFunc()
// Log struct
type logWriter struct{}
// Projects struct contains a projects list // Projects struct contains a projects list
type Blueprint struct { type Blueprint struct {
Projects []Project `yaml:"Projects,omitempty"` Projects []Project `yaml:"projects,omitempty"`
Files map[string]string `yaml:"-"` Files map[string]string `yaml:"-"`
} }
@ -41,7 +41,8 @@ type Project struct {
Test bool `yaml:"app_test,omitempty"` Test bool `yaml:"app_test,omitempty"`
Params []string `yaml:"app_params,omitempty"` Params []string `yaml:"app_params,omitempty"`
Watcher Watcher `yaml:"app_watcher,omitempty"` Watcher Watcher `yaml:"app_watcher,omitempty"`
Buffer Buffer Buffer Buffer `yaml:"-"`
parent *Blueprint
} }
// Watcher struct defines the livereload's logic // Watcher struct defines the livereload's logic

View File

@ -129,9 +129,6 @@ func pname(name string, color int) string {
return name return name
} }
// Log struct
type logWriter struct{}
// Cewrites the log timestamp // Cewrites the log timestamp
func (writer logWriter) Write(bytes []byte) (int, error) { func (writer logWriter) Write(bytes []byte) (int, error) {
return fmt.Print(YellowS("[") + time.Now().Format("15:04:05") + YellowS("]") + string(bytes)) return fmt.Print(YellowS("[") + time.Now().Format("15:04:05") + YellowS("]") + string(bytes))

View File

@ -2,36 +2,17 @@ package main
import ( import (
a "github.com/tockins/realize/app" a "github.com/tockins/realize/app"
c "github.com/tockins/realize/cli"
"fmt"
"gopkg.in/urfave/cli.v2" "gopkg.in/urfave/cli.v2"
"log"
"os" "os"
) )
var App *a.Realize var app a.Realizer
func main() { func main() {
App = &a.R app = a.R
handle := func(err error) error {
if err != nil {
fmt.Println(c.Red(err.Error()))
return nil
}
return nil
}
header := func() error {
fmt.Println(c.Blue(App.Name) + " - " + c.Blue(App.Version))
fmt.Println(c.BlueS(App.Description) + "\n")
gopath := os.Getenv("GOPATH")
if gopath == "" {
log.Fatal(c.Red("$GOPATH isn't set up properly"))
}
return nil
}
c := &cli.App{ c := &cli.App{
Name: App.Name, Name: a.Name,
Version: App.Version, Version: a.Version,
Authors: []*cli.Author{ Authors: []*cli.Author{
{ {
Name: "Alessio Pracchia", Name: "Alessio Pracchia",
@ -42,17 +23,19 @@ func main() {
Email: "conventi@hastega.it", Email: "conventi@hastega.it",
}, },
}, },
Usage: App.Description, Usage: a.Description,
Commands: []*cli.Command{ Commands: []*cli.Command{
{ {
Name: "run", Name: "run",
Usage: "Build and watch file changes", Usage: "Build and watch file changes",
Flags: []cli.Flag{
&cli.BoolFlag{Name: "no-server", Usage: "Enable the web panel"},
},
Action: func(p *cli.Context) error { Action: func(p *cli.Context) error {
return handle(App.Blueprint.Run()) return app.Handle(app.Run(p))
}, },
Before: func(c *cli.Context) error { Before: func(c *cli.Context) error {
header() return app.Before()
return nil
}, },
}, },
{ {
@ -64,17 +47,15 @@ func main() {
&cli.BoolFlag{Name: "no-run", Usage: "Disables the run"}, &cli.BoolFlag{Name: "no-run", Usage: "Disables the run"},
&cli.BoolFlag{Name: "no-bin", Usage: "Disables the installation"}, &cli.BoolFlag{Name: "no-bin", Usage: "Disables the installation"},
&cli.BoolFlag{Name: "no-fmt", Usage: "Disables the fmt (go fmt)"}, &cli.BoolFlag{Name: "no-fmt", Usage: "Disables the fmt (go fmt)"},
&cli.BoolFlag{Name: "test", Value: false, Usage: "Enable the tests"}, &cli.BoolFlag{Name: "no-server", Usage: "Disables the web panel"},
&cli.BoolFlag{Name: "Configuration", Value: false, Usage: "Take the defined settings if exist a Configuration file."}, &cli.BoolFlag{Name: "test", Value: false, Usage: "Enables the tests"},
&cli.BoolFlag{Name: "config", Value: false, Usage: "Take the defined settings if exist a Configuration file."},
}, },
Action: func(p *cli.Context) error { Action: func(p *cli.Context) error {
App.Blueprint.Add(p) return app.Handle(app.Fast(p))
App.Server.Start()
return handle(App.Blueprint.Fast(p))
}, },
Before: func(c *cli.Context) error { Before: func(c *cli.Context) error {
header() return app.Before()
return nil
}, },
}, },
{ {
@ -83,20 +64,19 @@ func main() {
Aliases: []string{"a"}, Aliases: []string{"a"},
Usage: "Add another project", Usage: "Add another project",
Flags: []cli.Flag{ Flags: []cli.Flag{
&cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: c.WorkingDir(), Usage: "Project name"}, &cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: app.Wdir(), Usage: "Project name"},
&cli.StringFlag{Name: "path", Aliases: []string{"b"}, Value: "/", Usage: "Project base path"}, &cli.StringFlag{Name: "path", Aliases: []string{"b"}, Value: "/", Usage: "Project base path"},
&cli.BoolFlag{Name: "build", Value: false, Usage: "Enable the build"}, &cli.BoolFlag{Name: "build", Value: false, Usage: "Enable the build"},
&cli.BoolFlag{Name: "no-run", Usage: "Disables the run"}, &cli.BoolFlag{Name: "no-run", Usage: "Disables the run"},
&cli.BoolFlag{Name: "no-bin", Usage: "Disables the installation"}, &cli.BoolFlag{Name: "no-bin", Usage: "Disables the installation"},
&cli.BoolFlag{Name: "no-fmt", Usage: "Disables the fmt (go fmt)"}, &cli.BoolFlag{Name: "no-fmt", Usage: "Disables the fmt (go fmt)"},
&cli.BoolFlag{Name: "test", Value: false, Usage: "Enable the tests"}, &cli.BoolFlag{Name: "test", Value: false, Usage: "Enables the tests"},
}, },
Action: func(p *cli.Context) error { Action: func(p *cli.Context) error {
return handle(App.Blueprint.Insert(p)) return app.Handle(app.Add(p))
}, },
Before: func(c *cli.Context) error { Before: func(c *cli.Context) error {
header() return app.Before()
return nil
}, },
}, },
{ {
@ -108,11 +88,10 @@ func main() {
&cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: ""}, &cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: ""},
}, },
Action: func(p *cli.Context) error { Action: func(p *cli.Context) error {
return handle(App.Blueprint.Remove(p)) return app.Handle(app.Remove(p))
}, },
Before: func(c *cli.Context) error { Before: func(c *cli.Context) error {
header() return app.Before()
return nil
}, },
}, },
{ {
@ -121,11 +100,10 @@ func main() {
Aliases: []string{"l"}, Aliases: []string{"l"},
Usage: "Projects list", Usage: "Projects list",
Action: func(p *cli.Context) error { Action: func(p *cli.Context) error {
return handle(App.Blueprint.List()) return app.Handle(app.List(p))
}, },
Before: func(c *cli.Context) error { Before: func(c *cli.Context) error {
header() return app.Before()
return nil
}, },
}, },
}, },

View File

@ -1,20 +1,21 @@
package server package server
import ( import (
c "github.com/tockins/realize/cli"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/labstack/echo" "github.com/labstack/echo"
"github.com/labstack/echo/engine/standard" "github.com/labstack/echo/engine/standard"
"github.com/labstack/echo/middleware" "github.com/labstack/echo/middleware"
c "github.com/tockins/realize/cli"
"golang.org/x/net/websocket" "golang.org/x/net/websocket"
"log" "log"
"net/http" "net/http"
) )
// Server struct contains server informations // Server struct contains server informations
type Server struct{ type Server struct {
Blueprint *c.Blueprint Blueprint *c.Blueprint
Files map[string]string
} }
func render(c echo.Context, path string) error { func render(c echo.Context, path string) error {