Esempio n. 1
0
// Run generates migration templates.
func (c *generateMigrationCommand) Run(args []string) error {
	if len(args) < 1 || args[0] == "" {
		return fmt.Errorf("no NAME given")
	}
	name := args[0]
	if c.option.ORM == "" {
		c.option.ORM = defaultORM
	}
	orm, exists := ORM[c.option.ORM]
	if !exists {
		return fmt.Errorf("unsupported ORM: `%v'", c.option.ORM)
	}
	now := _time.Now().Format("20060102150405")
	data := map[string]interface{}{
		"Name":       util.ToCamelCase(name),
		"TimeStamp":  now,
		"ImportPath": orm.ImportPath(),
		"TxType":     reflect.TypeOf(orm.TransactionType()).String(),
	}
	if err := util.CopyTemplate(
		filepath.Join(skeletonDir("migration"), "migration.go"+util.TemplateSuffix),
		filepath.Join("db", "migration", fmt.Sprintf("%v_%v.go", now, util.ToSnakeCase(name))),
		data,
	); err != nil {
		return err
	}
	initPath := filepath.Join("db", "migration", "init.go")
	if _, err := os.Stat(initPath); os.IsNotExist(err) {
		appDir, err := util.FindAppDir()
		if err != nil {
			return err
		}
		if err := util.CopyTemplate(
			filepath.Join(skeletonDir("migration"), "init.go"+util.TemplateSuffix),
			initPath, map[string]interface{}{
				"typeName":     c.option.ORM,
				"tx":           strings.TrimSpace(util.GoString(orm)),
				"dbImportPath": path.Join(appDir, "db"),
			},
		); err != nil {
			return err
		}
	}
	return nil
}
Esempio n. 2
0
func (c *buildCommand) Run(args []string) error {
	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
	execArgs := []string{"build", "-o", execName, "-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(); err != nil {
		return err
	}
	fmt.Printf("build all-in-one binary to %v\n", filepath.Join(dir, execName))
	util.PrintGreen("Build successful!\n")
	return nil
}
Esempio n. 3
0
func (c *migrateCommand) Run(args []string) error {
	if len(args) < 1 || !isValidDirection(args[0]) {
		return fmt.Errorf("no `up' or `down' specified")
	}
	if c.option.Limit < 1 {
		if c.option.Limit == 0 {
			c.option.Limit = -1
		} else {
			return fmt.Errorf("`limit' must be greater than or equal to 1")
		}
	}
	if c.option.DBConf == "" {
		c.option.DBConf = defaultDBConf
	}
	direction := args[0]
	tmpDir, err := filepath.Abs("tmp")
	if err != nil {
		return err
	}
	if err := os.MkdirAll(tmpDir, 0755); err != nil && !os.IsExist(err) {
		return fmt.Errorf("failed to create directory: %v", err)
	}
	_, filename, _, _ := runtime.Caller(0)
	skeletonDir := filepath.Join(filepath.Dir(filename), "skeleton", "migrate")
	t := template.Must(template.ParseFiles(filepath.Join(skeletonDir, direction+".go"+util.TemplateSuffix)))
	mainFilePath := filepath.ToSlash(filepath.Join(tmpDir, "migrate.go"))
	file, err := os.Create(mainFilePath)
	if err != nil {
		return fmt.Errorf("failed to create file: %v", err)
	}
	defer file.Close()
	appDir, err := util.FindAppDir()
	if err != nil {
		return err
	}
	dbPkg, err := getPackage(path.Join(appDir, "db"))
	if err != nil {
		return err
	}
	migrationPkg, err := getPackage(path.Join(appDir, "db", "migration"))
	if err != nil {
		return err
	}
	data := map[string]interface{}{
		"dbImportPath":        dbPkg.ImportPath,
		"migrationImportPath": migrationPkg.ImportPath,
		"dbconf":              c.option.DBConf,
		"limit":               c.option.Limit,
	}
	if err := t.Execute(file, data); err != nil {
		return fmt.Errorf("failed to write file: %v", err)
	}
	if err := execCmd("go", "run", mainFilePath); err != nil {
		return err
	}
	if err := os.RemoveAll(tmpDir); err != nil {
		return err
	}
	util.PrintGreen("All migrations are successful!\n")
	return nil
}