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  */