// Compile 编译当前Project。 func (this *Project) Compile() error { path, err := os.Getwd() if err != nil { return err } this.ChangeToRoot() defer os.Chdir(path) // 删除bin中的文件 if this.GoWay == "build" { binFile := this.getExeFilePath() if files.Exist(binFile) { os.Remove(binFile) } } os.Chmod(installFileName, 0755) cmd := exec.Command(installCmd) var stdout bytes.Buffer cmd.Stdout = &stdout if err = cmd.Run(); err != nil { return err } output := strings.TrimSpace(stdout.String()) errFile := filepath.Join(this.errAbsolutePath, "error.html") if successFlag == output { // 删除可能的错误文件夹和文件 if files.Exist(errFile) { os.RemoveAll(this.errAbsolutePath) } return nil } // 往项目中写入错误信息 if !files.Exist(this.errAbsolutePath) { if err = os.Mkdir(this.errAbsolutePath, 0777); err != nil { log.Println("can't create errAbsolutePath: ", err) } } file, err := os.Create(errFile) if err != nil { return err } defer file.Close() output = strings.Replace(output, "finished", "", -1) tpl.Execute(file, output) return errors.New(output) }
// New 要求被监听项目必须有src目录(按Go习惯建目录) func New(name, root, goWay, mainFile string, deamon bool, depends ...string) (*Project, error) { if !files.IsDir(root) { return nil, PrjRootErr } if filepath.IsAbs(mainFile) { return nil, errors.New("main配置项必须是相对于项目src的相对路径!") } root, err := filepath.Abs(root) if err != nil { return nil, err } binAbsolutePath := filepath.Join(root, "bin") options := "" switch goWay { case "run": if mainFile == "" { mainFile = name + ".go" } mainFile = filepath.Join("src", mainFile) case "build": if mainFile == "" { mainFile = name + ".go" } mainFile = filepath.Join("src", mainFile) if !files.Exist(binAbsolutePath) { if err = os.Mkdir(binAbsolutePath, 0777); err != nil { return nil, err } } output := filepath.Join("bin", name+binanryFileSuffix) options = "-o " + output case "install": fallthrough default: if mainFile == "" { mainFile = name } else { mainFile = filepath.Dir(mainFile) } } return &Project{ name: name, Root: root, binAbsolutePath: binAbsolutePath, srcAbsolutePath: filepath.Join(root, "src"), errAbsolutePath: filepath.Join(root, "_log_"), GoWay: goWay, deamon: deamon, MainFile: mainFile, Options: options, Depends: depends, }, nil }
// Run 当GoWay==run时,直接通过该方法,而不需要先Compile然后Start func (this *Project) Run() error { path, err := os.Getwd() if err != nil { return err } this.ChangeToRoot() defer os.Chdir(path) os.Chmod(installFileName, 0755) cmd := exec.Command(installCmd) var stdout bytes.Buffer var stderr bytes.Buffer cmd.Stdout = &stdout cmd.Stderr = &stderr if err = cmd.Start(); err != nil { return err } // TODO:据说time.Sleep会内存泄露 select { case <-time.After(300e6): } output := strings.TrimSpace(stdout.String()) errOutput := strings.TrimSpace(stderr.String()) errFile := filepath.Join(this.errAbsolutePath, "error.html") if this.deamon { if output == "" { // 删除可能的错误文件夹和文件 if files.Exist(errFile) { os.RemoveAll(this.errAbsolutePath) } this.process = cmd.Process return nil } } else { log.Println("=====================") log.Println("[INFO] 项目", this.name, "的运行结果:") for _, val := range strings.Split(errOutput, "\n") { fmt.Println(val) } log.Println("=====================") return nil } if strings.Contains(errOutput, "listen tcp") { if err = this.process.Kill(); err == nil { this.Run() } return nil } // 往项目中写入错误信息 if !files.Exist(this.errAbsolutePath) { if err = os.Mkdir(this.errAbsolutePath, 0777); err != nil { log.Println("can't create errAbsolutePath: ", err) } } file, err := os.Create(errFile) if err != nil { return err } defer file.Close() tpl.Execute(file, errOutput) return errors.New(errOutput) }