From 3fc2d2cae6a6138f82f8593e47b2b9d0df1c9f95 Mon Sep 17 00:00:00 2001 From: alessio Date: Sat, 27 Aug 2016 17:02:13 +0200 Subject: [PATCH 01/30] doc fixed --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index cb25d7f..570cde1 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ A Go build system with file watchers, output streams and live reload. Run, build ``` If you want, you can specify additional arguments for your project. + **The additional arguments must go after the options of "Realize"** ``` From 121b6e58f2f22ba3cb04f22e1388202a6b3feeb2 Mon Sep 17 00:00:00 2001 From: alessio Date: Sat, 27 Aug 2016 17:13:38 +0200 Subject: [PATCH 02/30] config example improved --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 570cde1..69c16d5 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,7 @@ A Go build system with file watchers, output streams and live reload. Run, build app_bin: true -> enable/disable go install app_build: false -> enable/disable go build app_fmt: true -> enable/disable go fmt - app_params: + app_params: -> the project will be launched with these parameters - --flag1 - param1 app_watcher: From 7ba2833bf8f9ff437b1dd50e2cc18b23b82f6a28 Mon Sep 17 00:00:00 2001 From: alessio Date: Sat, 27 Aug 2016 22:36:11 +0200 Subject: [PATCH 03/30] lint --- realize/config.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/realize/config.go b/realize/config.go index 3166037..5156c6e 100644 --- a/realize/config.go +++ b/realize/config.go @@ -87,20 +87,20 @@ func WorkingDir() string { } // Duplicates check projects with same name or same combinations of main/path -func Duplicates(value Project, arr []Project) (error, Project) { +func Duplicates(value Project, arr []Project) (Project, error) { for _, val := range arr { if value.Path == val.Path || value.Name == val.Name { return errors.New("There is a duplicate of '" + val.Name + "'. Check your config file!"), val } } - return nil, Project{} + return Project{}, nil } // Clean duplicate projects func (h *Config) Clean() { arr := h.Projects for key, val := range arr { - if err, _ := Duplicates(val, arr[key+1:]); err != nil { + if _, err := Duplicates(val, arr[key+1:]); err != nil { h.Projects = append(arr[:key], arr[key+1:]...) break } @@ -154,7 +154,7 @@ func (h *Config) Add(params *cli.Context) error { Ignore: watcherIgnores, }, } - if err, _ := Duplicates(new, h.Projects); err != nil { + if _, err := Duplicates(new, h.Projects); err != nil { return err } h.Projects = append(h.Projects, new) From d01a01a25bb440c9a1b1e439f9b2590c9bcf351e Mon Sep 17 00:00:00 2001 From: alessio Date: Sat, 27 Aug 2016 22:37:46 +0200 Subject: [PATCH 04/30] lint --- realize/watcher.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/realize/watcher.go b/realize/watcher.go index a962dea..282338e 100644 --- a/realize/watcher.go +++ b/realize/watcher.go @@ -129,7 +129,7 @@ func (p *Project) install(channel chan bool, wr *sync.WaitGroup) { if p.Bin { log.Println(pname(p.Name, 1), ":", "Installing..") start := time.Now() - if err, std := p.GoInstall(); err != nil { + if std, err := p.GoInstall(); err != nil { log.Println(pname(p.Name, 1), ":", fmt.Sprint(Red(err)), std) wr.Done() } else { @@ -157,7 +157,7 @@ func (p *Project) build() { if p.Build { log.Println(pname(p.Name, 1), ":", "Building..") start := time.Now() - if err, std := p.GoBuild(); err != nil { + if std, err := p.GoBuild(); err != nil { log.Println(pname(p.Name, 1), ":", fmt.Sprint(Red(err)), std) } else { log.Println(pname(p.Name, 5), ":", Green("Builded")+" after", MagentaS(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), "s")) From 83a2add87ac83ea0bc97e62e11ab55a427b5f95c Mon Sep 17 00:00:00 2001 From: alessio Date: Sat, 27 Aug 2016 23:57:26 +0200 Subject: [PATCH 05/30] go test support --- main.go | 4 +++- realize/config.go | 4 +++- realize/project.go | 28 +++++++++++++++++++++------- realize/watcher.go | 15 +++++++++++++++ 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/main.go b/main.go index 2a529c1..65464ad 100644 --- a/main.go +++ b/main.go @@ -65,6 +65,7 @@ func main() { &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: "Enable the tests"}, &cli.BoolFlag{Name: "config", Value: false, Usage: "Take the defined settings if exist a config file."}, }, Action: func(p *cli.Context) error { @@ -84,10 +85,11 @@ func main() { Flags: []cli.Flag{ &cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: r.WorkingDir(), Usage: "Project name"}, &cli.StringFlag{Name: "path", Aliases: []string{"b"}, Value: "/", Usage: "Project base path"}, - &cli.BoolFlag{Name: "build", Value: false, Usage: "Enable go build"}, + &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: "Enable the tests"}, }, Action: func(p *cli.Context) error { y := r.New(p) diff --git a/realize/config.go b/realize/config.go index 5156c6e..ac6dd7e 100644 --- a/realize/config.go +++ b/realize/config.go @@ -32,6 +32,7 @@ func New(params *cli.Context) *Config { Bin: boolFlag(params.Bool("no-bin")), Run: boolFlag(params.Bool("no-run")), Fmt: boolFlag(params.Bool("no-fmt")), + Test: params.Bool("test"), Params: argsParam(params), Watcher: Watcher{ Paths: watcherPaths, @@ -90,7 +91,7 @@ func WorkingDir() string { func Duplicates(value Project, arr []Project) (Project, error) { for _, val := range arr { if value.Path == val.Path || value.Name == val.Name { - return errors.New("There is a duplicate of '" + val.Name + "'. Check your config file!"), val + return val, errors.New("There is a duplicate of '" + val.Name + "'. Check your config file!") } } return Project{}, nil @@ -147,6 +148,7 @@ func (h *Config) Add(params *cli.Context) error { Bin: boolFlag(params.Bool("no-bin")), Run: boolFlag(params.Bool("no-run")), Fmt: boolFlag(params.Bool("no-fmt")), + Test: params.Bool("test"), Params: argsParam(params), Watcher: Watcher{ Paths: watcherPaths, diff --git a/realize/project.go b/realize/project.go index 43461c2..de1896e 100644 --- a/realize/project.go +++ b/realize/project.go @@ -22,6 +22,7 @@ type Project struct { Bin bool `yaml:"app_bin,omitempty"` Build bool `yaml:"app_build,omitempty"` Fmt bool `yaml:"app_fmt,omitempty"` + Test bool `yaml:"app_test,omitempty"` Params []string `yaml:"app_params,omitempty"` Watcher Watcher `yaml:"app_watcher,omitempty"` } @@ -83,7 +84,7 @@ func (p *Project) GoRun(channel chan bool, runner chan bool, wr *sync.WaitGroup) } // GoBuild is an implementation of the "go build" -func (p *Project) GoBuild() (error, string) { +func (p *Project) GoBuild() (string, error) { var out bytes.Buffer var stderr bytes.Buffer build := exec.Command("go", "build") @@ -91,27 +92,27 @@ func (p *Project) GoBuild() (error, string) { build.Stdout = &out build.Stderr = &stderr if err := build.Run(); err != nil { - return err, stderr.String() + return stderr.String(), err } - return nil, "" + return "", nil } // GoInstall is an implementation of the "go install" -func (p *Project) GoInstall() (error, string) { +func (p *Project) GoInstall() (string, error) { var out bytes.Buffer var stderr bytes.Buffer err := os.Setenv("GOBIN", filepath.Join(os.Getenv("GOPATH"), "bin")) if err != nil { - return nil, "" + return "", nil } build := exec.Command("go", "install") build.Dir = p.base build.Stdout = &out build.Stderr = &stderr if err := build.Run(); err != nil { - return err, stderr.String() + return stderr.String(), err } - return nil, "" + return "", nil } // GoFmt is an implementation of the gofmt @@ -126,3 +127,16 @@ func (p *Project) GoFmt(path string) (io.Writer, error) { } return nil, nil } + +// GoTest is an implementation of the go test +func (p *Project) GoTest(path string) (io.Writer, error) { + var out bytes.Buffer + build := exec.Command("go", "test") + build.Dir = path + build.Stdout = &out + build.Stderr = &out + if err := build.Run(); err != nil { + return build.Stdout, err + } + return nil, nil +} diff --git a/realize/watcher.go b/realize/watcher.go index 282338e..54048a4 100644 --- a/realize/watcher.go +++ b/realize/watcher.go @@ -178,6 +178,16 @@ func (p *Project) fmt(path string) error { return nil } +// Build calls an implementation of the "go test" +func (p *Project) test(path string) error { + if p.Test { + if _, err := p.GoTest(path); err != nil { + log.Println(pname(p.Name, 1), Red("Go Test fails in "), ":", Magenta(path)) + } + } + return nil +} + // Walks the file tree of a project func (p *Project) walks(watcher *fsnotify.Watcher) { var files, folders int64 @@ -202,6 +212,11 @@ func (p *Project) walks(watcher *fsnotify.Watcher) { } else { folders++ + go func() { + if err := p.test(path); err != nil { + fmt.Println(err) + } + }() } } } From 551be782f50f0e63d8900909b568f94a296d3ab2 Mon Sep 17 00:00:00 2001 From: alessio Date: Sun, 28 Aug 2016 00:16:30 +0200 Subject: [PATCH 06/30] test support --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 69c16d5..dd585e5 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ A Go build system with file watchers, output streams and live reload. Run, build --name="Project Name" -> Name, if not specified takes the working directory name --path="server" -> Base Path, if not specified takes the working directory name --build -> Enables the build + --test -> Enables the tests --no-bin -> Disables the installation --no-run -> Disables the run --no-fmt -> Disables the fmt (go fmt) @@ -108,6 +109,7 @@ A Go build system with file watchers, output streams and live reload. Run, build ``` --build -> Enables the build + --test -> Enables the tests --no-bin -> Disables the installation --no-run -> Disables the run --no-fmt -> Disables the fmt (go fmt) @@ -144,6 +146,7 @@ A Go build system with file watchers, output streams and live reload. Run, build app_bin: true -> enable/disable go install app_build: false -> enable/disable go build app_fmt: true -> enable/disable go fmt + app_test: true -> enable/disable go test app_params: -> the project will be launched with these parameters - --flag1 - param1 @@ -180,7 +183,7 @@ A Go build system with file watchers, output streams and live reload. Run, build - [x] Support for multiple projects - [x] Watcher files preview - [x] Support for directories with duplicates names -- [ ] Go test support +- [x] Go test support - [x] Additional arguments - [x] Go fmt support - [x] Cli fast run From cef47d2527d6ce29e64e7ff66fe15e459184bc33 Mon Sep 17 00:00:00 2001 From: alessio Date: Mon, 29 Aug 2016 11:58:29 +0200 Subject: [PATCH 07/30] cli spinner v1.1 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index dd585e5..9959443 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,7 @@ A Go build system with file watchers, output streams and live reload. Run, build - [ ] Output files - [ ] Cli args - [ ] Before/After command +- [ ] Cli spinner #### Contacts From 71d0609bb029feca736dc19d60f5986fdb546efd Mon Sep 17 00:00:00 2001 From: alessio Date: Mon, 29 Aug 2016 18:44:27 +0200 Subject: [PATCH 08/30] milestone v1.1 updated --- README.md | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 9959443..82bc270 100644 --- a/README.md +++ b/README.md @@ -174,33 +174,14 @@ A Go build system with file watchers, output streams and live reload. Run, build - .go ``` -#### Next releases - -#####Milestone 1.0 - -- [x] Cli start, remove, add, list, run -- [x] Remove duplicate projects -- [x] Support for multiple projects -- [x] Watcher files preview -- [x] Support for directories with duplicates names -- [x] Go test support -- [x] Additional arguments -- [x] Go fmt support -- [x] Cli fast run -- [x] Execution times for build/install -- [x] Go doc -- [x] Support for server start/stop -- [x] Stream projects output -- [x] Cli feedback +#### Next release ##### Milestone 1.1 -- [ ] Test under windows -- [ ] Unit test -- [ ] Custom path on commands -- [ ] Output files -- [ ] Cli args -- [ ] Before/After command -- [ ] Cli spinner +- [ ] Testing on windows +- [ ] Custom paths for the commands fast/add +- [ ] Save output on a file +- [ ] Enable the fields Before/After +- [ ] Web interface on localhost - **Maybe** #### Contacts From 5ba1a26a65b5dbc788157baa428ceeaa0447a357 Mon Sep 17 00:00:00 2001 From: alessio Date: Mon, 29 Aug 2016 18:48:23 +0200 Subject: [PATCH 09/30] milestone v1.1 updated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 82bc270..b1217f8 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ A Go build system with file watchers, output streams and live reload. Run, build - [ ] Custom paths for the commands fast/add - [ ] Save output on a file - [ ] Enable the fields Before/After -- [ ] Web interface on localhost - **Maybe** +- [ ] Web interface - **Maybe** #### Contacts From b99917cc64e008a7855ad914a7c38c3ac38e47a3 Mon Sep 17 00:00:00 2001 From: alessio Date: Mon, 29 Aug 2016 18:48:42 +0200 Subject: [PATCH 10/30] milestone v1.1 updated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b1217f8..29228df 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ A Go build system with file watchers, output streams and live reload. Run, build - [ ] Custom paths for the commands fast/add - [ ] Save output on a file - [ ] Enable the fields Before/After -- [ ] Web interface - **Maybe** +- [ ] Web panel - **Maybe** #### Contacts From 62d5e80a8d1a7c5ddb489b7a2605b6387b128801 Mon Sep 17 00:00:00 2001 From: Daniele Conventi Date: Tue, 30 Aug 2016 15:58:02 +0200 Subject: [PATCH 11/30] Fixed link --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 29228df..37d98ce 100644 --- a/README.md +++ b/README.md @@ -72,9 +72,9 @@ A Go build system with file watchers, output streams and live reload. Run, build ``` $ realize add --name="My Project" --path="projects/package" --build --no-run ``` - + If you want, you can specify additional arguments for your project. - + **The additional arguments must go after the options of "Realize"** ``` @@ -82,7 +82,7 @@ A Go build system with file watchers, output streams and live reload. Run, build $ realize add yourParams --yourFlags --path="/print/printer" --no-run // wrong ``` - + - Remove a project by its name ``` @@ -104,7 +104,7 @@ A Go build system with file watchers, output streams and live reload. Run, build ``` $ realize fast ``` - + The fast command supports the following custom parameters: ``` @@ -115,7 +115,7 @@ A Go build system with file watchers, output streams and live reload. Run, build --no-fmt -> Disables the fmt (go fmt) --config -> Take the defined settings if exist a config file ``` - + The "fast" command supporst addittional arguments as the "add" command. ``` @@ -123,7 +123,7 @@ A Go build system with file watchers, output streams and live reload. Run, build $ realize fast yourParams --yourFlags --no-run // wrong ``` - + #### Color reference @@ -189,4 +189,4 @@ A Go build system with file watchers, output streams and live reload. Run, build - Chat with us [Gitter](https://gitter.im/tockins/realize) - [Alessio Pracchia](https://www.linkedin.com/in/alessio-pracchia-38a70673) -- [Daniele Conventi](https://www.linkedin.com/in/daniele-conventi-b419b0a4) +- [Daniele Conventi](https://www.linkedin.com/in/conventi) From 96f079fe467f1c282df8fe21fb8b87945f3e22e3 Mon Sep 17 00:00:00 2001 From: alessio Date: Tue, 30 Aug 2016 16:36:03 +0200 Subject: [PATCH 12/30] test field in list --- realize/config.go | 1 + 1 file changed, 1 insertion(+) diff --git a/realize/config.go b/realize/config.go index ac6dd7e..726a0ff 100644 --- a/realize/config.go +++ b/realize/config.go @@ -203,6 +203,7 @@ func (h *Config) List() error { fmt.Println(MagentaS("|"), "\t", Yellow("Build"), ":", MagentaS(val.Build)) fmt.Println(MagentaS("|"), "\t", Yellow("Install"), ":", MagentaS(val.Bin)) fmt.Println(MagentaS("|"), "\t", Yellow("Fmt"), ":", MagentaS(val.Fmt)) + fmt.Println(MagentaS("|"), "\t", Yellow("Test"), ":", MagentaS(val.Test)) fmt.Println(MagentaS("|"), "\t", Yellow("Params"), ":", MagentaS(val.Params)) fmt.Println(MagentaS("|"), "\t", Yellow("Watcher"), ":") fmt.Println(MagentaS("|"), "\t\t", Yellow("After"), ":", MagentaS(val.Watcher.After)) From 0fd83277d918869b2da44ea9d55eccf3e071abd8 Mon Sep 17 00:00:00 2001 From: alessio Date: Tue, 30 Aug 2016 16:37:35 +0200 Subject: [PATCH 13/30] watching msg fixed --- realize/watcher.go | 1 - 1 file changed, 1 deletion(-) diff --git a/realize/watcher.go b/realize/watcher.go index 54048a4..1743e3c 100644 --- a/realize/watcher.go +++ b/realize/watcher.go @@ -240,7 +240,6 @@ func (p *Project) walks(watcher *fsnotify.Watcher) { } } fmt.Println(Red("Watching: "), pname(p.Name, 1), Magenta(files), "file/s", Magenta(folders), "folder/s") - fmt.Println() } // Ignore validates a path From ef6f05d84cac2b1a93056c79827b5ca1616e7a81 Mon Sep 17 00:00:00 2001 From: alessio Date: Tue, 30 Aug 2016 19:27:47 +0200 Subject: [PATCH 14/30] custom path support --- README.md | 2 +- main.go | 2 ++ realize/watcher.go | 15 ++++++++++++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 37d98ce..96b0aa6 100644 --- a/README.md +++ b/README.md @@ -178,7 +178,7 @@ A Go build system with file watchers, output streams and live reload. Run, build ##### Milestone 1.1 - [ ] Testing on windows -- [ ] Custom paths for the commands fast/add +- [x] Custom paths for the commands fast/add - [ ] Save output on a file - [ ] Enable the fields Before/After - [ ] Web panel - **Maybe** diff --git a/main.go b/main.go index 65464ad..5e2a0b7 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main import ( "fmt" r "github.com/tockins/realize/realize" + _ "github.com/tockins/realize/server" "gopkg.in/urfave/cli.v2" "log" "os" @@ -61,6 +62,7 @@ func main() { Name: "fast", Usage: "Build and watch file changes for a single project without any 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"}, diff --git a/realize/watcher.go b/realize/watcher.go index 1743e3c..343633b 100644 --- a/realize/watcher.go +++ b/realize/watcher.go @@ -1,6 +1,7 @@ package realize import ( + "errors" "fmt" "github.com/fsnotify/fsnotify" "gopkg.in/urfave/cli.v2" @@ -78,7 +79,11 @@ func (p *Project) watching() { } defer end() - p.walks(watcher) + err = p.walks(watcher) + if err != nil { + fmt.Println(pname(p.Name, 1), ":", Red(err.Error())) + return + } go routines(p, channel, &wr) p.reload = time.Now().Truncate(time.Second) @@ -189,7 +194,7 @@ func (p *Project) test(path string) error { } // Walks the file tree of a project -func (p *Project) walks(watcher *fsnotify.Watcher) { +func (p *Project) walks(watcher *fsnotify.Watcher) error { var files, folders int64 wd, _ := os.Getwd() @@ -226,9 +231,12 @@ func (p *Project) walks(watcher *fsnotify.Watcher) { if p.Path == "." || p.Path == "/" { p.base = wd p.Path = WorkingDir() + } 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 { @@ -236,10 +244,11 @@ func (p *Project) walks(watcher *fsnotify.Watcher) { log.Println(Red(err.Error())) } } else { - fmt.Println(pname(p.Name, 1), ":\t", Red(base+" path doesn't exist")) + return errors.New(base + " path doesn't exist") } } fmt.Println(Red("Watching: "), pname(p.Name, 1), Magenta(files), "file/s", Magenta(folders), "folder/s") + return nil } // Ignore validates a path From 52b7bf231e2db2966167967b9594ecb26432e699 Mon Sep 17 00:00:00 2001 From: alessio Date: Tue, 30 Aug 2016 19:33:25 +0200 Subject: [PATCH 15/30] custom paths doc --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 96b0aa6..7d9d61d 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ A Go build system with file watchers, output streams and live reload. Run, build --name="Project Name" -> Name, if not specified takes the working directory name --path="server" -> Base Path, if not specified takes the working directory name --build -> Enables the build - --test -> Enables the tests + --test -> Enables the tests --no-bin -> Disables the installation --no-run -> Disables the run --no-fmt -> Disables the fmt (go fmt) @@ -59,18 +59,16 @@ A Go build system with file watchers, output streams and live reload. Run, build ``` $ realize add - ``` - ``` + $ realize add --path="mypath" - ``` - ``` + $ realize add --name="My Project" --build - ``` - ``` + $ realize add --name="My Project" --path="/projects/package" --build - ``` - ``` + $ realize add --name="My Project" --path="projects/package" --build --no-run + + $ realize add --path="/Users/alessio/go/src/github.com/tockins/realize-examples/coin/" ``` If you want, you can specify additional arguments for your project. @@ -116,12 +114,14 @@ A Go build system with file watchers, output streams and live reload. Run, build --config -> Take the defined settings if exist a config file ``` - The "fast" command supporst addittional arguments as the "add" command. + The "fast" command supports addittional arguments as the "add" command. ``` $ realize fast --no-run yourParams --yourFlags // correct $ realize fast yourParams --yourFlags --no-run // wrong + + $ realize fast --path="/Users/alessio/go/src/github.com/tockins/realize-examples/coin/" ``` From d03f5c5a7f61fccae01acc098200ac7a84877a93 Mon Sep 17 00:00:00 2001 From: alessio Date: Tue, 30 Aug 2016 19:44:26 +0200 Subject: [PATCH 16/30] bug fix, custom path released #17 fixed --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 5e2a0b7..43abbe6 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,7 @@ package main import ( "fmt" r "github.com/tockins/realize/realize" - _ "github.com/tockins/realize/server" + //_ "github.com/tockins/realize/server" "gopkg.in/urfave/cli.v2" "log" "os" From 38bd1f8ba54843d5ba7e94cfa8b03efefe1fa473 Mon Sep 17 00:00:00 2001 From: alessio Date: Wed, 31 Aug 2016 14:08:15 +0200 Subject: [PATCH 17/30] output file, code clean --- main.go | 30 ++-- realize/app.go | 63 ++------ realize/blueprint.go | 225 +++++++++++++++++++++++++++++ realize/config.go | 219 ---------------------------- realize/{project.go => execute.go} | 28 ++-- realize/utils.go | 130 +++++++++++++++++ realize/watcher.go | 90 ++---------- 7 files changed, 404 insertions(+), 381 deletions(-) create mode 100644 realize/blueprint.go delete mode 100644 realize/config.go rename realize/{project.go => execute.go} (81%) create mode 100644 realize/utils.go diff --git a/main.go b/main.go index 43abbe6..e6c027d 100644 --- a/main.go +++ b/main.go @@ -11,7 +11,7 @@ import ( func main() { - app := r.Info() + app := r.App handle := func(err error) error { if err != nil { @@ -50,8 +50,7 @@ func main() { Name: "run", Usage: "Build and watch file changes", Action: func(p *cli.Context) error { - y := r.New(p) - return handle(y.Watch()) + return handle(app.Blueprint.Run()) }, Before: func(c *cli.Context) error { header() @@ -60,7 +59,7 @@ func main() { }, { Name: "fast", - Usage: "Build and watch file changes for a single project without any config file", + Usage: "Build and watch file changes for a single project without any Configuration 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"}, @@ -68,11 +67,11 @@ func main() { &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: "Enable the tests"}, - &cli.BoolFlag{Name: "config", Value: false, Usage: "Take the defined settings if exist a config file."}, + &cli.BoolFlag{Name: "Configuration", Value: false, Usage: "Take the defined settings if exist a Configuration file."}, }, Action: func(p *cli.Context) error { - y := r.New(p) - return handle(y.Fast(p)) + app.Blueprint.Add(p) + return handle(app.Blueprint.Fast(p)) }, Before: func(c *cli.Context) error { header() @@ -81,11 +80,11 @@ func main() { }, { Name: "add", - Category: "config", + Category: "Configuration", Aliases: []string{"a"}, Usage: "Add another project", Flags: []cli.Flag{ - &cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: r.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.BoolFlag{Name: "build", Value: false, Usage: "Enable the build"}, &cli.BoolFlag{Name: "no-run", Usage: "Disables the run"}, @@ -94,8 +93,7 @@ func main() { &cli.BoolFlag{Name: "test", Value: false, Usage: "Enable the tests"}, }, Action: func(p *cli.Context) error { - y := r.New(p) - return handle(y.Add(p)) + return handle(app.Blueprint.Insert(p)) }, Before: func(c *cli.Context) error { header() @@ -104,15 +102,14 @@ func main() { }, { Name: "remove", - Category: "config", + Category: "Configuration", Aliases: []string{"r"}, Usage: "Remove a project", Flags: []cli.Flag{ &cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: ""}, }, Action: func(p *cli.Context) error { - y := r.New(p) - return handle(y.Remove(p)) + return handle(app.Blueprint.Remove(p)) }, Before: func(c *cli.Context) error { header() @@ -121,12 +118,11 @@ func main() { }, { Name: "list", - Category: "config", + Category: "Configuration", Aliases: []string{"l"}, Usage: "Projects list", Action: func(p *cli.Context) error { - y := r.New(p) - return handle(y.List()) + return handle(app.Blueprint.List()) }, Before: func(c *cli.Context) error { header() diff --git a/realize/app.go b/realize/app.go index b659f46..879fb9c 100644 --- a/realize/app.go +++ b/realize/app.go @@ -1,21 +1,12 @@ package realize import ( - "fmt" "github.com/fatih/color" "log" "sync" - "syscall" - "time" ) -// Default values and info -const ( - AppName = "Realize" - AppVersion = "v1.0" - AppDescription = "A Go build system with file watchers, output streams and live reload. Run, build and watch file changes with custom paths" - AppFile = "realize.config.yaml" -) +var App Realize var wg sync.WaitGroup @@ -46,47 +37,19 @@ var MagentaS = color.New(color.FgMagenta).SprintFunc() // Magenta color bold var Magenta = color.New(color.FgMagenta, color.Bold).SprintFunc() -// WatcherIgnores is an array of default ignored paths -var watcherIgnores = []string{"vendor", "bin"} - -// WatcherExts is an array of default exts -var watcherExts = []string{".go"} - -// WatcherPaths is an array of default watched paths -var watcherPaths = []string{"/"} - -type logWriter struct{} - -// App struct contains the informations about realize -type App struct { - Name, Version, Description, Author, Email string -} - -// Custom log timestamp +// Initialize the application func init() { + App = Realize{ + Name: "Realize", + Version: "1.0", + Description: "A Go build system with file watchers, output streams and live reload. Run, build and watch file changes with custom paths", + Limit: 10000, + } + App.Blueprint.files = map[string]string{ + "config": "r.config.yaml", + "output": "r.output.log", + } + App.limit() log.SetFlags(0) log.SetOutput(new(logWriter)) - - // increases the files limit - var rLimit syscall.Rlimit - rLimit.Max = 10000 - rLimit.Cur = 10000 - err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) - if err != nil { - fmt.Println(Red("Error Setting Rlimit "), err) - } -} - -// Info returns the general informations about Realize -func Info() *App { - return &App{ - Name: AppName, - Version: AppVersion, - Description: AppDescription, - } -} - -// Cewrites the log timestamp -func (writer logWriter) Write(bytes []byte) (int, error) { - return fmt.Print(YellowS("[") + time.Now().Format("15:04:05") + YellowS("]") + string(bytes)) } diff --git a/realize/blueprint.go b/realize/blueprint.go new file mode 100644 index 0000000..88e2433 --- /dev/null +++ b/realize/blueprint.go @@ -0,0 +1,225 @@ +package realize + +import ( + "errors" + "fmt" + "gopkg.in/urfave/cli.v2" + "gopkg.in/yaml.v2" + "log" + "os" + "path/filepath" + "strings" + "syscall" + "time" +) + +// App struct contains the informations about realize +type Realize struct { + Name, Description, Author, Email string + Version string `yaml:"version,omitempty"` + Limit uint64 + Blueprint Blueprint +} + +// Projects struct contains a projects list +type Blueprint struct { + Projects []Project `yaml:"projects,omitempty"` + files map[string]string +} + +// Project defines the informations of a single project +type Project struct { + reload time.Time + base string + Name string `yaml:"app_name,omitempty"` + Path string `yaml:"app_path,omitempty"` + Run bool `yaml:"app_run,omitempty"` + Bin bool `yaml:"app_bin,omitempty"` + Build bool `yaml:"app_build,omitempty"` + Fmt bool `yaml:"app_fmt,omitempty"` + Test bool `yaml:"app_test,omitempty"` + Params []string `yaml:"app_params,omitempty"` + Watcher Watcher `yaml:"app_watcher,omitempty"` +} + +// Wdir returns the name last element of the working directory path +func (r *Realize) Wdir() string { + dir, err := os.Getwd() + if err != nil { + log.Fatal(Red(err)) + } + return filepath.Base(dir) +} + +// Limit defines the max number of watched files +func (r *Realize) limit() { + // increases the files limit + var rLimit syscall.Rlimit + rLimit.Max = r.Limit + rLimit.Cur = r.Limit + err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) + if err != nil { + fmt.Println(Red("Error Setting Rlimit "), err) + } +} + +// Watch method adds the given paths on the Watcher +func (h *Blueprint) Run() error { + err := h.Read() + if err == nil { + // loop projects + wg.Add(len(h.Projects)) + for k := range h.Projects { + go h.Projects[k].watching() + } + wg.Wait() + return nil + } + return err +} + +// Fast method run a project from his working directory without makes a config file +func (h *Blueprint) Fast(params *cli.Context) error { + fast := h.Projects[0] + // Takes the values from config if wd path match with someone else + if params.Bool("config") { + if err := h.Read(); err == nil { + for _, val := range h.Projects { + if fast.Path == val.Path { + fast = val + } + } + } + } + wg.Add(1) + go fast.watching() + wg.Wait() + return nil +} + +// Add a new project +func (h *Blueprint) Add(params *cli.Context) error { + p := Project{ + Name: nameFlag(params), + Path: filepath.Clean(params.String("path")), + Build: params.Bool("build"), + Bin: boolFlag(params.Bool("no-bin")), + Run: boolFlag(params.Bool("no-run")), + Fmt: boolFlag(params.Bool("no-fmt")), + Test: params.Bool("test"), + Params: argsParam(params), + Watcher: Watcher{ + Paths: []string{"/"}, + Ignore: []string{"vendor"}, + Exts: []string{".go"}, + Output: map[string]bool{ + "cli": true, + "file": false, + }, + }, + } + if _, err := duplicates(p, h.Projects); err != nil { + return err + } + h.Projects = append(h.Projects, p) + return nil +} + +// Clean duplicate projects +func (h *Blueprint) Clean() { + arr := h.Projects + for key, val := range arr { + if _, err := duplicates(val, arr[key+1:]); err != nil { + h.Projects = append(arr[:key], arr[key+1:]...) + break + } + } +} + +// Read, Check and remove duplicates from the config file +func (h *Blueprint) Read() error { + content, err := read(h.files["config"]) + if err == nil { + err = yaml.Unmarshal(content, h) + if err == nil { + if len(h.Projects) > 0 { + h.Clean() + return nil + } + return errors.New("There are no projects!") + } + return err + } + return err +} + +// Create and unmarshal yaml config file +func (h *Blueprint) Create() error { + y, err := yaml.Marshal(h) + if err != nil { + return err + } + return write(h.files["config"], y) +} + +// Inserts a new project in the list +func (h *Blueprint) Insert(params *cli.Context) error { + check := h.Read() + err := h.Add(params) + if err == nil { + err = h.Create() + if check == nil && err == nil { + fmt.Println(Green("Your project was successfully added")) + } else { + fmt.Println(Green("The config file was successfully created")) + } + } + return err +} + +// Remove a project +func (h *Blueprint) Remove(params *cli.Context) error { + err := h.Read() + if err == nil { + for key, val := range h.Projects { + if params.String("name") == val.Name { + h.Projects = append(h.Projects[:key], h.Projects[key+1:]...) + err = h.Create() + if err == nil { + fmt.Println(Green("Your project was successfully removed")) + } + return err + } + } + return errors.New("No project found") + } + return err +} + +// List of all the projects +func (h *Blueprint) List() error { + err := h.Read() + if err == nil { + for _, val := range h.Projects { + fmt.Println(Blue("|"), Blue(strings.ToUpper(val.Name))) + fmt.Println(MagentaS("|"), "\t", Yellow("Base Path"), ":", MagentaS(val.Path)) + fmt.Println(MagentaS("|"), "\t", Yellow("Run"), ":", MagentaS(val.Run)) + fmt.Println(MagentaS("|"), "\t", Yellow("Build"), ":", MagentaS(val.Build)) + fmt.Println(MagentaS("|"), "\t", Yellow("Install"), ":", MagentaS(val.Bin)) + fmt.Println(MagentaS("|"), "\t", Yellow("Fmt"), ":", MagentaS(val.Fmt)) + fmt.Println(MagentaS("|"), "\t", Yellow("Test"), ":", MagentaS(val.Test)) + fmt.Println(MagentaS("|"), "\t", Yellow("Params"), ":", MagentaS(val.Params)) + fmt.Println(MagentaS("|"), "\t", Yellow("Watcher"), ":") + fmt.Println(MagentaS("|"), "\t\t", Yellow("After"), ":", MagentaS(val.Watcher.After)) + fmt.Println(MagentaS("|"), "\t\t", Yellow("Before"), ":", MagentaS(val.Watcher.Before)) + fmt.Println(MagentaS("|"), "\t\t", Yellow("Extensions"), ":", MagentaS(val.Watcher.Exts)) + fmt.Println(MagentaS("|"), "\t\t", Yellow("Paths"), ":", MagentaS(val.Watcher.Paths)) + fmt.Println(MagentaS("|"), "\t\t", Yellow("Paths ignored"), ":", MagentaS(val.Watcher.Ignore)) + fmt.Println(MagentaS("|"), "\t\t", Yellow("Watch preview"), ":", MagentaS(val.Watcher.Preview)) + fmt.Println(MagentaS("|"), "\t\t", Yellow("Output"), ":") + fmt.Println(MagentaS("|"), "\t\t\t", Yellow("Cli"), ":", MagentaS(val.Watcher.Output["cli"])) + fmt.Println(MagentaS("|"), "\t\t\t", Yellow("File"), ":", MagentaS(val.Watcher.Output["file"])) + } + } + return err +} diff --git a/realize/config.go b/realize/config.go deleted file mode 100644 index 726a0ff..0000000 --- a/realize/config.go +++ /dev/null @@ -1,219 +0,0 @@ -package realize - -import ( - "errors" - "fmt" - "gopkg.in/urfave/cli.v2" - "gopkg.in/yaml.v2" - "io/ioutil" - "log" - "os" - "path/filepath" - "strings" -) - -// Config struct contains the general informations about a project -type Config struct { - file string - Version string `yaml:"version,omitempty"` - Projects []Project -} - -// New method puts the cli params in the struct -func New(params *cli.Context) *Config { - return &Config{ - file: AppFile, - Version: AppVersion, - Projects: []Project{ - { - Name: nameFlag(params), - Path: filepath.Clean(params.String("path")), - Build: params.Bool("build"), - Bin: boolFlag(params.Bool("no-bin")), - Run: boolFlag(params.Bool("no-run")), - Fmt: boolFlag(params.Bool("no-fmt")), - Test: params.Bool("test"), - Params: argsParam(params), - Watcher: Watcher{ - Paths: watcherPaths, - Ignore: watcherIgnores, - Exts: watcherExts, - }, - }, - }, - } -} - -// argsParam parse one by one the given argumentes -func argsParam(params *cli.Context) []string { - argsN := params.NArg() - if argsN > 0 { - var args []string - for i := 0; i <= argsN-1; i++ { - args = append(args, params.Args().Get(i)) - } - return args - } - return nil -} - -// NameParam check the project name presence. If empty takes the working directory name -func nameFlag(params *cli.Context) string { - var name string - if params.String("name") == "" && params.String("path") == "" { - return WorkingDir() - } else if params.String("path") != "/" { - name = filepath.Base(params.String("path")) - } else { - name = params.String("name") - } - return name -} - -// BoolParam is used to check the presence of a bool flag -func boolFlag(b bool) bool { - if b { - return false - } - return true -} - -// WorkingDir returns the last element of the working dir path -func WorkingDir() string { - dir, err := os.Getwd() - if err != nil { - log.Fatal(Red(err)) - } - return filepath.Base(dir) -} - -// Duplicates check projects with same name or same combinations of main/path -func Duplicates(value Project, arr []Project) (Project, error) { - for _, val := range arr { - if value.Path == val.Path || value.Name == val.Name { - return val, errors.New("There is a duplicate of '" + val.Name + "'. Check your config file!") - } - } - return Project{}, nil -} - -// Clean duplicate projects -func (h *Config) Clean() { - arr := h.Projects - for key, val := range arr { - if _, err := Duplicates(val, arr[key+1:]); err != nil { - h.Projects = append(arr[:key], arr[key+1:]...) - break - } - } -} - -// Read, Check and remove duplicates from the config file -func (h *Config) Read() error { - _, err := os.Stat(h.file) - if err == nil { - file, err := ioutil.ReadFile(h.file) - if err == nil { - if len(h.Projects) > 0 { - err = yaml.Unmarshal(file, h) - if err == nil { - h.Clean() - } - return err - } - return errors.New("There are no projects") - } - return h.Create() - } - return err -} - -// Create and unmarshal yaml config file -func (h *Config) Create() error { - y, err := yaml.Marshal(h) - if err != nil { - return err - } - return ioutil.WriteFile(h.file, y, 0655) -} - -// Add another project -func (h *Config) Add(params *cli.Context) error { - err := h.Read() - if err == nil { - new := Project{ - Name: nameFlag(params), - Path: filepath.Clean(params.String("path")), - Build: params.Bool("build"), - Bin: boolFlag(params.Bool("no-bin")), - Run: boolFlag(params.Bool("no-run")), - Fmt: boolFlag(params.Bool("no-fmt")), - Test: params.Bool("test"), - Params: argsParam(params), - Watcher: Watcher{ - Paths: watcherPaths, - Exts: watcherExts, - Ignore: watcherIgnores, - }, - } - if _, err := Duplicates(new, h.Projects); err != nil { - return err - } - h.Projects = append(h.Projects, new) - err = h.Create() - if err == nil { - fmt.Println(Green("Your project was successfully added")) - } - return err - } - err = h.Create() - if err == nil { - fmt.Println(Green("The config file was successfully created")) - } - return err -} - -// Remove a project in list -func (h *Config) Remove(params *cli.Context) error { - err := h.Read() - if err == nil { - for key, val := range h.Projects { - if params.String("name") == val.Name { - h.Projects = append(h.Projects[:key], h.Projects[key+1:]...) - err = h.Create() - if err == nil { - fmt.Println(Green("Your project was successfully removed")) - } - return err - } - } - return errors.New("No project found") - } - return err -} - -// List of projects -func (h *Config) List() error { - err := h.Read() - if err == nil { - for _, val := range h.Projects { - fmt.Println(Blue("|"), Blue(strings.ToUpper(val.Name))) - fmt.Println(MagentaS("|"), "\t", Yellow("Base Path"), ":", MagentaS(val.Path)) - fmt.Println(MagentaS("|"), "\t", Yellow("Run"), ":", MagentaS(val.Run)) - fmt.Println(MagentaS("|"), "\t", Yellow("Build"), ":", MagentaS(val.Build)) - fmt.Println(MagentaS("|"), "\t", Yellow("Install"), ":", MagentaS(val.Bin)) - fmt.Println(MagentaS("|"), "\t", Yellow("Fmt"), ":", MagentaS(val.Fmt)) - fmt.Println(MagentaS("|"), "\t", Yellow("Test"), ":", MagentaS(val.Test)) - fmt.Println(MagentaS("|"), "\t", Yellow("Params"), ":", MagentaS(val.Params)) - fmt.Println(MagentaS("|"), "\t", Yellow("Watcher"), ":") - fmt.Println(MagentaS("|"), "\t\t", Yellow("After"), ":", MagentaS(val.Watcher.After)) - fmt.Println(MagentaS("|"), "\t\t", Yellow("Before"), ":", MagentaS(val.Watcher.Before)) - fmt.Println(MagentaS("|"), "\t\t", Yellow("Extensions"), ":", MagentaS(val.Watcher.Exts)) - fmt.Println(MagentaS("|"), "\t\t", Yellow("Paths"), ":", MagentaS(val.Watcher.Paths)) - fmt.Println(MagentaS("|"), "\t\t", Yellow("Paths ignored"), ":", MagentaS(val.Watcher.Ignore)) - fmt.Println(MagentaS("|"), "\t\t", Yellow("Watch preview"), ":", MagentaS(val.Watcher.Preview)) - } - return nil - } - return err -} diff --git a/realize/project.go b/realize/execute.go similarity index 81% rename from realize/project.go rename to realize/execute.go index de1896e..aded846 100644 --- a/realize/project.go +++ b/realize/execute.go @@ -12,21 +12,6 @@ import ( "time" ) -// The Project struct defines the informations about a project -type Project struct { - reload time.Time - base string - Name string `yaml:"app_name,omitempty"` - Path string `yaml:"app_path,omitempty"` - Run bool `yaml:"app_run,omitempty"` - Bin bool `yaml:"app_bin,omitempty"` - Build bool `yaml:"app_build,omitempty"` - Fmt bool `yaml:"app_fmt,omitempty"` - Test bool `yaml:"app_test,omitempty"` - Params []string `yaml:"app_params,omitempty"` - Watcher Watcher `yaml:"app_watcher,omitempty"` -} - // GoRun is an implementation of the bin execution func (p *Project) GoRun(channel chan bool, runner chan bool, wr *sync.WaitGroup) error { @@ -51,7 +36,6 @@ func (p *Project) GoRun(channel chan bool, runner chan bool, wr *sync.WaitGroup) // Read stdout and stderr in same var outputs := io.MultiReader(stdout, stderr) - if err != nil { log.Println(Red(err.Error())) return err @@ -67,7 +51,17 @@ func (p *Project) GoRun(channel chan bool, runner chan bool, wr *sync.WaitGroup) for in.Scan() { select { default: - log.Println(pname(p.Name, 3), ":", BlueS(in.Text())) + if p.Watcher.Output["cli"] { + log.Println(pname(p.Name, 3), ":", BlueS(in.Text())) + } + if p.Watcher.Output["file"] { + path := filepath.Join(p.base, App.Blueprint.files["output"]) + f := create(path) + t := time.Now() + if _, err := f.WriteString(t.Format("2006-01-02 15:04:05") + " : " + in.Text() + "\r\n"); err != nil { + log.Fatal(err) + } + } } } close(stop) diff --git a/realize/utils.go b/realize/utils.go new file mode 100644 index 0000000..b0a7ea3 --- /dev/null +++ b/realize/utils.go @@ -0,0 +1,130 @@ +package realize + +import ( + "errors" + "fmt" + "gopkg.in/urfave/cli.v2" + "io/ioutil" + "log" + "os" + "path/filepath" + "strings" + "time" +) + +// Read a file given a name and return its byte stream +func read(file string) ([]byte, error) { + _, err := os.Stat(file) + if err == nil { + content, err := ioutil.ReadFile(file) + if err != nil { + return nil, err + } + return content, err + } + return nil, err + +} + +// Write a file given a name and a byte stream +func write(name string, data []byte) error { + err := ioutil.WriteFile(name, data, 0655) + if err != nil { + log.Fatal(err) + return err + } + return nil +} + +// Create a new file and return its pointer +func create(file string) *os.File { + out, err := os.OpenFile(file, os.O_APPEND|os.O_WRONLY|os.O_CREATE|os.O_SYNC, 0655) + if err != nil { + log.Fatal(err) + } + return out +} + +// argsParam parse one by one the given argumentes +func argsParam(params *cli.Context) []string { + argsN := params.NArg() + if argsN > 0 { + var args []string + for i := 0; i <= argsN-1; i++ { + args = append(args, params.Args().Get(i)) + } + return args + } + return nil +} + +// NameParam check the project name presence. If empty takes the working directory name +func nameFlag(params *cli.Context) string { + var name string + if params.String("name") == "" && params.String("path") == "" { + return App.Wdir() + } else if params.String("path") != "/" { + name = filepath.Base(params.String("path")) + } else { + name = params.String("name") + } + return name +} + +// BoolParam is used to check the presence of a bool flag +func boolFlag(b bool) bool { + if b { + return false + } + return true +} + +// Duplicates check projects with same name or same combinations of main/path +func duplicates(value Project, arr []Project) (Project, error) { + for _, val := range arr { + if value.Path == val.Path || value.Name == val.Name { + return val, errors.New("There is a duplicate of '" + val.Name + "'. Check your config file!") + } + } + return Project{}, nil +} + +// check if a string is inArray +func inArray(str string, list []string) bool { + for _, v := range list { + if v == str { + return true + } + } + return false +} + +// Defines the colors scheme for the project name +func pname(name string, color int) string { + switch color { + case 1: + name = Yellow("[") + strings.ToUpper(name) + Yellow("]") + break + case 2: + name = Yellow("[") + Red(strings.ToUpper(name)) + Yellow("]") + break + case 3: + name = Yellow("[") + Blue(strings.ToUpper(name)) + Yellow("]") + break + case 4: + name = Yellow("[") + Magenta(strings.ToUpper(name)) + Yellow("]") + break + case 5: + name = Yellow("[") + Green(strings.ToUpper(name)) + Yellow("]") + break + } + return name +} + +// Log struct +type logWriter struct{} + +// Cewrites the log timestamp +func (writer logWriter) Write(bytes []byte) (int, error) { + return fmt.Print(YellowS("[") + time.Now().Format("15:04:05") + YellowS("]") + string(bytes)) +} diff --git a/realize/watcher.go b/realize/watcher.go index 343633b..6e8df4f 100644 --- a/realize/watcher.go +++ b/realize/watcher.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "github.com/fsnotify/fsnotify" - "gopkg.in/urfave/cli.v2" "log" "math/big" "os" @@ -17,46 +16,13 @@ import ( // The Watcher struct defines the livereload's logic type Watcher struct { // different before and after on re-run? - Before []string `yaml:"before,omitempty"` - After []string `yaml:"after,omitempty"` - Paths []string `yaml:"paths,omitempty"` - Ignore []string `yaml:"ignore_paths,omitempty"` - Exts []string `yaml:"exts,omitempty"` - Preview bool `yaml:"preview,omitempty"` -} - -// Watch method adds the given paths on the Watcher -func (h *Config) Watch() error { - err := h.Read() - if err == nil { - // loop projects - wg.Add(len(h.Projects)) - for k := range h.Projects { - go h.Projects[k].watching() - } - wg.Wait() - return nil - } - return err -} - -// Fast method run a project from his working directory without makes a config file -func (h *Config) Fast(params *cli.Context) error { - fast := h.Projects[0] - // Takes the values from config if wd path match with someone else - if params.Bool("config") { - if err := h.Read(); err == nil { - for _, val := range h.Projects { - if fast.Path == val.Path { - fast = val - } - } - } - } - wg.Add(1) - go fast.watching() - wg.Wait() - return nil + Before []string `yaml:"before,omitempty"` + After []string `yaml:"after,omitempty"` + Paths []string `yaml:"paths,omitempty"` + Ignore []string `yaml:"ignore_paths,omitempty"` + Exts []string `yaml:"exts,omitempty"` + Preview bool `yaml:"preview,omitempty"` + Output map[string]bool `yaml:"output,omitempty"` } // Watching method is the main core. It manages the livereload and the watching @@ -84,7 +50,7 @@ func (p *Project) watching() { fmt.Println(pname(p.Name, 1), ":", Red(err.Error())) return } - go routines(p, channel, &wr) + go p.routines(channel, &wr) p.reload = time.Now().Truncate(time.Second) // waiting for an event @@ -117,7 +83,7 @@ func (p *Project) watching() { if err != nil { log.Fatal(Red(err)) } else { - go routines(p, channel, &wr) + go p.routines(channel, &wr) p.reload = time.Now().Truncate(time.Second) } } @@ -230,7 +196,7 @@ func (p *Project) walks(watcher *fsnotify.Watcher) error { if p.Path == "." || p.Path == "/" { p.base = wd - p.Path = WorkingDir() + p.Path = App.Wdir() } else if filepath.IsAbs(p.Path) { p.base = p.Path } else { @@ -247,7 +213,7 @@ func (p *Project) walks(watcher *fsnotify.Watcher) error { return errors.New(base + " path doesn't exist") } } - fmt.Println(Red("Watching: "), pname(p.Name, 1), Magenta(files), "file/s", Magenta(folders), "folder/s") + fmt.Println(Red("Watching"), ":", pname(p.Name, 1), Magenta(files), "file/s", Magenta(folders), "folder/s") return nil } @@ -262,41 +228,9 @@ func (p *Project) ignore(str string) bool { } // Routines launches the following methods: run, build, fmt, install -func routines(p *Project, channel chan bool, wr *sync.WaitGroup) { +func (p *Project) routines(channel chan bool, wr *sync.WaitGroup) { wr.Add(1) go p.build() go p.install(channel, wr) wr.Wait() } - -// check if a string is inArray -func inArray(str string, list []string) bool { - for _, v := range list { - if v == str { - return true - } - } - return false -} - -// defines the colors scheme for the project name -func pname(name string, color int) string { - switch color { - case 1: - name = Yellow("[") + strings.ToUpper(name) + Yellow("]") - break - case 2: - name = Yellow("[") + Red(strings.ToUpper(name)) + Yellow("]") - break - case 3: - name = Yellow("[") + Blue(strings.ToUpper(name)) + Yellow("]") - break - case 4: - name = Yellow("[") + Magenta(strings.ToUpper(name)) + Yellow("]") - break - case 5: - name = Yellow("[") + Green(strings.ToUpper(name)) + Yellow("]") - break - } - return name -} From 613cb8e5903fb8edc538372c9a21749e35a0581b Mon Sep 17 00:00:00 2001 From: alessio Date: Wed, 31 Aug 2016 14:14:09 +0200 Subject: [PATCH 18/30] output support doc --- README.md | 20 +++++--------------- realize/blueprint.go | 4 ++-- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 7d9d61d..35cae89 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,6 @@ A Go build system with file watchers, output streams and live reload. Run, build - For more examples check [Realize Examples](https://github.com/tockins/realize-examples) ``` - version: "1.0" projects: - app_name: App One -> name app_path: one -> root path @@ -159,19 +158,10 @@ A Go build system with file watchers, output streams and live reload. Run, build - bin exts: -> file extensions to observe for live reload - .go - - app_name: App Two -> another project - app_path: two - app_run: true - app_build: true - app_bin: true - app_watcher: - paths: - - / - ignore_paths: - - vendor - - bin - exts: - - .go + output: -> enable/disable the output destinations + cli: true -> cli output + file: true -> creates an output file inside the project + ``` #### Next release @@ -179,7 +169,7 @@ A Go build system with file watchers, output streams and live reload. Run, build ##### Milestone 1.1 - [ ] Testing on windows - [x] Custom paths for the commands fast/add -- [ ] Save output on a file +- [x] Save output on a file - [ ] Enable the fields Before/After - [ ] Web panel - **Maybe** diff --git a/realize/blueprint.go b/realize/blueprint.go index 88e2433..3e18d94 100644 --- a/realize/blueprint.go +++ b/realize/blueprint.go @@ -16,14 +16,14 @@ import ( // App struct contains the informations about realize type Realize struct { Name, Description, Author, Email string - Version string `yaml:"version,omitempty"` + Version string Limit uint64 Blueprint Blueprint } // Projects struct contains a projects list type Blueprint struct { - Projects []Project `yaml:"projects,omitempty"` + Projects []Project `yaml:"Projects,omitempty"` files map[string]string } From 98439141b7a298e4988fe3ffe8e06fd4d1ad6974 Mon Sep 17 00:00:00 2001 From: alessio Date: Thu, 1 Sep 2016 18:05:40 +0200 Subject: [PATCH 19/30] name convention --- realize/{execute.go => exec.go} | 0 realize/{app.go => realize.go} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename realize/{execute.go => exec.go} (100%) rename realize/{app.go => realize.go} (100%) diff --git a/realize/execute.go b/realize/exec.go similarity index 100% rename from realize/execute.go rename to realize/exec.go diff --git a/realize/app.go b/realize/realize.go similarity index 100% rename from realize/app.go rename to realize/realize.go From 199d5d95a78e6e39a8265e4d1656cc8c185b6963 Mon Sep 17 00:00:00 2001 From: alessio Date: Fri, 2 Sep 2016 00:17:19 +0200 Subject: [PATCH 20/30] code organization --- realize/blueprint.go => cli/cmd.go | 40 +++-------------- {realize => cli}/exec.go | 4 +- cli/main.go | 70 ++++++++++++++++++++++++++++++ {realize => cli}/utils.go | 4 +- {realize => cli}/watcher.go | 14 +----- main.go => realize.go | 21 ++++++++- realize/realize.go | 55 ----------------------- 7 files changed, 99 insertions(+), 109 deletions(-) rename realize/blueprint.go => cli/cmd.go (82%) rename {realize => cli}/exec.go (97%) create mode 100644 cli/main.go rename {realize => cli}/utils.go (98%) rename {realize => cli}/watcher.go (91%) rename main.go => realize.go (89%) delete mode 100644 realize/realize.go diff --git a/realize/blueprint.go b/cli/cmd.go similarity index 82% rename from realize/blueprint.go rename to cli/cmd.go index 3e18d94..4e40409 100644 --- a/realize/blueprint.go +++ b/cli/cmd.go @@ -1,4 +1,4 @@ -package realize +package cli import ( "errors" @@ -10,38 +10,8 @@ import ( "path/filepath" "strings" "syscall" - "time" ) -// App struct contains the informations about realize -type Realize struct { - Name, Description, Author, Email string - Version string - Limit uint64 - Blueprint Blueprint -} - -// Projects struct contains a projects list -type Blueprint struct { - Projects []Project `yaml:"Projects,omitempty"` - files map[string]string -} - -// Project defines the informations of a single project -type Project struct { - reload time.Time - base string - Name string `yaml:"app_name,omitempty"` - Path string `yaml:"app_path,omitempty"` - Run bool `yaml:"app_run,omitempty"` - Bin bool `yaml:"app_bin,omitempty"` - Build bool `yaml:"app_build,omitempty"` - Fmt bool `yaml:"app_fmt,omitempty"` - Test bool `yaml:"app_test,omitempty"` - Params []string `yaml:"app_params,omitempty"` - Watcher Watcher `yaml:"app_watcher,omitempty"` -} - // Wdir returns the name last element of the working directory path func (r *Realize) Wdir() string { dir, err := os.Getwd() @@ -51,8 +21,8 @@ func (r *Realize) Wdir() string { return filepath.Base(dir) } -// Limit defines the max number of watched files -func (r *Realize) limit() { +// Flimit defines the max number of watched files +func (r *Realize) Increases() { // increases the files limit var rLimit syscall.Rlimit rLimit.Max = r.Limit @@ -138,7 +108,7 @@ func (h *Blueprint) Clean() { // Read, Check and remove duplicates from the config file func (h *Blueprint) Read() error { - content, err := read(h.files["config"]) + content, err := read(h.Files["config"]) if err == nil { err = yaml.Unmarshal(content, h) if err == nil { @@ -159,7 +129,7 @@ func (h *Blueprint) Create() error { if err != nil { return err } - return write(h.files["config"], y) + return write(h.Files["config"], y) } // Inserts a new project in the list diff --git a/realize/exec.go b/cli/exec.go similarity index 97% rename from realize/exec.go rename to cli/exec.go index aded846..0d9cd22 100644 --- a/realize/exec.go +++ b/cli/exec.go @@ -1,4 +1,4 @@ -package realize +package cli import ( "bufio" @@ -55,7 +55,7 @@ func (p *Project) GoRun(channel chan bool, runner chan bool, wr *sync.WaitGroup) log.Println(pname(p.Name, 3), ":", BlueS(in.Text())) } if p.Watcher.Output["file"] { - path := filepath.Join(p.base, App.Blueprint.files["output"]) + path := filepath.Join(p.base, App.Blueprint.Files["output"]) f := create(path) t := time.Now() if _, err := f.WriteString(t.Format("2006-01-02 15:04:05") + " : " + in.Text() + "\r\n"); err != nil { diff --git a/cli/main.go b/cli/main.go new file mode 100644 index 0000000..1239fe5 --- /dev/null +++ b/cli/main.go @@ -0,0 +1,70 @@ +package cli + +import ( + "github.com/fatih/color" + "log" + "sync" + "time" +) + +var App Realize + +var wg sync.WaitGroup + +// Green, Red Bold, Red, Blue, Blue Bold, Yellow, Yellow Bold, Magenta, Magenta Bold colors +var Green, Red, RedS, Blue, BlueS, Yellow, YellowS, Magenta, MagentaS = color.New(color.FgGreen, color.Bold).SprintFunc(), + color.New(color.FgRed, color.Bold).SprintFunc(), + color.New(color.FgRed).SprintFunc(), + color.New(color.FgBlue, color.Bold).SprintFunc(), + color.New(color.FgBlue).SprintFunc(), + color.New(color.FgYellow, color.Bold).SprintFunc(), + color.New(color.FgYellow).SprintFunc(), + color.New(color.FgMagenta, color.Bold).SprintFunc(), + color.New(color.FgMagenta).SprintFunc() + +// Realize struct contains the general app informations +type Realize struct { + Name, Description, Author, Email string + Version string + Limit uint64 + Blueprint Blueprint +} + +// Projects struct contains a projects list +type Blueprint struct { + Projects []Project `yaml:"Projects,omitempty"` + Files map[string]string `yaml:"-"` +} + +// Project defines the informations of a single project +type Project struct { + reload time.Time + base string + Name string `yaml:"app_name,omitempty"` + Path string `yaml:"app_path,omitempty"` + Run bool `yaml:"app_run,omitempty"` + Bin bool `yaml:"app_bin,omitempty"` + Build bool `yaml:"app_build,omitempty"` + Fmt bool `yaml:"app_fmt,omitempty"` + Test bool `yaml:"app_test,omitempty"` + Params []string `yaml:"app_params,omitempty"` + Watcher Watcher `yaml:"app_watcher,omitempty"` +} + +// Watcher struct defines the livereload's logic +type Watcher struct { + // different before and after on re-run? + Before []string `yaml:"before,omitempty"` + After []string `yaml:"after,omitempty"` + Paths []string `yaml:"paths,omitempty"` + Ignore []string `yaml:"ignore_paths,omitempty"` + Exts []string `yaml:"exts,omitempty"` + Preview bool `yaml:"preview,omitempty"` + Output map[string]bool `yaml:"output,omitempty"` +} + +// Initialize the application +func init() { + log.SetFlags(0) + log.SetOutput(new(logWriter)) +} diff --git a/realize/utils.go b/cli/utils.go similarity index 98% rename from realize/utils.go rename to cli/utils.go index b0a7ea3..4c7fb3b 100644 --- a/realize/utils.go +++ b/cli/utils.go @@ -1,4 +1,4 @@ -package realize +package cli import ( "errors" @@ -30,7 +30,7 @@ func read(file string) ([]byte, error) { func write(name string, data []byte) error { err := ioutil.WriteFile(name, data, 0655) if err != nil { - log.Fatal(err) + log.Fatal(Red(err)) return err } return nil diff --git a/realize/watcher.go b/cli/watcher.go similarity index 91% rename from realize/watcher.go rename to cli/watcher.go index 6e8df4f..db96820 100644 --- a/realize/watcher.go +++ b/cli/watcher.go @@ -1,4 +1,4 @@ -package realize +package cli import ( "errors" @@ -13,18 +13,6 @@ import ( "time" ) -// The Watcher struct defines the livereload's logic -type Watcher struct { - // different before and after on re-run? - Before []string `yaml:"before,omitempty"` - After []string `yaml:"after,omitempty"` - Paths []string `yaml:"paths,omitempty"` - Ignore []string `yaml:"ignore_paths,omitempty"` - Exts []string `yaml:"exts,omitempty"` - Preview bool `yaml:"preview,omitempty"` - Output map[string]bool `yaml:"output,omitempty"` -} - // Watching method is the main core. It manages the livereload and the watching func (p *Project) watching() { diff --git a/main.go b/realize.go similarity index 89% rename from main.go rename to realize.go index e6c027d..cc9a85a 100644 --- a/main.go +++ b/realize.go @@ -1,14 +1,31 @@ package main import ( - "fmt" - r "github.com/tockins/realize/realize" + r "github.com/tockins/realize/cli" //_ "github.com/tockins/realize/server" + "fmt" "gopkg.in/urfave/cli.v2" "log" "os" ) +func init() { + App := r.Realize{ + Name: "Realize", + Version: "1.0", + Description: "A Go build system with file watchers, output streams and live reload. Run, build and watch file changes with custom paths", + Limit: 10000, + Blueprint: r.Blueprint{ + Files: map[string]string{ + "config": "r.config.yaml", + "output": "r.output.log", + }, + }, + } + App.Increases() + r.App = App +} + func main() { app := r.App diff --git a/realize/realize.go b/realize/realize.go deleted file mode 100644 index 879fb9c..0000000 --- a/realize/realize.go +++ /dev/null @@ -1,55 +0,0 @@ -package realize - -import ( - "github.com/fatih/color" - "log" - "sync" -) - -var App Realize - -var wg sync.WaitGroup - -// Green color bold -var Green = color.New(color.FgGreen, color.Bold).SprintFunc() - -// Red color bold -var Red = color.New(color.FgRed, color.Bold).SprintFunc() - -// RedS color used for errors -var RedS = color.New(color.FgRed).SprintFunc() - -// Blue color bold used for project output -var Blue = color.New(color.FgBlue, color.Bold).SprintFunc() - -// BlueS color -var BlueS = color.New(color.FgBlue).SprintFunc() - -// Yellow color bold -var Yellow = color.New(color.FgYellow, color.Bold).SprintFunc() - -// YellowS color -var YellowS = color.New(color.FgYellow).SprintFunc() - -// MagentaS color -var MagentaS = color.New(color.FgMagenta).SprintFunc() - -// Magenta color bold -var Magenta = color.New(color.FgMagenta, color.Bold).SprintFunc() - -// Initialize the application -func init() { - App = Realize{ - Name: "Realize", - Version: "1.0", - Description: "A Go build system with file watchers, output streams and live reload. Run, build and watch file changes with custom paths", - Limit: 10000, - } - App.Blueprint.files = map[string]string{ - "config": "r.config.yaml", - "output": "r.output.log", - } - App.limit() - log.SetFlags(0) - log.SetOutput(new(logWriter)) -} From f0780873243c7ba1ab97c0349d073e5706f3a322 Mon Sep 17 00:00:00 2001 From: alessio Date: Fri, 2 Sep 2016 00:28:38 +0200 Subject: [PATCH 21/30] code organization fixed --- realize.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/realize.go b/realize.go index cc9a85a..0df2aa6 100644 --- a/realize.go +++ b/realize.go @@ -9,8 +9,10 @@ import ( "os" ) +var App r.Realize + func init() { - App := r.Realize{ + App = r.Realize{ Name: "Realize", Version: "1.0", Description: "A Go build system with file watchers, output streams and live reload. Run, build and watch file changes with custom paths", @@ -28,8 +30,6 @@ func init() { func main() { - app := r.App - handle := func(err error) error { if err != nil { fmt.Println(r.Red(err.Error())) @@ -39,8 +39,8 @@ func main() { } header := func() error { - fmt.Println(r.Blue(app.Name) + " - " + r.Blue(app.Version)) - fmt.Println(r.BlueS(app.Description) + "\n") + fmt.Println(r.Blue(App.Name) + " - " + r.Blue(App.Version)) + fmt.Println(r.BlueS(App.Description) + "\n") gopath := os.Getenv("GOPATH") if gopath == "" { log.Fatal(r.Red("$GOPATH isn't set up properly")) @@ -49,8 +49,8 @@ func main() { } cli := &cli.App{ - Name: app.Name, - Version: app.Version, + Name: App.Name, + Version: App.Version, Authors: []*cli.Author{ { Name: "Alessio Pracchia", @@ -61,13 +61,13 @@ func main() { Email: "conventi@hastega.it", }, }, - Usage: app.Description, + Usage: App.Description, Commands: []*cli.Command{ { Name: "run", Usage: "Build and watch file changes", Action: func(p *cli.Context) error { - return handle(app.Blueprint.Run()) + return handle(App.Blueprint.Run()) }, Before: func(c *cli.Context) error { header() @@ -87,8 +87,8 @@ func main() { &cli.BoolFlag{Name: "Configuration", Value: false, Usage: "Take the defined settings if exist a Configuration file."}, }, Action: func(p *cli.Context) error { - app.Blueprint.Add(p) - return handle(app.Blueprint.Fast(p)) + App.Blueprint.Add(p) + return handle(App.Blueprint.Fast(p)) }, Before: func(c *cli.Context) error { header() @@ -101,7 +101,7 @@ func main() { Aliases: []string{"a"}, Usage: "Add another project", Flags: []cli.Flag{ - &cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: app.Wdir(), 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.BoolFlag{Name: "build", Value: false, Usage: "Enable the build"}, &cli.BoolFlag{Name: "no-run", Usage: "Disables the run"}, @@ -110,7 +110,7 @@ func main() { &cli.BoolFlag{Name: "test", Value: false, Usage: "Enable the tests"}, }, Action: func(p *cli.Context) error { - return handle(app.Blueprint.Insert(p)) + return handle(App.Blueprint.Insert(p)) }, Before: func(c *cli.Context) error { header() @@ -126,7 +126,7 @@ func main() { &cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: ""}, }, Action: func(p *cli.Context) error { - return handle(app.Blueprint.Remove(p)) + return handle(App.Blueprint.Remove(p)) }, Before: func(c *cli.Context) error { header() @@ -139,7 +139,7 @@ func main() { Aliases: []string{"l"}, Usage: "Projects list", Action: func(p *cli.Context) error { - return handle(app.Blueprint.List()) + return handle(App.Blueprint.List()) }, Before: func(c *cli.Context) error { header() From 8c269b0c2f7b99ca33d9f9f961e52f5f6c5f954e Mon Sep 17 00:00:00 2001 From: alessio Date: Fri, 2 Sep 2016 00:34:48 +0200 Subject: [PATCH 22/30] open server url --- server/open.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 server/open.go diff --git a/server/open.go b/server/open.go new file mode 100644 index 0000000..5666b5a --- /dev/null +++ b/server/open.go @@ -0,0 +1,33 @@ +package server + +import ( + "bytes" + "errors" + "io" + "os/exec" + "runtime" +) + +var cli map[string]string +var stderr bytes.Buffer + +func init() { + cli = map[string]string{ + "windows": "start", + "darwin": "open", + "linux": "xdg-open", + } +} + +func Open(url string) (io.Writer, error) { + if open, err := cli[runtime.GOOS]; !err { + return nil, errors.New("This operating system is not supported.") + } else { + cmd := exec.Command(open, url) + cmd.Stderr = &stderr + if err := cmd.Run(); err != nil { + return cmd.Stderr, err + } + } + return nil, nil +} From 0e83ef7bae7a12cd854cf18ecb7ad7e3da8a7575 Mon Sep 17 00:00:00 2001 From: alessio Date: Fri, 2 Sep 2016 00:35:31 +0200 Subject: [PATCH 23/30] server run --- server/main.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 server/main.go diff --git a/server/main.go b/server/main.go new file mode 100644 index 0000000..ca3105f --- /dev/null +++ b/server/main.go @@ -0,0 +1,15 @@ +package server + +import ( + "github.com/labstack/echo" + "github.com/labstack/echo/engine/standard" + "net/http" +) + +func init() { + e := echo.New() + e.GET("/", func(c echo.Context) error { + return c.String(http.StatusOK, "Hi Realize") + }) + go e.Run(standard.New(":5000")) +} From fd1158ddbe271e36ccedebbc7c727ee2ac67e239 Mon Sep 17 00:00:00 2001 From: alessio Date: Mon, 5 Sep 2016 17:53:37 +0200 Subject: [PATCH 24/30] after, before commands --- README.md | 2 +- cli/exec.go | 17 ++++++++++++++++- cli/watcher.go | 48 ++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 35cae89..6f35158 100644 --- a/README.md +++ b/README.md @@ -170,7 +170,7 @@ A Go build system with file watchers, output streams and live reload. Run, build - [ ] Testing on windows - [x] Custom paths for the commands fast/add - [x] Save output on a file -- [ ] Enable the fields Before/After +- [x] Enable the fields Before/After - [ ] Web panel - **Maybe** diff --git a/cli/exec.go b/cli/exec.go index 0d9cd22..bedb8af 100644 --- a/cli/exec.go +++ b/cli/exec.go @@ -3,11 +3,13 @@ package cli import ( "bufio" "bytes" + "fmt" "io" "log" "os" "os/exec" "path/filepath" + "strings" "sync" "time" ) @@ -27,7 +29,7 @@ func (p *Project) GoRun(channel chan bool, runner chan bool, wr *sync.WaitGroup) if err := build.Process.Kill(); err != nil { log.Fatal(Red("Failed to stop: "), Red(err)) } - log.Println(pname(p.Name, 2), ":", RedS("Stopped")) + log.Println(pname(p.Name, 2), ":", RedS("Ended")) wr.Done() }() @@ -134,3 +136,16 @@ func (p *Project) GoTest(path string) (io.Writer, error) { } return nil, nil } + +// Cmd exec a list of defined commands +func (p *Project) Cmd(cmds []string) (errors []error) { + for _, cmd := range cmds { + c := strings.Split(cmd, " ") + build := exec.Command(c[0], c[1:]...) + build.Dir = p.base + if err := build.Run(); err != nil { + errors = append(errors, err) + } + } + return errors +} diff --git a/cli/watcher.go b/cli/watcher.go index db96820..2e30959 100644 --- a/cli/watcher.go +++ b/cli/watcher.go @@ -7,9 +7,11 @@ import ( "log" "math/big" "os" + "os/signal" "path/filepath" "strings" "sync" + "syscall" "time" ) @@ -33,11 +35,13 @@ func (p *Project) watching() { } defer end() + p.cmd() err = p.walks(watcher) if err != nil { fmt.Println(pname(p.Name, 1), ":", Red(err.Error())) return } + go p.routines(channel, &wr) p.reload = time.Now().Truncate(time.Second) @@ -60,7 +64,7 @@ func (p *Project) watching() { i := strings.Index(event.Name, filepath.Ext(event.Name)) if event.Name[:i] != "" && inArray(ext, p.Watcher.Exts) { - log.Println(pname(p.Name, 4), ":", Magenta(event.Name[:i]+ext)) + fmt.Println(pname(p.Name, 4), Magenta(strings.ToUpper(ext[1:])+" changed"), Magenta(event.Name[:i]+ext)) // stop and run again if p.Run { close(channel) @@ -92,7 +96,7 @@ func (p *Project) install(channel chan bool, wr *sync.WaitGroup) { log.Println(pname(p.Name, 1), ":", fmt.Sprint(Red(err)), std) wr.Done() } else { - log.Println(pname(p.Name, 5), ":", Green("Installed")+" after", MagentaS(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), "s")) + log.Println(pname(p.Name, 5), ":", Green("Installed")+" after", MagentaS(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s")) if p.Run { runner := make(chan bool, 1) log.Println(pname(p.Name, 1), ":", "Running..") @@ -101,7 +105,7 @@ func (p *Project) install(channel chan bool, wr *sync.WaitGroup) { for { select { case <-runner: - log.Println(pname(p.Name, 5), ":", Green("Has been run")+" after", MagentaS(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), "s")) + log.Println(pname(p.Name, 5), ":", Green("Has been run")+" after", MagentaS(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s")) return } } @@ -119,25 +123,53 @@ func (p *Project) build() { if std, err := p.GoBuild(); err != nil { log.Println(pname(p.Name, 1), ":", fmt.Sprint(Red(err)), std) } else { - log.Println(pname(p.Name, 5), ":", Green("Builded")+" after", MagentaS(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), "s")) + log.Println(pname(p.Name, 5), ":", Green("Builded")+" after", MagentaS(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s")) } return } return } -// Build calls an implementation of the "gofmt" +// Fmt calls an implementation of the "gofmt" func (p *Project) fmt(path string) error { if p.Fmt { if _, err := p.GoFmt(path); err != nil { log.Println(pname(p.Name, 1), Red("There are some GoFmt errors in "), ":", Magenta(path)) - //fmt.Println(msg) } } return nil } -// Build calls an implementation of the "go test" +// Cmd calls an wrapper for execute the commands after/before +func (p *Project) cmd() { + c := make(chan os.Signal, 2) + signal.Notify(c, os.Interrupt, syscall.SIGTERM) + cast := func(commands []string) { + if errs := p.Cmd(commands); errs != nil { + for _, err := range errs { + log.Println(pname(p.Name, 2), Red(err)) + } + } + } + + if len(p.Watcher.Before) > 0 { + cast(p.Watcher.Before) + } + + go func() { + for { + select { + case <-c: + if len(p.Watcher.After) > 0 { + cast(p.Watcher.After) + } + os.Exit(1) + } + } + }() +} + +// Test calls an implementation of the "go test" func (p *Project) test(path string) error { if p.Test { if _, err := p.GoTest(path); err != nil { @@ -201,7 +233,7 @@ func (p *Project) walks(watcher *fsnotify.Watcher) error { return errors.New(base + " path doesn't exist") } } - fmt.Println(Red("Watching"), ":", pname(p.Name, 1), Magenta(files), "file/s", Magenta(folders), "folder/s") + fmt.Println(pname(p.Name, 1), Red("Watching"), Magenta(files), "file/s", Magenta(folders), "folder/s") return nil } From 6ce759340738ae0b804a9658deb71a7ace3b6a2c Mon Sep 17 00:00:00 2001 From: alessio Date: Mon, 5 Sep 2016 17:57:49 +0200 Subject: [PATCH 25/30] fmt import removed --- cli/exec.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/exec.go b/cli/exec.go index bedb8af..4598f56 100644 --- a/cli/exec.go +++ b/cli/exec.go @@ -3,7 +3,6 @@ package cli import ( "bufio" "bytes" - "fmt" "io" "log" "os" From 1cc2e64e5cc8ade94cec7e39b4c372033747834e Mon Sep 17 00:00:00 2001 From: alessio Date: Mon, 5 Sep 2016 20:11:45 +0200 Subject: [PATCH 26/30] quotes removed from the after/before commands --- cli/exec.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/exec.go b/cli/exec.go index 4598f56..29cbfa8 100644 --- a/cli/exec.go +++ b/cli/exec.go @@ -139,6 +139,7 @@ func (p *Project) GoTest(path string) (io.Writer, error) { // Cmd exec a list of defined commands func (p *Project) Cmd(cmds []string) (errors []error) { for _, cmd := range cmds { + cmd := strings.Replace(strings.Replace(cmd, "'", "", -1), "\"", "", -1) c := strings.Split(cmd, " ") build := exec.Command(c[0], c[1:]...) build.Dir = p.base From b2c38ef474939d9d01e0039383254bf675aa4e5e Mon Sep 17 00:00:00 2001 From: alessio Date: Tue, 6 Sep 2016 02:31:44 +0200 Subject: [PATCH 27/30] bindata render --- server/assets/index.html | 1 + server/main.go | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 server/assets/index.html diff --git a/server/assets/index.html b/server/assets/index.html new file mode 100644 index 0000000..0a90125 --- /dev/null +++ b/server/assets/index.html @@ -0,0 +1 @@ +Testing \ No newline at end of file diff --git a/server/main.go b/server/main.go index ca3105f..1ff6f8b 100644 --- a/server/main.go +++ b/server/main.go @@ -3,13 +3,27 @@ package server import ( "github.com/labstack/echo" "github.com/labstack/echo/engine/standard" + "github.com/labstack/echo/middleware" "net/http" ) +func render(c echo.Context, path string) error{ + data, err := Asset(path) + if err != nil { + return echo.NewHTTPError(http.StatusNotFound) + } + rs := c.Response() + rs.Header().Set(echo.HeaderContentType, echo.MIMETextHTMLCharsetUTF8) + rs.WriteHeader(http.StatusOK) + rs.Write(data) + return nil +} + func init() { e := echo.New() + e.Use(middleware.Gzip()) e.GET("/", func(c echo.Context) error { - return c.String(http.StatusOK, "Hi Realize") + return render(c, "server/assets/index.html") }) go e.Run(standard.New(":5000")) } From d2d442bf76c605c649091337b5dd99a5232b0343 Mon Sep 17 00:00:00 2001 From: alessio Date: Tue, 6 Sep 2016 02:36:35 +0200 Subject: [PATCH 28/30] bindata --- server/data.go | 239 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 server/data.go diff --git a/server/data.go b/server/data.go new file mode 100644 index 0000000..3bc66f3 --- /dev/null +++ b/server/data.go @@ -0,0 +1,239 @@ +// Code generated by go-bindata. +// sources: +// server/assets/index.html +// DO NOT EDIT! + +package server + +import ( + "bytes" + "compress/gzip" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" +) + +func bindataRead(data []byte, name string) ([]byte, error) { + gz, err := gzip.NewReader(bytes.NewBuffer(data)) + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + + var buf bytes.Buffer + _, err = io.Copy(&buf, gz) + clErr := gz.Close() + + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + if clErr != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +type asset struct { + bytes []byte + info os.FileInfo +} + +type bindataFileInfo struct { + name string + size int64 + mode os.FileMode + modTime time.Time +} + +func (fi bindataFileInfo) Name() string { + return fi.name +} +func (fi bindataFileInfo) Size() int64 { + return fi.size +} +func (fi bindataFileInfo) Mode() os.FileMode { + return fi.mode +} +func (fi bindataFileInfo) ModTime() time.Time { + return fi.modTime +} +func (fi bindataFileInfo) IsDir() bool { + return false +} +func (fi bindataFileInfo) Sys() interface{} { + return nil +} + +var _serverAssetsIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x0a\x49\x2d\x2e\xc9\xcc\x4b\x07\x04\x00\x00\xff\xff\x9a\x63\x4e\x27\x07\x00\x00\x00") + +func serverAssetsIndexHtmlBytes() ([]byte, error) { + return bindataRead( + _serverAssetsIndexHtml, + "server/assets/index.html", + ) +} + +func serverAssetsIndexHtml() (*asset, error) { + bytes, err := serverAssetsIndexHtmlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "server/assets/index.html", size: 7, mode: os.FileMode(420), modTime: time.Unix(1472831748, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +// Asset loads and returns the asset for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func Asset(name string) ([]byte, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) + } + return a.bytes, nil + } + return nil, fmt.Errorf("Asset %s not found", name) +} + +// MustAsset is like Asset but panics when Asset would return an error. +// It simplifies safe initialization of global variables. +func MustAsset(name string) []byte { + a, err := Asset(name) + if err != nil { + panic("asset: Asset(" + name + "): " + err.Error()) + } + + return a +} + +// AssetInfo loads and returns the asset info for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func AssetInfo(name string) (os.FileInfo, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) + } + return a.info, nil + } + return nil, fmt.Errorf("AssetInfo %s not found", name) +} + +// AssetNames returns the names of the assets. +func AssetNames() []string { + names := make([]string, 0, len(_bindata)) + for name := range _bindata { + names = append(names, name) + } + return names +} + +// _bindata is a table, holding each asset generator, mapped to its name. +var _bindata = map[string]func() (*asset, error){ + "server/assets/index.html": serverAssetsIndexHtml, +} + +// AssetDir returns the file names below a certain +// directory embedded in the file by go-bindata. +// For example if you run go-bindata on data/... and data contains the +// following hierarchy: +// data/ +// foo.txt +// img/ +// a.png +// b.png +// then AssetDir("data") would return []string{"foo.txt", "img"} +// AssetDir("data/img") would return []string{"a.png", "b.png"} +// AssetDir("foo.txt") and AssetDir("notexist") would return an error +// AssetDir("") will return []string{"data"}. +func AssetDir(name string) ([]string, error) { + node := _bintree + if len(name) != 0 { + cannonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(cannonicalName, "/") + for _, p := range pathList { + node = node.Children[p] + if node == nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + } + } + if node.Func != nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + rv := make([]string, 0, len(node.Children)) + for childName := range node.Children { + rv = append(rv, childName) + } + return rv, nil +} + +type bintree struct { + Func func() (*asset, error) + Children map[string]*bintree +} + +var _bintree = &bintree{nil, map[string]*bintree{ + "server": {nil, map[string]*bintree{ + "assets": {nil, map[string]*bintree{ + "index.html": {serverAssetsIndexHtml, map[string]*bintree{}}, + }}, + }}, +}} + +// RestoreAsset restores an asset under the given directory +func RestoreAsset(dir, name string) error { + data, err := Asset(name) + if err != nil { + return err + } + info, err := AssetInfo(name) + if err != nil { + return err + } + err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) + if err != nil { + return err + } + err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + if err != nil { + return err + } + err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) + if err != nil { + return err + } + return nil +} + +// RestoreAssets restores an asset under the given directory recursively +func RestoreAssets(dir, name string) error { + children, err := AssetDir(name) + // File + if err != nil { + return RestoreAsset(dir, name) + } + // Dir + for _, child := range children { + err = RestoreAssets(dir, filepath.Join(name, child)) + if err != nil { + return err + } + } + return nil +} + +func _filePath(dir, name string) string { + cannonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) +} From cdb69077706ef0b28071dc92cf3128c5718145e5 Mon Sep 17 00:00:00 2001 From: conventi Date: Sat, 17 Sep 2016 14:38:23 +0200 Subject: [PATCH 29/30] Initialization server part for WebSocket --- cli/cmd.go | 24 ------------------------ cli/exec.go | 2 +- cli/main.go | 12 ++---------- cli/utils.go | 11 ++++++++++- cli/watcher.go | 2 +- realize.go | 45 ++++++++++++++++++++++++++++++++++----------- server/main.go | 17 +++++++++++++++-- 7 files changed, 63 insertions(+), 50 deletions(-) diff --git a/cli/cmd.go b/cli/cmd.go index 4e40409..3329caa 100644 --- a/cli/cmd.go +++ b/cli/cmd.go @@ -5,34 +5,10 @@ import ( "fmt" "gopkg.in/urfave/cli.v2" "gopkg.in/yaml.v2" - "log" - "os" "path/filepath" "strings" - "syscall" ) -// Wdir returns the name last element of the working directory path -func (r *Realize) Wdir() string { - dir, err := os.Getwd() - if err != nil { - log.Fatal(Red(err)) - } - return filepath.Base(dir) -} - -// Flimit defines the max number of watched files -func (r *Realize) Increases() { - // increases the files limit - var rLimit syscall.Rlimit - rLimit.Max = r.Limit - rLimit.Cur = r.Limit - err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) - if err != nil { - fmt.Println(Red("Error Setting Rlimit "), err) - } -} - // Watch method adds the given paths on the Watcher func (h *Blueprint) Run() error { err := h.Read() diff --git a/cli/exec.go b/cli/exec.go index 29cbfa8..405af80 100644 --- a/cli/exec.go +++ b/cli/exec.go @@ -56,7 +56,7 @@ func (p *Project) GoRun(channel chan bool, runner chan bool, wr *sync.WaitGroup) log.Println(pname(p.Name, 3), ":", BlueS(in.Text())) } if p.Watcher.Output["file"] { - path := filepath.Join(p.base, App.Blueprint.Files["output"]) + path := filepath.Join(p.base, Bp.Files["output"]) f := create(path) t := time.Now() if _, err := f.WriteString(t.Format("2006-01-02 15:04:05") + " : " + in.Text() + "\r\n"); err != nil { diff --git a/cli/main.go b/cli/main.go index 1239fe5..196c19f 100644 --- a/cli/main.go +++ b/cli/main.go @@ -7,8 +7,6 @@ import ( "time" ) -var App Realize - var wg sync.WaitGroup // Green, Red Bold, Red, Blue, Blue Bold, Yellow, Yellow Bold, Magenta, Magenta Bold colors @@ -22,14 +20,6 @@ var Green, Red, RedS, Blue, BlueS, Yellow, YellowS, Magenta, MagentaS = color.Ne color.New(color.FgMagenta, color.Bold).SprintFunc(), color.New(color.FgMagenta).SprintFunc() -// Realize struct contains the general app informations -type Realize struct { - Name, Description, Author, Email string - Version string - Limit uint64 - Blueprint Blueprint -} - // Projects struct contains a projects list type Blueprint struct { Projects []Project `yaml:"Projects,omitempty"` @@ -68,3 +58,5 @@ func init() { log.SetFlags(0) log.SetOutput(new(logWriter)) } + +var Bp Blueprint diff --git a/cli/utils.go b/cli/utils.go index 4c7fb3b..ef3601a 100644 --- a/cli/utils.go +++ b/cli/utils.go @@ -12,6 +12,15 @@ import ( "time" ) +// Wdir returns the name last element of the working directory path +func Wdir() string { + dir, err := os.Getwd() + if err != nil { + log.Fatal(Red(err)) + } + return filepath.Base(dir) +} + // Read a file given a name and return its byte stream func read(file string) ([]byte, error) { _, err := os.Stat(file) @@ -62,7 +71,7 @@ func argsParam(params *cli.Context) []string { func nameFlag(params *cli.Context) string { var name string if params.String("name") == "" && params.String("path") == "" { - return App.Wdir() + return Wdir() } else if params.String("path") != "/" { name = filepath.Base(params.String("path")) } else { diff --git a/cli/watcher.go b/cli/watcher.go index 2e30959..334d06b 100644 --- a/cli/watcher.go +++ b/cli/watcher.go @@ -216,7 +216,7 @@ func (p *Project) walks(watcher *fsnotify.Watcher) error { if p.Path == "." || p.Path == "/" { p.base = wd - p.Path = App.Wdir() + p.Path = Wdir() } else if filepath.IsAbs(p.Path) { p.base = p.Path } else { diff --git a/realize.go b/realize.go index 0df2aa6..0da49d8 100644 --- a/realize.go +++ b/realize.go @@ -1,23 +1,45 @@ package main import ( - r "github.com/tockins/realize/cli" - //_ "github.com/tockins/realize/server" "fmt" + c "github.com/tockins/realize/cli" + s "github.com/tockins/realize/server" "gopkg.in/urfave/cli.v2" "log" "os" + "syscall" ) -var App r.Realize +var App Realize + +// Realize struct contains the general app informations +type Realize struct { + Name, Description, Author, Email string + Version string + Limit uint64 + Blueprint c.Blueprint + Server s.Server +} + +// Flimit defines the max number of watched files +func (r *Realize) Increases() { + // increases the files limit + var rLimit syscall.Rlimit + rLimit.Max = r.Limit + rLimit.Cur = r.Limit + err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) + if err != nil { + fmt.Println(c.Red("Error Setting Rlimit "), err) + } +} func init() { - App = r.Realize{ + App = Realize{ Name: "Realize", Version: "1.0", Description: "A Go build system with file watchers, output streams and live reload. Run, build and watch file changes with custom paths", Limit: 10000, - Blueprint: r.Blueprint{ + Blueprint: c.Blueprint{ Files: map[string]string{ "config": "r.config.yaml", "output": "r.output.log", @@ -25,25 +47,25 @@ func init() { }, } App.Increases() - r.App = App + c.Bp = App.Blueprint } func main() { handle := func(err error) error { if err != nil { - fmt.Println(r.Red(err.Error())) + fmt.Println(c.Red(err.Error())) return nil } return nil } header := func() error { - fmt.Println(r.Blue(App.Name) + " - " + r.Blue(App.Version)) - fmt.Println(r.BlueS(App.Description) + "\n") + 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(r.Red("$GOPATH isn't set up properly")) + log.Fatal(c.Red("$GOPATH isn't set up properly")) } return nil } @@ -88,6 +110,7 @@ func main() { }, Action: func(p *cli.Context) error { App.Blueprint.Add(p) + App.Server.Start() return handle(App.Blueprint.Fast(p)) }, Before: func(c *cli.Context) error { @@ -101,7 +124,7 @@ func main() { Aliases: []string{"a"}, Usage: "Add another project", Flags: []cli.Flag{ - &cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: App.Wdir(), Usage: "Project name"}, + &cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: c.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"}, diff --git a/server/main.go b/server/main.go index 1ff6f8b..3b5281c 100644 --- a/server/main.go +++ b/server/main.go @@ -1,13 +1,19 @@ package server import ( + "fmt" "github.com/labstack/echo" "github.com/labstack/echo/engine/standard" "github.com/labstack/echo/middleware" + "golang.org/x/net/websocket" "net/http" ) -func render(c echo.Context, path string) error{ +// Server struct contains server informations +type Server struct { +} + +func render(c echo.Context, path string) error { data, err := Asset(path) if err != nil { return echo.NewHTTPError(http.StatusNotFound) @@ -19,11 +25,18 @@ func render(c echo.Context, path string) error{ return nil } -func init() { +func (s *Server) Start() { e := echo.New() e.Use(middleware.Gzip()) e.GET("/", func(c echo.Context) error { return render(c, "server/assets/index.html") }) + e.GET("/ws", standard.WrapHandler(projects())) go e.Run(standard.New(":5000")) } + +func projects() websocket.Handler { + return websocket.Handler(func(ws *websocket.Conn) { + fmt.Println(12) + }) +} From 4af65755168d5a3c30f3ba48aff4a5aa33d22c93 Mon Sep 17 00:00:00 2001 From: conventi Date: Sat, 17 Sep 2016 15:15:11 +0200 Subject: [PATCH 30/30] Fixed reference for Blueprint object --- cli/main.go | 4 ++-- realize.go | 4 +++- server/main.go | 21 ++++++++++++++++++--- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/cli/main.go b/cli/main.go index 196c19f..e1cf7f9 100644 --- a/cli/main.go +++ b/cli/main.go @@ -7,6 +7,8 @@ import ( "time" ) +var Bp *Blueprint + var wg sync.WaitGroup // Green, Red Bold, Red, Blue, Blue Bold, Yellow, Yellow Bold, Magenta, Magenta Bold colors @@ -58,5 +60,3 @@ func init() { log.SetFlags(0) log.SetOutput(new(logWriter)) } - -var Bp Blueprint diff --git a/realize.go b/realize.go index 0da49d8..8c23614 100644 --- a/realize.go +++ b/realize.go @@ -47,7 +47,9 @@ func init() { }, } App.Increases() - c.Bp = App.Blueprint + c.Bp = &App.Blueprint + s.Bp = &App.Blueprint + } func main() { diff --git a/server/main.go b/server/main.go index 3b5281c..c5d2d4c 100644 --- a/server/main.go +++ b/server/main.go @@ -1,14 +1,17 @@ package server import ( - "fmt" "github.com/labstack/echo" "github.com/labstack/echo/engine/standard" "github.com/labstack/echo/middleware" + c "github.com/tockins/realize/cli" "golang.org/x/net/websocket" + "log" "net/http" ) +var Bp *c.Blueprint + // Server struct contains server informations type Server struct { } @@ -31,12 +34,24 @@ func (s *Server) Start() { e.GET("/", func(c echo.Context) error { return render(c, "server/assets/index.html") }) - e.GET("/ws", standard.WrapHandler(projects())) + + e.GET("/projects", standard.WrapHandler(projects())) go e.Run(standard.New(":5000")) } +// The WebSocket for projects list func projects() websocket.Handler { return websocket.Handler(func(ws *websocket.Conn) { - fmt.Println(12) + for { + err := websocket.Message.Send(ws, "Hello") + if err != nil { + log.Fatal(err) + } + msg := "" + err = websocket.Message.Receive(ws, &msg) + if err != nil { + log.Fatal(err) + } + } }) }