github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/db/migration/cli/command/command.go (about) 1 package cli 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path" 8 "text/template" 9 "time" 10 ) 11 12 var defaultMigrationDir = "migrations/" 13 14 type MigrationType string 15 16 const ( 17 SQL MigrationType = "sql" 18 Go MigrationType = "go" 19 ) 20 21 type MigrationCommand struct { 22 GenerateCommand GenerateCommand `command:"generate"` 23 } 24 25 type GenerateCommand struct { 26 MigrationDirectory string `short:"d" long:"directory" default:"migrations" description:"The directory to which the migration files should be written"` 27 MigrationName string `short:"n" long:"name" description:"The name of the migration"` 28 Type MigrationType `short:"t" long:"type" description:"The file type of the migration"` 29 } 30 31 func NewGenerateCommand(migrationDir string, migrationName string, migrationType MigrationType) *GenerateCommand { 32 if migrationDir == "" { 33 migrationDir = defaultMigrationDir 34 } 35 36 return &GenerateCommand{ 37 migrationDir, 38 migrationName, 39 migrationType, 40 } 41 } 42 43 func (c *GenerateCommand) Execute(args []string) error { 44 if c.Type == SQL { 45 return c.GenerateSQLMigration() 46 } else if c.Type == Go { 47 return c.GenerateGoMigration() 48 } 49 return fmt.Errorf("unsupported migration type %s. Supported types include %s and %s", c.Type, SQL, Go) 50 } 51 52 func (c *GenerateCommand) GenerateSQLMigration() error { 53 currentTime := time.Now().Unix() 54 fileNameFormat := "%d_%s.%s.sql" 55 56 upMigrationFileName := fmt.Sprintf(fileNameFormat, currentTime, c.MigrationName, "up") 57 downMigrationFileName := fmt.Sprintf(fileNameFormat, currentTime, c.MigrationName, "down") 58 59 contents := "" 60 61 err := ioutil.WriteFile(path.Join(c.MigrationDirectory, upMigrationFileName), []byte(contents), 0644) 62 if err != nil { 63 return err 64 } 65 err = ioutil.WriteFile(path.Join(c.MigrationDirectory, downMigrationFileName), []byte(contents), 0644) 66 if err != nil { 67 return err 68 } 69 return nil 70 } 71 72 type migrationInfo struct { 73 MigrationId int64 74 Direction string 75 } 76 77 const goMigrationTemplate = `package migrations 78 79 // implement the migration in this function 80 func {{ .Direction }}_{{ .MigrationId }}() error { 81 return nil 82 }` 83 84 func renderGoMigrationToFile(filePath string, state migrationInfo) error { 85 migrationFile, err := os.Create(filePath) 86 if err != nil { 87 return err 88 } 89 defer migrationFile.Close() 90 91 tmpl, err := template.New("go-migration-template").Parse(goMigrationTemplate) 92 if err != nil { 93 return err 94 } 95 96 err = tmpl.Execute(migrationFile, state) 97 if err != nil { 98 return err 99 } 100 101 return nil 102 } 103 104 func (c *GenerateCommand) GenerateGoMigration() error { 105 currentTime := time.Now().Unix() 106 fileNameFormat := "%d_%s.%s.go" 107 108 upMigrationFileName := fmt.Sprintf(fileNameFormat, currentTime, c.MigrationName, "up") 109 downMigrationFileName := fmt.Sprintf(fileNameFormat, currentTime, c.MigrationName, "down") 110 111 err := renderGoMigrationToFile(path.Join(c.MigrationDirectory, upMigrationFileName), migrationInfo{ 112 MigrationId: currentTime, 113 Direction: "Up", 114 }) 115 if err != nil { 116 return err 117 } 118 119 err = renderGoMigrationToFile(path.Join(c.MigrationDirectory, downMigrationFileName), migrationInfo{ 120 MigrationId: currentTime, 121 Direction: "Down", 122 }) 123 if err != nil { 124 return err 125 } 126 127 return nil 128 }