func (c *runCommand) Run(args []string) (err error) { var basedir string var importPath string if len(args) > 0 { importPath = args[0] basedir, err = util.FindAbsDir(importPath) if err != nil { c, err := execCmd("go", "get", "-v", importPath) if err != nil { return err } if err := c.Wait(); err != nil { c.Process.Kill() return err } basedir, err = util.FindAbsDir(importPath) if err != nil { return err } } } else { basedir, err = os.Getwd() if err != nil { return err } } execName := filepath.Base(basedir) if runtime.GOOS == "windows" { execName += ".exe" } if err := util.PrintEnv(basedir); err != nil { return err } fmt.Println("Starting...") var cmd *exec.Cmd for { if cmd != nil { if err := cmd.Process.Signal(miyabi.ShutdownSignal); err != nil { cmd.Process.Kill() } if err := cmd.Wait(); err != nil { fmt.Fprintln(os.Stderr, err) } } newCmd, err := runApp(basedir, execName, importPath) if err != nil { fmt.Fprint(os.Stderr, err) } fmt.Println() cmd = newCmd if err := watchApp(basedir, execName); err != nil { if err := cmd.Process.Signal(miyabi.ShutdownSignal); err != nil { cmd.Process.Kill() } return err } fmt.Println("\nRestarting...") } }
func (c *buildCommand) Run(args []string) (err error) { var appDir string var dir string if len(args) > 0 { appDir = args[0] dir, err = util.FindAbsDir(appDir) if err != nil { return err } } else { dir, err = os.Getwd() if err != nil { return err } appDir, err = util.FindAppDir() if err != nil { return err } } appName := filepath.Base(dir) configPkg, err := getPackage(path.Join(appDir, "config")) if err != nil { return fmt.Errorf(`cannot import "%s": %v`, path.Join(appDir, "config"), err) } var dbImportPath string if dbPkg, err := getPackage(path.Join(appDir, "db")); err == nil { dbImportPath = dbPkg.ImportPath } var migrationImportPath string if migrationPkg, err := getPackage(path.Join(appDir, "db", "migration")); err == nil { migrationImportPath = migrationPkg.ImportPath } tmpDir, err := filepath.Abs("tmp") if err != nil { return err } if err := os.Mkdir(tmpDir, 0755); err != nil && !os.IsExist(err) { return fmt.Errorf("failed to create directory: %v", err) } _, filename, _, _ := runtime.Caller(0) baseDir := filepath.Dir(filename) skeletonDir := filepath.Join(baseDir, "skeleton", "build") mainTemplate, err := ioutil.ReadFile(filepath.Join(skeletonDir, "main.go"+util.TemplateSuffix)) if err != nil { return err } mainFilePath := filepath.ToSlash(filepath.Join(tmpDir, "main.go")) builderFilePath := filepath.ToSlash(filepath.Join(tmpDir, "builder.go")) file, err := os.Create(builderFilePath) if err != nil { return fmt.Errorf("failed to create file: %v", err) } defer file.Close() builderTemplatePath := filepath.ToSlash(filepath.Join(skeletonDir, "builder.go"+util.TemplateSuffix)) t := template.Must(template.ParseFiles(builderTemplatePath)) var resources map[string]string if c.option.All { resources = collectResourcePaths(filepath.Join(dir, kocha.StaticDir)) } tag, err := c.detectVersionTag() if err != nil { return err } data := map[string]interface{}{ "configImportPath": configPkg.ImportPath, "dbImportPath": dbImportPath, "migrationImportPath": migrationImportPath, "mainTemplate": string(mainTemplate), "mainFilePath": mainFilePath, "resources": resources, "version": tag, } if err := t.Execute(file, data); err != nil { return fmt.Errorf("failed to write file: %v", err) } file.Close() execName := appName if runtime.GOOS == "windows" { execName += ".exe" } if err := execCmdWithHostEnv("go", "run", builderFilePath); err != nil { return err } // To avoid to become a dynamic linked binary. // See https://github.com/golang/go/issues/9344 execPath := filepath.Join(dir, execName) execArgs := []string{"build", "-o", execPath, "-installsuffix", "."} // On Linux, works fine. On Windows, doesn't work. // On other platforms, not tested. if runtime.GOOS == "linux" { execArgs = append(execArgs, "-ldflags", `-extldflags "-static"`) } execArgs = append(execArgs, mainFilePath) if err := execCmd("go", execArgs...); err != nil { return err } if err := os.RemoveAll(tmpDir); err != nil { return err } if err := util.PrintEnv(dir); err != nil { return err } fmt.Printf("build all-in-one binary to %v\n", execPath) util.PrintGreen("Build successful!\n") return nil }