github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/kmg/SubCommand/goCmd/GoWatch.go.bak (about) 1 package goCommand 2 3 /* 4 import ( 5 "fmt" 6 "os" 7 "os/exec" 8 "path/filepath" 9 10 "github.com/bronze1man/kmg/console" 11 "github.com/bronze1man/kmg/fsnotify" 12 "github.com/bronze1man/kmg/kmgCmd" 13 "github.com/bronze1man/kmg/kmgConfig" 14 ) 15 16 //Warning!! do not use go run to build executes... 17 // you can kill go run xxx, you can not kill main.exe xxx 18 //TODO cygwin ctrl+c not exit children processes 19 //TODO wrap restart cmd stuff 20 //TODO wrap lastHappendTime watch stuff 21 type GoWatch struct { 22 context *console.Context 23 GOPATH string 24 wd string 25 watcher *fsnotify.Watcher 26 cmd *exec.Cmd 27 mainFilePath string 28 targetFilePath string 29 isDebug bool //more output 30 } 31 32 func (command *GoWatch) GetNameConfig() *console.NameConfig { 33 return &console.NameConfig{Name: "GoWatch", 34 Short: "watch current project and rebuild and restart app when some file changed", 35 } 36 } 37 38 func (command *GoWatch) Execute(context *console.Context) (err error) { 39 command.isDebug = false 40 command.context = context 41 if len(context.Args) != 3 { 42 return fmt.Errorf("usage: %s watch [packages]", context.ExecutionName) 43 } 44 command.mainFilePath = context.Args[2] 45 kmgc, err := kmgConfig.LoadEnvFromWd() 46 if err != nil { 47 return 48 } 49 command.GOPATH = kmgc.GOPATHToString() 50 command.wd = kmgc.ProjectPath 51 runner, err := fsnotify.NewRunner(10000) 52 if err != nil { 53 return err 54 } 55 runner.Watcher.ErrorHandler = func(err error) { 56 fmt.Println("watcher.Error error: ", err) 57 } 58 runner.Watcher.IsIgnorePath = func(path string) bool { 59 if fsnotify.DefaultIsIgnorePath(path) { 60 return true 61 } 62 if path == command.targetFilePath { 63 return true 64 } 65 return false 66 } 67 runner.Watcher.WatchRecursion(command.wd) 68 // wait forever 69 runner.Run(func() { 70 err := command.restart() 71 if err != nil { 72 fmt.Println("command.restart() error: ", err) 73 } 74 }) 75 return nil 76 } 77 func (command *GoWatch) restart() error { 78 //kill old process 79 err := command.stop() 80 if err != nil { 81 return err 82 } 83 //start new one 84 var name string 85 if filepath.Ext(command.mainFilePath) == ".go" { 86 name = filepath.Base(command.mainFilePath[:len(command.mainFilePath)-len(".go")]) 87 } else { 88 name = filepath.Base(command.mainFilePath) 89 } 90 command.targetFilePath = filepath.Join(command.wd, "bin", name+".exe") 91 92 command.debugPrintln("target file path: ", command.targetFilePath) 93 94 command.cmd = kmgCmd.NewStdioCmd(command.context, "go", "build", "-o", command.targetFilePath, command.mainFilePath) 95 err = kmgCmd.SetCmdEnv(command.cmd, "GOPATH", command.GOPATH) 96 if err != nil { 97 return err 98 } 99 100 err = command.cmd.Run() 101 if err != nil { 102 return fmt.Errorf("rebuild error: %s", err.Error()) 103 } 104 _, err = os.Stat(command.targetFilePath) 105 if err != nil { 106 return err 107 } 108 command.cmd = kmgCmd.NewStdioCmd(command.context, command.targetFilePath) 109 err = kmgCmd.SetCmdEnv(command.cmd, "GOPATH", command.GOPATH) 110 if err != nil { 111 return err 112 } 113 err = command.cmd.Start() 114 if err != nil { 115 return fmt.Errorf("restart error: %s", err.Error()) 116 } 117 fmt.Println("[kmg] app running pid:", command.cmd.Process.Pid) 118 go func() { 119 cmd := command.cmd 120 err := cmd.Wait() 121 fmt.Println("[kmg] app exit pid:", cmd.Process.Pid) 122 if err != nil { 123 command.debugPrintln("wait error: ", err.Error()) 124 } 125 }() 126 return nil 127 } 128 129 func (command *GoWatch) stop() error { 130 if command.cmd == nil { 131 return nil 132 } 133 if command.cmd.Process == nil { 134 return nil 135 } 136 err := command.cmd.Process.Kill() 137 if err != nil { 138 command.debugPrintln("Process.Kill() error", err) 139 } 140 return nil 141 } 142 func (command *GoWatch) debugPrintln(o ...interface{}) { 143 if command.isDebug { 144 fmt.Println(o...) 145 } 146 } 147 */