clean, config commands

doc improved
run command improved
This commit is contained in:
alessio 2016-12-27 00:14:29 +01:00
parent 40780b17f0
commit 558f8384cc
7 changed files with 263 additions and 207 deletions

View File

@ -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)

View File

@ -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
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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"}