mirror of
https://github.com/kataras/iris.git
synced 2025-02-02 15:30:36 +01:00
💡 Happy Sunday: Introducing rizla
This commit is contained in:
parent
bd91395b19
commit
6391ba04ca
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
179
iris/run.go
179
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
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user