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