Example #1
0
File: main.go Project: naoina/kocha
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...")
	}
}
Example #2
0
File: main.go Project: naoina/kocha
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
}