From 6391ba04ca8143e36e779eb206f6f8d92e91d368 Mon Sep 17 00:00:00 2001 From: Makis Maropoulos Date: Sun, 26 Jun 2016 16:26:44 +0300 Subject: [PATCH] :bulb: Happy Sunday: Introducing rizla --- README.md | 5 +- THIRDPARTY-LICENSE.md | 2 +- iris/run.go | 179 ++++-------------------------------------- utils/file.go | 48 ----------- 4 files changed, 18 insertions(+), 216 deletions(-) diff --git a/README.md b/README.md index 8a347168..6037f3e9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Travis Widget]][Travis] [![Release Widget]][Release] [![Report Widget]][Report] [![License Widget]][License] [![Gitter Widget]][Gitter] [![Documentation Widget]][Documentation] -[Travis Widget]: https://img.shields.io/travis/tmrts/boilr.svg?style=flat-square +[Travis Widget]: https://img.shields.io/travis/kataras/iris.svg?style=flat-square [Travis]: http://travis-ci.org/kataras/iris [License Widget]: https://img.shields.io/badge/license-MIT%20%20License%20-E91E63.svg?style=flat-square [License]: https://github.com/kataras/iris/blob/master/LICENSE @@ -51,7 +51,7 @@ func main() { Installation ------------ - The only requirement is Go 1.6 +The only requirement is the [Go Programming Language](https://golang.org/dl), at least v1.6 `$ go get -u github.com/kataras/iris/iris` @@ -181,7 +181,6 @@ If you are interested in contributing to the Iris project, please see the docume Third-Party Licenses ------------ -This project is using third-party libraries to achieve this result. Third-Party Licenses can be found [here](THIRDPARTY-LICENSE.md) diff --git a/THIRDPARTY-LICENSE.md b/THIRDPARTY-LICENSE.md index 3edbdebb..4d8c4cd1 100644 --- a/THIRDPARTY-LICENSE.md +++ b/THIRDPARTY-LICENSE.md @@ -8,7 +8,7 @@ Third party packages - [blackfriday is one of the supporting template engines](https://github.com/russross/blackfriday) - [klauspost/gzip for faster compression](https://github.com/klauspost/compress) - [httprouter](https://github.com/julienschmidt/httprouter) for the basic BSD kernel's [trie algorithm](https://en.wikipedia.org/wiki/Trie) used inside [muxEntry](https://github.com/kataras/iris/blob/master/http.go#L578), edited by [Iris' author](https://github.com/kataras) to improve its performance and achieve 0 memory allocations per operation. -- [goo](https://github.com/kataras/goo) used inside iris command line tool +- [rizla](https://github.com/kataras/rizla) used inside iris command line tool - [cli](https://github.com/kataras/cli) used inside iris command line tool - [color](https://github.com/fatih/color) with [go-colorable](https://github.com/mattn/go-colorable) for the logger's colors] - [mergo for merge configs](https://github.com/imdario/mergo) diff --git a/iris/run.go b/iris/run.go index 92620eb9..4c32bdad 100644 --- a/iris/run.go +++ b/iris/run.go @@ -1,181 +1,32 @@ package main import ( - "io/ioutil" "os" - "path/filepath" - "runtime" - "strconv" + "strings" - "sync/atomic" - "github.com/iris-contrib/errors" "github.com/kataras/cli" - "github.com/kataras/iris/utils" + "github.com/kataras/rizla/rizla" ) -var ( - errInvalidArgs = errors.New("Invalid arguments [%s], type -h to get assistant") - errInvalidExt = errors.New("%s is not a go program") - errUnexpected = errors.New("Unexpected error!!! Please post an issue here: https://github.com/kataras/iris/issues") - errBuild = errors.New("\n Failed to build the %s iris program. Trace: %s") - errRun = errors.New("\n Failed to run the %s iris program. Trace: %s") - goExt = ".go" -) - -var times uint32 - -func build(sourcepath string) error { - goBuild := utils.CommandBuilder("go", "build", sourcepath) - goBuild.Dir = workingDir - goBuild.Stdout = os.Stdout - goBuild.Stderr = os.Stderr - if err := goBuild.Run(); err != nil { - ferr := errBuild.Format(sourcepath, err.Error()) - printer.Dangerf(ferr.Error()) - return ferr - } - return nil -} - -func run(executablePath string) (*utils.Cmd, error) { - runCmd := utils.CommandBuilder("." + utils.PathSeparator + executablePath) - runCmd.Dir = workingDir - runCmd.Stderr = os.Stderr - runCmd.Stdout = os.Stdout - - if err := runCmd.Start(); err != nil { - ferr := errRun.Format(executablePath, err.Error()) - printer.Dangerf(ferr.Error()) - return nil, ferr - } - times++ - return runCmd, nil -} - func runAndWatch(flags cli.Flags) error { if len(os.Args) <= 2 { - err := errInvalidArgs.Format(strings.Join(os.Args, ",")) - printer.Dangerf(err.Error()) - return err + printer.Dangerf("Invalid arguments [%s], type -h to get assistant", strings.Join(os.Args, ",")) + os.Exit(-1) } - isWindows := runtime.GOOS == "windows" - programPath := "" - executablePath := "" - filenameCh := make(chan string) + programPath := os.Args[2] - if len(os.Args) > 2 { // iris run main.go - programPath = os.Args[2] - if programPath[len(programPath)-1] == '/' { - programPath = programPath[0 : len(programPath)-1] - } + /*project := rizla.NewProject(programPath) + project.Name = "IRIS" + project.AllowReloadAfter = time.Duration(3) * time.Second + rizla.Add(project) - if filepath.Ext(programPath) != goExt { - return errInvalidExt.Format(programPath) - } + rizla.Out = os.Stdout + rizla.Err = os.Stderr + rizla.Run()*/ + // or just do that: - // check if we have a path,change the workingdir and programpath - if lidx := strings.LastIndexByte(programPath, os.PathSeparator); lidx > 0 { // no / - workingDir = workingDir + utils.PathSeparator + programPath[0:lidx] - programPath = programPath[lidx+1:] - } else if lidx := strings.LastIndexByte(programPath, '/'); lidx > 0 { // no / - workingDir = workingDir + "/" + programPath[0:lidx] - programPath = programPath[lidx+1:] - } - - executablePath = programPath[:len(programPath)-3] - if isWindows { - executablePath += ".exe" - } - - } - - subfiles, err := ioutil.ReadDir(workingDir) - if err != nil { - printer.Dangerf(err.Error()) - return err - } - var paths []string - paths = append(paths, workingDir) - for _, subfile := range subfiles { - if subfile.IsDir() { - if abspath, err := filepath.Abs(workingDir + utils.PathSeparator + subfile.Name()); err == nil { - paths = append(paths, abspath) - } - - } - } - - // run the file watcher before all, because the user maybe has a go syntax error before the first run - utils.WatchDirectoryChanges(paths, func(fname string) { - //remove the working dir from the fname path, printer should only print the relative changed file ( from the project's path) - fname = fname[len(workingDir)+1:] - - if (filepath.Ext(fname) == goExt) || (!isWindows && strings.Contains(fname, goExt)) { // on !windows it sends a .gooutput_RANDOM_STRINGHERE, Note that: we do contains instead of HasPrefix - filenameCh <- fname - } - - }, printer) - - if err = build(programPath); err != nil { - printer.Dangerf(err.Error()) - return err - } - - runCmd, err := run(executablePath) - - if err != nil { - printer.Dangerf(err.Error()) - return err - } - // here(below), we don't return the error because the -help command doesn't help the user for these errors. - defer func() { - printer.Dangerf("") - printer.Panic(errUnexpected) - }() - - for { - select { - case fname := <-filenameCh: - { - // it's not a warning but I like to use purple color for this message - if !isWindows { - fname = " " // we don't want to print the ".gooutput..." so dont print anything as a name - } - - printer.Infof("[OP: %d] File %s changed, reloading...", atomic.LoadUint32(×), fname) - - //kill the prev run - - err := runCmd.Process.Kill() - if err == nil { - _, err = runCmd.Process.Wait() - } else { - - // force kill, sometimes runCmd.Process.Kill or Signal(os.Kill) doesn't kills - if isWindows { - err = utils.CommandBuilder("taskkill", "/F", "/T", "/PID", strconv.Itoa(runCmd.Process.Pid)).Run() - } else { - err = utils.CommandBuilder("kill", "-INT", "-"+strconv.Itoa(runCmd.Process.Pid)).Run() - } - } - - err = build(programPath) - if err != nil { - printer.Warningf(err.Error()) - } else { - - if runCmd, err = run(executablePath); err != nil { - printer.Warningf(err.Error() + "\n") - - } else { - // we did .Start, but it should be fast so no need to add a sleeper - printer.Successf("ready!\n") - } - } - - } - } - } + rizla.Run(programPath) + return nil } diff --git a/utils/file.go b/utils/file.go index 75bac032..28748a45 100644 --- a/utils/file.go +++ b/utils/file.go @@ -12,9 +12,6 @@ import ( "runtime" "strings" "time" - - "github.com/fsnotify/fsnotify" - "github.com/kataras/iris/logger" ) const ( @@ -332,48 +329,3 @@ func GetParentDir(targetDirectory string) string { parentDirectory := targetDirectory[0:lastSlashIndex] return parentDirectory } - -/* - // 3-BSD License for package fsnotify/fsnotify - // Copyright (c) 2012 The Go Authors. All rights reserved. - // Copyright (c) 2012 fsnotify Authors. All rights reserved. -*/ - -// WatchDirectoryChanges watches a directory and fires the callback with the changed name, receives a logger just to print with red letters any errors, no need for second callback. -func WatchDirectoryChanges(paths []string, evt func(filename string), logger *logger.Logger) { - isWindows := runtime.GOOS == "windows" - watcher, werr := fsnotify.NewWatcher() - if werr != nil { - logger.Dangerf(werr.Error()) - return - } - - go func() { - var lastChange = time.Now() - var i = 0 - for { - select { - case event := <-watcher.Events: - if event.Op&fsnotify.Write == fsnotify.Write { - //this is received two times, the last time is the real changed file, so - i++ - if i%2 == 0 || !isWindows { // this 'hack' works for windows & linux but I dont know if works for osx too, we can wait for issue reports here. - if time.Now().After(lastChange.Add(time.Duration(1) * time.Second)) { - lastChange = time.Now() - evt(event.Name) - } - } - - } - case err := <-watcher.Errors: - logger.Dangerf(err.Error()) - } - } - }() - for _, p := range paths { - if werr = watcher.Add(p); werr != nil { - logger.Dangerf(werr.Error()) - } - } - -}