parent
40780b17f0
commit
558f8384cc
141
realize.go
141
realize.go
|
@ -8,21 +8,18 @@ import (
|
|||
w "github.com/tockins/realize/watcher"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
name = "Realize"
|
||||
version = "1.2.1"
|
||||
version = "1.3"
|
||||
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"
|
||||
streams = "streams.log"
|
||||
outputs = "outputs.log"
|
||||
errs = "errors.log"
|
||||
logs = "logs.log"
|
||||
host = "localhost"
|
||||
port = 5001
|
||||
server = true
|
||||
open = false
|
||||
)
|
||||
|
||||
var r realize
|
||||
|
@ -45,23 +42,12 @@ func init() {
|
|||
Description: description,
|
||||
Sync: make(chan string),
|
||||
Settings: c.Settings{
|
||||
Config: c.Config{
|
||||
Flimit: 0,
|
||||
Polling: false,
|
||||
PollingInterval: time.Millisecond * 200,
|
||||
},
|
||||
Resources: c.Resources{
|
||||
Config: config,
|
||||
Streams: streams,
|
||||
Outputs: outputs,
|
||||
Logs: logs,
|
||||
Errors: errs,
|
||||
},
|
||||
Server: c.Server{
|
||||
Enabled: server,
|
||||
Open: open,
|
||||
Host: host,
|
||||
Port: port,
|
||||
},
|
||||
},
|
||||
}
|
||||
r.Blueprint = w.Blueprint{
|
||||
|
@ -122,43 +108,32 @@ func main() {
|
|||
Usage: r.Description,
|
||||
Commands: []*cli.Command{
|
||||
{
|
||||
Name: "run",
|
||||
Usage: "Build and watch file changes. Can be used even with a single project or without the config file",
|
||||
Name: "run",
|
||||
Aliases: []string{"r"},
|
||||
Usage: "Run a toolchain on a project. Can be personalized, used with a single project and without make a realize config file",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "path", Aliases: []string{"b"}, Value: "", Usage: "Project base path"},
|
||||
&cli.BoolFlag{Name: "build", Value: false, Usage: "Enables the build"},
|
||||
&cli.BoolFlag{Name: "no-run", Usage: "Disables the run"},
|
||||
&cli.BoolFlag{Name: "no-bin", Usage: "Disables the installation"},
|
||||
&cli.BoolFlag{Name: "no-fmt", Usage: "Disables the fmt (go fmt)"},
|
||||
&cli.BoolFlag{Name: "no-server", Usage: "Disables the web panel"},
|
||||
&cli.BoolFlag{Name: "no-config", Value: false, Usage: "Uses the config settings"},
|
||||
&cli.BoolFlag{Name: "open", Usage: "Automatically opens the web panel"},
|
||||
&cli.IntFlag{Name: "port", Usage: "Sets the web panel port"},
|
||||
&cli.BoolFlag{Name: "test", Value: false, Usage: "Enables the tests"},
|
||||
&cli.StringFlag{Name: "path", Aliases: []string{"p"}, Value: "", Usage: "Project base path"},
|
||||
&cli.IntFlag{Name: "flimit", Aliases: []string{"f"}, Usage: "Increase files limit"},
|
||||
&cli.BoolFlag{Name: "legacy", Aliases: []string{"l"}, Value: false, Usage: "Enable legacy watch"},
|
||||
&cli.IntFlag{Name: "legacy-delay", Aliases: []string{"ld"}, Usage: "Restarting delay for legacy watch"},
|
||||
&cli.BoolFlag{Name: "build", Aliases: []string{"b"}, Value: false, Usage: "Enable go build"},
|
||||
&cli.BoolFlag{Name: "test", Aliases: []string{"t"}, Value: false, Usage: "Enable go test"},
|
||||
&cli.BoolFlag{Name: "generate", Aliases: []string{"g"}, Value: false, Usage: "Enable go generate"},
|
||||
&cli.BoolFlag{Name: "preview", Aliases: []string{"prev"}, Value: false, Usage: "Print each watched file"},
|
||||
&cli.BoolFlag{Name: "no-run", Aliases: []string{"nr"}, Usage: "Disable go run"},
|
||||
&cli.BoolFlag{Name: "no-bin", Aliases: []string{"nb"}, Usage: "Disable go install"},
|
||||
&cli.BoolFlag{Name: "no-fmt", Aliases: []string{"nf"}, Usage: "Disable go fmt"},
|
||||
&cli.BoolFlag{Name: "no-config", Aliases: []string{"nc"}, Value: false, Usage: "Run ignoring an existing config file"},
|
||||
&cli.BoolFlag{Name: "no-server", Aliases: []string{"ns"}, Value: false, Usage: "Disable web panel"},
|
||||
&cli.BoolFlag{Name: "serv-open", Aliases: []string{"so"}, Value: false, Usage: "Open wen panel in a new browser tab"},
|
||||
&cli.IntFlag{Name: "serv-port", Aliases: []string{"sp"}, Value: port, Usage: "Server port number"},
|
||||
&cli.StringFlag{Name: "serv-host", Aliases: []string{"sh"}, Value: host, Usage: "Server host"},
|
||||
},
|
||||
Action: func(p *cli.Context) error {
|
||||
if p.Bool("no-config") {
|
||||
r.Settings = c.Settings{
|
||||
Config: c.Config{
|
||||
Flimit: 0,
|
||||
},
|
||||
Resources: c.Resources{
|
||||
Config: config,
|
||||
Streams: streams,
|
||||
Logs: logs,
|
||||
Errors: errs,
|
||||
},
|
||||
Server: c.Server{
|
||||
Enabled: server,
|
||||
Open: open,
|
||||
Host: host,
|
||||
Port: port,
|
||||
},
|
||||
}
|
||||
r.Blueprint.Projects = r.Blueprint.Projects[:0]
|
||||
r.Blueprint.Add(p)
|
||||
} else if len(r.Blueprint.Projects) <= 0 {
|
||||
r.Blueprint.Add(p)
|
||||
r.Settings.Init(p)
|
||||
if r.Settings.Config.Create || len(r.Blueprint.Projects) <= 0 {
|
||||
r.Blueprint.Projects = []w.Project{}
|
||||
handle(r.Blueprint.Add(p))
|
||||
}
|
||||
handle(r.Server.Start(p))
|
||||
handle(r.Blueprint.Run())
|
||||
|
@ -170,23 +145,51 @@ func main() {
|
|||
},
|
||||
},
|
||||
{
|
||||
Name: "add",
|
||||
Name: "config",
|
||||
Category: "Configuration",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Add another project",
|
||||
Aliases: []string{"c"},
|
||||
Usage: "Create/Edit a realize config",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: r.Wdir(), Usage: "Project name"},
|
||||
&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: "no-run", Usage: "Disables the run"},
|
||||
&cli.BoolFlag{Name: "no-bin", Usage: "Disables the installation"},
|
||||
&cli.BoolFlag{Name: "no-fmt", Usage: "Disables the fmt (go fmt)"},
|
||||
&cli.BoolFlag{Name: "test", Value: false, Usage: "Enables the tests"},
|
||||
&cli.StringFlag{Name: "path", Aliases: []string{"p"}, Value: "", Usage: "Project base path"},
|
||||
&cli.BoolFlag{Name: "build", Aliases: []string{"b"}, Value: false, Usage: "Enable go build"},
|
||||
&cli.BoolFlag{Name: "test", Aliases: []string{"t"}, Value: false, Usage: "Enable go test"},
|
||||
&cli.BoolFlag{Name: "generate", Aliases: []string{"g"}, Value: false, Usage: "Enable go generate"},
|
||||
&cli.BoolFlag{Name: "preview", Aliases: []string{"prev"}, Value: false, Usage: "Print each watched file"},
|
||||
&cli.BoolFlag{Name: "no-run", Aliases: []string{"nr"}, Usage: "Disable go run"},
|
||||
&cli.BoolFlag{Name: "no-bin", Aliases: []string{"nb"}, Usage: "Disable go install"},
|
||||
&cli.BoolFlag{Name: "no-fmt", Aliases: []string{"nf"}, Usage: "Disable go fmt"},
|
||||
},
|
||||
Action: func(p *cli.Context) (err error) {
|
||||
handle(r.Blueprint.Insert(p))
|
||||
handle(r.Record(r))
|
||||
fmt.Println(r.Green.Bold("Your project was successfully added"))
|
||||
fmt.Println(r.Green.Bold("Your project was successfully added."))
|
||||
return nil
|
||||
},
|
||||
Before: func(c *cli.Context) error {
|
||||
return before()
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "add",
|
||||
Category: "Configuration",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Add a new project to an existing realize config file",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: r.Wdir(), Usage: "Project name"},
|
||||
&cli.StringFlag{Name: "path", Aliases: []string{"p"}, Value: "", Usage: "Project base path"},
|
||||
&cli.BoolFlag{Name: "build", Aliases: []string{"b"}, Value: false, Usage: "Enable go build"},
|
||||
&cli.BoolFlag{Name: "test", Aliases: []string{"t"}, Value: false, Usage: "Enable go test"},
|
||||
&cli.BoolFlag{Name: "generate", Aliases: []string{"g"}, Value: false, Usage: "Enable go generate"},
|
||||
&cli.BoolFlag{Name: "preview", Aliases: []string{"prev"}, Value: false, Usage: "Print each watched file"},
|
||||
&cli.BoolFlag{Name: "no-run", Aliases: []string{"nr"}, Usage: "Disable go run"},
|
||||
&cli.BoolFlag{Name: "no-bin", Aliases: []string{"nb"}, Usage: "Disable go install"},
|
||||
&cli.BoolFlag{Name: "no-fmt", Aliases: []string{"nf"}, Usage: "Disable go fmt"},
|
||||
},
|
||||
Action: func(p *cli.Context) (err error) {
|
||||
handle(r.Blueprint.Insert(p))
|
||||
handle(r.Record(r))
|
||||
fmt.Println(r.Green.Bold("Your project was successfully added."))
|
||||
return nil
|
||||
},
|
||||
Before: func(c *cli.Context) error {
|
||||
|
@ -197,7 +200,7 @@ func main() {
|
|||
Name: "remove",
|
||||
Category: "Configuration",
|
||||
Aliases: []string{"r"},
|
||||
Usage: "Remove a project",
|
||||
Usage: "Remove a project from a config file",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: ""},
|
||||
},
|
||||
|
@ -223,6 +226,20 @@ func main() {
|
|||
return before()
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "clean",
|
||||
Category: "Configuration",
|
||||
Aliases: []string{"c"},
|
||||
Usage: "Remove realize folder",
|
||||
Action: func(p *cli.Context) error {
|
||||
handle(r.Settings.Remove())
|
||||
fmt.Println(r.Green.Bold("Realize folder successfully removed."))
|
||||
return nil
|
||||
},
|
||||
Before: func(c *cli.Context) error {
|
||||
return before()
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
c.Run(os.Args)
|
||||
|
|
|
@ -48,10 +48,7 @@ func render(c echo.Context, path string, mime int) error {
|
|||
|
||||
// Start the web server
|
||||
func (s *Server) Start(p *cli.Context) (err error) {
|
||||
if p.Int("port") != 0 {
|
||||
s.Settings.Server.Port = p.Int("port")
|
||||
}
|
||||
if !p.Bool("no-server") && s.Enabled {
|
||||
if s.Status {
|
||||
e := echo.New()
|
||||
e.Use(middleware.Gzip())
|
||||
e.Use(middleware.Recover())
|
||||
|
@ -95,8 +92,6 @@ func (s *Server) Start(p *cli.Context) (err error) {
|
|||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s.Server.Enabled = false
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package settings
|
||||
|
||||
import (
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"gopkg.in/yaml.v2"
|
||||
"os"
|
||||
"time"
|
||||
|
@ -9,30 +10,36 @@ import (
|
|||
// Settings defines a group of general settings
|
||||
type Settings struct {
|
||||
Colors `yaml:"-"`
|
||||
Config `yaml:",inline" json:"config"`
|
||||
Resources `yaml:"resources" json:"resources"`
|
||||
Server `yaml:"server" json:"server"`
|
||||
Config `yaml:"config" json:"config"`
|
||||
Server `yaml:"server,omitempty" json:"server,omitempty"`
|
||||
}
|
||||
|
||||
// Config defines structural options
|
||||
type Config struct {
|
||||
Flimit uint64 `yaml:"flimit" json:"flimit"`
|
||||
Polling bool `yaml:"polling" json:"polling"`
|
||||
PollingInterval time.Duration `yaml:"polling_interval" json:"polling_interval"`
|
||||
Create bool `yaml:"-" json:"-"`
|
||||
Flimit uint64 `yaml:"flimit,omitempty" json:"flimit,omitempty"`
|
||||
Legacy `yaml:"legacy,omitempty" json:"legacy,omitempty"`
|
||||
}
|
||||
|
||||
// Polling configuration
|
||||
type Legacy struct {
|
||||
Status bool `yaml:"status" json:"status"`
|
||||
Interval time.Duration `yaml:"interval" json:"interval"`
|
||||
}
|
||||
|
||||
// Server settings, used for the web panel
|
||||
type Server struct {
|
||||
Enabled bool `yaml:"enable" json:"enable"`
|
||||
Open bool `yaml:"open" json:"open"`
|
||||
Host string `yaml:"host" json:"host"`
|
||||
Port int `yaml:"port" json:"port"`
|
||||
Status bool `yaml:"status" json:"status"`
|
||||
Open bool `yaml:"open" json:"open"`
|
||||
Host string `yaml:"host" json:"host"`
|
||||
Port int `yaml:"port" json:"port"`
|
||||
}
|
||||
|
||||
// Resources defines the files generated by realize
|
||||
type Resources struct {
|
||||
Config string `yaml:"-" json:"-"`
|
||||
Streams string `yaml:"streams" json:"output"`
|
||||
Outputs string `yaml:"outputs" json:"outputs"`
|
||||
Logs string `yaml:"logs" json:"log"`
|
||||
Errors string `yaml:"errors" json:"error"`
|
||||
}
|
||||
|
@ -53,14 +60,43 @@ func (s *Settings) Read(out interface{}) error {
|
|||
|
||||
// Record create and unmarshal the yaml config file
|
||||
func (s *Settings) Record(out interface{}) error {
|
||||
y, err := yaml.Marshal(out)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := os.Stat(".realize/"); os.IsNotExist(err) {
|
||||
if err = os.Mkdir(".realize/", 0770); err != nil {
|
||||
return s.Write(s.Resources.Config, y)
|
||||
if s.Config.Create {
|
||||
y, err := yaml.Marshal(out)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := os.Stat(".realize/"); os.IsNotExist(err) {
|
||||
if err = os.Mkdir(".realize/", 0770); err != nil {
|
||||
return s.Write(s.Resources.Config, y)
|
||||
}
|
||||
}
|
||||
return s.Write(".realize/"+s.Resources.Config, y)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove realize folder
|
||||
func (s *Settings) Remove() error {
|
||||
if _, err := os.Stat(".realize/"); !os.IsNotExist(err) {
|
||||
return os.RemoveAll(".realize/")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Init configuration for general settings
|
||||
func (s *Settings) Init(p *cli.Context) {
|
||||
s.Config = Config{
|
||||
Create: !p.Bool("no-config"),
|
||||
Flimit: p.Uint64("flimit"),
|
||||
Legacy: Legacy{
|
||||
Status: p.Bool("legacy"),
|
||||
Interval: p.Duration("legacy-delay"),
|
||||
},
|
||||
}
|
||||
s.Server = Server{
|
||||
Status: !p.Bool("no-server"),
|
||||
Open: p.Bool("serv-open"),
|
||||
Host: p.String("serv-host"),
|
||||
Port: p.Int("serv-port"),
|
||||
}
|
||||
return s.Write(".realize/"+s.Resources.Config, y)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ func (h *Blueprint) Run() error {
|
|||
for k := range h.Projects {
|
||||
h.Projects[k].parent = h
|
||||
h.Projects[k].path = h.Projects[k].Path
|
||||
if h.Polling.Status {
|
||||
if h.Legacy.Status {
|
||||
go h.Projects[k].watchByPolling()
|
||||
} else {
|
||||
go h.Projects[k].watchByNotify()
|
||||
|
@ -32,27 +32,27 @@ func (h *Blueprint) Run() error {
|
|||
// Add a new project
|
||||
func (h *Blueprint) Add(p *cli.Context) error {
|
||||
project := Project{
|
||||
Name: h.name(p),
|
||||
Path: strings.Replace(filepath.Clean(p.String("path")), "\\", "/", -1),
|
||||
Build: p.Bool("build"),
|
||||
Bin: !p.Bool("no-bin"),
|
||||
Run: !p.Bool("no-run"),
|
||||
Fmt: !p.Bool("no-fmt"),
|
||||
Test: p.Bool("test"),
|
||||
Params: argsParam(p),
|
||||
Name: h.name(p),
|
||||
Path: strings.Replace(filepath.Clean(p.String("path")), "\\", "/", -1),
|
||||
Fmt: !p.Bool("no-fmt"),
|
||||
Generate: p.Bool("generate"),
|
||||
Test: p.Bool("test"),
|
||||
Build: p.Bool("build"),
|
||||
Bin: !p.Bool("no-bin"),
|
||||
Run: !p.Bool("no-run"),
|
||||
Params: argsParam(p),
|
||||
Watcher: Watcher{
|
||||
Paths: []string{"/"},
|
||||
Ignore: []string{"vendor"},
|
||||
Exts: []string{".go"},
|
||||
Preview: false,
|
||||
Preview: p.Bool("preview"),
|
||||
Scripts: []Command{},
|
||||
},
|
||||
Cli: Cli{
|
||||
Streams: true,
|
||||
},
|
||||
File: File{
|
||||
Streams: false,
|
||||
Logs: false,
|
||||
Errors: false,
|
||||
Streams: Streams{
|
||||
CliOut: true,
|
||||
FileOut: false,
|
||||
FileLog: false,
|
||||
FileErr: false,
|
||||
},
|
||||
}
|
||||
if _, err := duplicates(project, h.Projects); err != nil {
|
||||
|
@ -97,18 +97,17 @@ func (h *Blueprint) List() error {
|
|||
for _, val := range h.Projects {
|
||||
fmt.Println(h.Blue.Bold("|"), h.Blue.Bold(strings.ToUpper(val.Name)))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Base Path"), ":", h.Magenta.Regular(val.Path))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Run"), ":", h.Magenta.Regular(val.Run))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Build"), ":", h.Magenta.Regular(val.Build))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Install"), ":", h.Magenta.Regular(val.Bin))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Fmt"), ":", h.Magenta.Regular(val.Fmt))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Generate"), ":", h.Magenta.Regular(val.Generate))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Test"), ":", h.Magenta.Regular(val.Test))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Install"), ":", h.Magenta.Regular(val.Bin))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Build"), ":", h.Magenta.Regular(val.Build))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Run"), ":", h.Magenta.Regular(val.Run))
|
||||
if len(val.Params) > 0 {
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Params"), ":", h.Magenta.Regular(val.Params))
|
||||
}
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Watcher"), ":")
|
||||
if len(val.Watcher.Commands) > 0 {
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("After"), ":", h.Magenta.Regular(val.Watcher.Commands))
|
||||
}
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Preview"), ":", h.Magenta.Regular(val.Watcher.Preview))
|
||||
if len(val.Watcher.Exts) > 0 {
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Extensions"), ":", h.Magenta.Regular(val.Watcher.Exts))
|
||||
}
|
||||
|
@ -118,13 +117,25 @@ func (h *Blueprint) List() error {
|
|||
if len(val.Watcher.Ignore) > 0 {
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Ignored paths"), ":", h.Magenta.Regular(val.Watcher.Ignore))
|
||||
}
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Files preview"), ":", h.Magenta.Regular(val.Watcher.Preview))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Cli"), ":")
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Streams"), ":", h.Magenta.Regular(val.Cli.Streams))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("File"), ":")
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Streams"), ":", h.Magenta.Regular(val.File.Streams))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Logs"), ":", h.Magenta.Regular(val.File.Logs))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Errors"), ":", h.Magenta.Regular(val.File.Errors))
|
||||
if len(val.Watcher.Scripts) > 0 {
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Scripts"), ":")
|
||||
for _, v := range val.Watcher.Scripts {
|
||||
if v.Command != "" {
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t\t", h.Magenta.Regular("-"), h.Yellow.Regular("Command"), ":", h.Magenta.Regular(v.Command))
|
||||
if v.Path != "" {
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t\t", h.Yellow.Regular("Path"), ":", h.Magenta.Regular(v.Path))
|
||||
}
|
||||
if v.Type != "" {
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t\t", h.Yellow.Regular("Type"), ":", h.Magenta.Regular(v.Type))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Streams"), ":")
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Cli Out"), ":", h.Magenta.Regular(val.Streams.CliOut))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("File Out"), ":", h.Magenta.Regular(val.Streams.FileOut))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("File Log"), ":", h.Magenta.Regular(val.Streams.FileLog))
|
||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("File Err"), ":", h.Magenta.Regular(val.Streams.FileErr))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ func (p *Project) goTools(dir string, name string, cmd ...string) (string, error
|
|||
return "", nil
|
||||
}
|
||||
|
||||
// Cmds exec a list of defined commands
|
||||
// Exec an additional command from a defined path if specified
|
||||
func (p *Project) command(cmd Command) (errors string, logs string) {
|
||||
var stdout bytes.Buffer
|
||||
var stderr bytes.Buffer
|
||||
|
|
|
@ -39,15 +39,14 @@ type Project struct {
|
|||
Name string `yaml:"name" json:"name"`
|
||||
Path string `yaml:"path" json:"path"`
|
||||
Fmt bool `yaml:"fmt" json:"fmt"`
|
||||
Test bool `yaml:"test" json:"test"`
|
||||
Generate bool `yaml:"generate" json:"generate"`
|
||||
Test bool `yaml:"test" json:"test"`
|
||||
Bin bool `yaml:"bin" json:"bin"`
|
||||
Build bool `yaml:"build" json:"build"`
|
||||
Run bool `yaml:"run" json:"run"`
|
||||
Params []string `yaml:"params,omitempty" json:"params,omitempty"`
|
||||
Watcher Watcher `yaml:"watcher" json:"watcher"`
|
||||
Cli Cli `yaml:"cli,omitempty" json:"cli,omitempty"`
|
||||
File File `yaml:"file,omitempty" json:"file,omitempty"`
|
||||
Streams Streams `yaml:"streams" json:"streams"`
|
||||
Buffer Buffer `yaml:"-" json:"buffer"`
|
||||
parent *Blueprint
|
||||
path string
|
||||
|
@ -55,30 +54,26 @@ type Project struct {
|
|||
|
||||
// Watcher struct defines the livereload's logic
|
||||
type Watcher struct {
|
||||
Preview bool `yaml:"preview" json:"preview"`
|
||||
Paths []string `yaml:"paths" json:"paths"`
|
||||
Ignore []string `yaml:"ignore_paths" json:"ignore"`
|
||||
Exts []string `yaml:"exts" json:"exts"`
|
||||
Commands []Command `yaml:"commands,omitempty" json:"commands,omitempty"`
|
||||
Preview bool `yaml:"preview" json:"preview"`
|
||||
Paths []string `yaml:"paths" json:"paths"`
|
||||
Ignore []string `yaml:"ignore_paths" json:"ignore"`
|
||||
Exts []string `yaml:"exts" json:"exts"`
|
||||
Scripts []Command `yaml:"scripts,omitempty" json:"scripts,omitempty"`
|
||||
}
|
||||
|
||||
// Command options
|
||||
type Command struct {
|
||||
Type string `yaml:"type,omitempty" json:"type,omitempty"`
|
||||
Command string `yaml:"command,omitempty" json:"command,omitempty"`
|
||||
Path string `yaml:"path,omitempty" json:"path,omitempty"`
|
||||
}
|
||||
|
||||
// Cli output status, enables or disables
|
||||
type Cli struct {
|
||||
Streams bool `yaml:"streams" json:"streams"`
|
||||
Type string `yaml:"type" json:"type"`
|
||||
Command string `yaml:"command" json:"command"`
|
||||
Path string `yaml:"path" json:"path"`
|
||||
}
|
||||
|
||||
// File determinates the status of each log files (streams, logs, errors)
|
||||
type File struct {
|
||||
Streams bool `yaml:"streams,omitempty" json:"streams,omitempty"`
|
||||
Logs bool `yaml:"logs,omitempty" json:"logs,omitempty"`
|
||||
Errors bool `yaml:"errors,omitempty" json:"errors,omitempty"`
|
||||
type Streams struct {
|
||||
CliOut bool `yaml:"cli_out" json:"cli_out"`
|
||||
FileOut bool `yaml:"file_out" json:"file_out"`
|
||||
FileLog bool `yaml:"file_log" json:"file_log"`
|
||||
FileErr bool `yaml:"file_err" json:"file_err"`
|
||||
}
|
||||
|
||||
// Buffer define an array buffer for each log files
|
||||
|
|
|
@ -43,7 +43,7 @@ func (p *Project) watchByPolling() {
|
|||
}()
|
||||
|
||||
p.cmd("before")
|
||||
p.Fatal(p.walks(watcher))
|
||||
p.Fatal(p.watch(watcher))
|
||||
go p.routines(channel, &wr)
|
||||
p.LastChangedOn = time.Now().Truncate(time.Second)
|
||||
walk := func(changed string, info os.FileInfo, err error) error {
|
||||
|
@ -64,16 +64,17 @@ func (p *Project) watchByPolling() {
|
|||
file := changed[:i] + ext
|
||||
path := filepath.Dir(changed[:i])
|
||||
if changed[:i] != "" && inArray(ext, p.Watcher.Exts) {
|
||||
p.LastChangedOn = time.Now().Truncate(time.Second)
|
||||
msg = fmt.Sprintln(p.pname(p.Name, 4), ":", p.Magenta.Bold(strings.ToUpper(ext[1:])+" changed"), p.Magenta.Bold(file))
|
||||
out = BufferOut{Time: time.Now(), Text: strings.ToUpper(ext[1:]) + " changed " + file}
|
||||
p.print("log", out, msg, "")
|
||||
// stop and run again
|
||||
if p.Run {
|
||||
close(channel)
|
||||
channel = make(chan bool)
|
||||
}
|
||||
// handle multiple errors, need a better way
|
||||
p.LastChangedOn = time.Now().Truncate(time.Second)
|
||||
// repeat the initial cycle
|
||||
msg = fmt.Sprintln(p.pname(p.Name, 4), ":", p.Magenta.Bold(strings.ToUpper(ext[1:])+" changed"), p.Magenta.Bold(file))
|
||||
out = BufferOut{Time: time.Now(), Text: strings.ToUpper(ext[1:]) + " changed " + file}
|
||||
p.print("log", out, msg, "")
|
||||
|
||||
p.cmd("change")
|
||||
p.fmt(file)
|
||||
p.test(path)
|
||||
p.generate(path)
|
||||
|
@ -98,7 +99,7 @@ func (p *Project) watchByPolling() {
|
|||
select {
|
||||
case <-exit:
|
||||
return
|
||||
case <-time.After(p.parent.Polling.Interval / time.Duration(len(p.Watcher.Paths))):
|
||||
case <-time.After(p.parent.Legacy.Interval / time.Duration(len(p.Watcher.Paths))):
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +119,7 @@ func (p *Project) watchByNotify() {
|
|||
}()
|
||||
|
||||
p.cmd("before")
|
||||
p.Fatal(p.walks(watcher))
|
||||
p.Fatal(p.watch(watcher))
|
||||
go p.routines(channel, &wr)
|
||||
p.LastChangedOn = time.Now().Truncate(time.Second)
|
||||
for {
|
||||
|
@ -139,16 +140,17 @@ func (p *Project) watchByNotify() {
|
|||
file := event.Name[:i] + ext
|
||||
path := filepath.Dir(event.Name[:i])
|
||||
if event.Name[:i] != "" && inArray(ext, p.Watcher.Exts) {
|
||||
p.LastChangedOn = time.Now().Truncate(time.Second)
|
||||
msg = fmt.Sprintln(p.pname(p.Name, 4), ":", p.Magenta.Bold(strings.ToUpper(ext[1:])+" changed"), p.Magenta.Bold(file))
|
||||
out = BufferOut{Time: time.Now(), Text: strings.ToUpper(ext[1:]) + " changed " + file}
|
||||
p.print("log", out, msg, "")
|
||||
// stop and run again
|
||||
if p.Run {
|
||||
close(channel)
|
||||
channel = make(chan bool)
|
||||
}
|
||||
// handle multiple errors, need a better way
|
||||
p.LastChangedOn = time.Now().Truncate(time.Second)
|
||||
// repeat the initial cycle
|
||||
msg = fmt.Sprintln(p.pname(p.Name, 4), ":", p.Magenta.Bold(strings.ToUpper(ext[1:])+" changed"), p.Magenta.Bold(file))
|
||||
out = BufferOut{Time: time.Now(), Text: strings.ToUpper(ext[1:]) + " changed " + file}
|
||||
p.print("log", out, msg, "")
|
||||
|
||||
p.cmd("change")
|
||||
p.fmt(file)
|
||||
p.test(path)
|
||||
p.generate(path)
|
||||
|
@ -166,6 +168,55 @@ func (p *Project) watchByNotify() {
|
|||
}
|
||||
}
|
||||
|
||||
// Watch the files tree of a project
|
||||
func (p *Project) watch(watcher watcher) error {
|
||||
var files, folders int64
|
||||
wd, _ := os.Getwd()
|
||||
walk := func(path string, info os.FileInfo, err error) error {
|
||||
if !p.ignore(path) {
|
||||
if (info.IsDir() && len(filepath.Ext(path)) == 0 && !strings.HasPrefix(path, ".")) && !strings.Contains(path, "/.") || (inArray(filepath.Ext(path), p.Watcher.Exts)) {
|
||||
if p.Watcher.Preview {
|
||||
log.Println(p.pname(p.Name, 1), ":", path)
|
||||
}
|
||||
if err = watcher.Add(path); err != nil {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
if inArray(filepath.Ext(path), p.Watcher.Exts) {
|
||||
files++
|
||||
p.fmt(path)
|
||||
} else {
|
||||
folders++
|
||||
p.generate(path)
|
||||
p.test(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if p.path == "." || p.path == "/" {
|
||||
p.base = wd
|
||||
p.path = p.Wdir()
|
||||
} else if filepath.IsAbs(p.path) {
|
||||
p.base = p.path
|
||||
} else {
|
||||
p.base = filepath.Join(wd, p.path)
|
||||
}
|
||||
for _, dir := range p.Watcher.Paths {
|
||||
base := filepath.Join(p.base, dir)
|
||||
if _, err := os.Stat(base); err == nil {
|
||||
if err := filepath.Walk(base, walk); err != nil {
|
||||
log.Println(p.Red.Bold(err.Error()))
|
||||
}
|
||||
} else {
|
||||
return errors.New(base + " path doesn't exist")
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// Install calls an implementation of "go install"
|
||||
func (p *Project) install() error {
|
||||
if p.Bin {
|
||||
|
@ -266,7 +317,7 @@ func (p *Project) test(path string) error {
|
|||
|
||||
// Cmd calls an wrapper for execute the commands after/before
|
||||
func (p *Project) cmd(flag string) {
|
||||
for _, cmd := range p.Watcher.Commands {
|
||||
for _, cmd := range p.Watcher.Scripts {
|
||||
if strings.ToLower(cmd.Type) == flag {
|
||||
errors, logs := p.command(cmd)
|
||||
msg = fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Bold("Command"), p.Green.Bold("\"")+cmd.Command+p.Green.Bold("\""))
|
||||
|
@ -291,55 +342,6 @@ func (p *Project) cmd(flag string) {
|
|||
}
|
||||
}
|
||||
|
||||
// Walks the file tree of a project
|
||||
func (p *Project) walks(watcher watcher) error {
|
||||
var files, folders int64
|
||||
wd, _ := os.Getwd()
|
||||
walk := func(path string, info os.FileInfo, err error) error {
|
||||
if !p.ignore(path) {
|
||||
if (info.IsDir() && len(filepath.Ext(path)) == 0 && !strings.HasPrefix(path, ".")) && !strings.Contains(path, "/.") || (inArray(filepath.Ext(path), p.Watcher.Exts)) {
|
||||
if p.Watcher.Preview {
|
||||
log.Println(p.pname(p.Name, 1), ":", path)
|
||||
}
|
||||
if err = watcher.Add(path); err != nil {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
if inArray(filepath.Ext(path), p.Watcher.Exts) {
|
||||
files++
|
||||
p.fmt(path)
|
||||
} else {
|
||||
folders++
|
||||
p.generate(path)
|
||||
p.test(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if p.path == "." || p.path == "/" {
|
||||
p.base = wd
|
||||
p.path = p.Wdir()
|
||||
} else if filepath.IsAbs(p.path) {
|
||||
p.base = p.path
|
||||
} else {
|
||||
p.base = filepath.Join(wd, p.path)
|
||||
}
|
||||
for _, dir := range p.Watcher.Paths {
|
||||
base := filepath.Join(p.base, dir)
|
||||
if _, err := os.Stat(base); err == nil {
|
||||
if err := filepath.Walk(base, walk); err != nil {
|
||||
log.Println(p.Red.Bold(err.Error()))
|
||||
}
|
||||
} else {
|
||||
return errors.New(base + " path doesn't exist")
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// Ignore and validate a path
|
||||
func (p *Project) ignore(str string) bool {
|
||||
for _, v := range p.Watcher.Ignore {
|
||||
|
@ -388,20 +390,20 @@ func (p *Project) print(t string, o BufferOut, msg string, stream string) {
|
|||
switch t {
|
||||
case "out":
|
||||
p.Buffer.StdOut = append(p.Buffer.StdOut, o)
|
||||
if p.File.Streams {
|
||||
f := p.Create(p.base, p.parent.Resources.Streams)
|
||||
if p.Streams.FileOut {
|
||||
f := p.Create(p.base, p.parent.Resources.Outputs)
|
||||
t := time.Now()
|
||||
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, "")
|
||||
}
|
||||
}
|
||||
if msg != "" && p.Cli.Streams {
|
||||
if msg != "" && p.Streams.CliOut {
|
||||
log.Print(msg)
|
||||
}
|
||||
case "log":
|
||||
p.Buffer.StdLog = append(p.Buffer.StdLog, o)
|
||||
if p.File.Logs {
|
||||
if p.Streams.FileLog {
|
||||
f := p.Create(p.base, p.parent.Resources.Logs)
|
||||
t := time.Now()
|
||||
s := []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Text, "\r\n"}
|
||||
|
@ -417,7 +419,7 @@ func (p *Project) print(t string, o BufferOut, msg string, stream string) {
|
|||
}
|
||||
case "error":
|
||||
p.Buffer.StdErr = append(p.Buffer.StdErr, o)
|
||||
if p.File.Errors {
|
||||
if p.Streams.FileErr {
|
||||
f := p.Create(p.base, p.parent.Resources.Errors)
|
||||
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"}
|
||||
|
|
Loading…
Reference in New Issue