Skip to content

Commit

Permalink
reflect review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
isacikgoz committed Sep 11, 2024
1 parent ef76ea4 commit d4edf0d
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 71 deletions.
11 changes: 10 additions & 1 deletion cmd/migration-assist/commands/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,16 @@ func runSourceCheckCmdF(cmd *cobra.Command, args []string) error {
}

outputFile, _ := cmd.Flags().GetString("output")
if err = os.WriteFile(outputFile, b, 0600); err != nil {
if _, err = os.Stat(outputFile); err == nil || os.IsExist(err) {
if ConfirmationPrompt("Output file already exists, do you want to overwrite it?") {
if err = os.Remove(outputFile); err != nil {
return fmt.Errorf("could not remove output file: %w", err)
}
} else {
baseLogger.Println("Output file already exists, will not overwrite it.")
}
}
if err = os.WriteFile(outputFile, b, 0666); err != nil {
return fmt.Errorf("could not write to output file: %w", err)
}

Expand Down
148 changes: 79 additions & 69 deletions cmd/migration-assist/commands/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,23 @@ import (

func TargetCheckCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "postgres",
Short: "Checks the Postgres database schema whether it is ready for the migration",
RunE: runTargetCheckCmdF,
Example: " migration-assist postgres \"postgres://mmuser:mostest@localhost:8765/mattermost_test?sslmode=disable\" \\\n--run-migrations",
Args: cobra.MinimumNArgs(1),
Use: "postgres",
Short: "Checks the Postgres database schema whether it is ready for the migration",
RunE: runTargetCheckCmdF,
Example: " migration-assist postgres \"postgres://mmuser:mostest@localhost:8765/mattermost_test?sslmode=disable\" \\\n--run-migrations" +
"\n\n--mattermost-version, --migrations-dir, --applied-migrations are mutually exclusive. Use only one of these flags.\n",
Args: cobra.MinimumNArgs(1),
}

amCmd := RunAfterMigration()
cmd.AddCommand(amCmd)

// Optional flags
cmd.Flags().Bool("run-migrations", false, "Runs migrations for Postgres schema")
cmd.Flags().String("mattermost-version", "", "Mattermost version to be cloned to run migrations (example: v8.1)")
cmd.Flags().String("migrations-dir", "", "Migrations directory (should be used if mattermost-version is not supplied)")
cmd.Flags().String("git", "git", "git binary to be executed if the repository will be cloned")
cmd.Flags().String("mattermost-version", "", "Mattermost version to be cloned to run migrations (example: \"v8.1\")")
cmd.Flags().String("migrations-dir", "", "Migrations directory (should be used if the migrations are already cloned separately)")
cmd.Flags().String("applied-migrations", "", "File containing the list of applied migrations (example: \"mysql.output\")")
cmd.Flags().String("git", "git", "git binary to be executed if the repository will be cloned (ie. --mattermost-version is supplied)")
cmd.Flags().Bool("check-schema-owner", true, "Check if the schema owner is the same as the user running the migration")
cmd.Flags().Bool("check-tables-empty", true, "Check if tables are empty before running migrations")
cmd.PersistentFlags().String("schema", "public", "the default schema to be used for the session")
Expand Down Expand Up @@ -111,69 +113,13 @@ func runTargetCheckCmdF(cmd *cobra.Command, args []string) error {
return nil
}

mysqlMigrations := "mysql.output"
if len(args) > 1 {
mysqlMigrations = args[1]
}

var src sources.Source

// download required migrations if necessary
mysqlMigrations, _ := cmd.Flags().GetString("applied-migrations")
mmVersion, _ := cmd.Flags().GetString("mattermost-version")
migrationDir, _ := cmd.Flags().GetString("migrations-dir")
if _, err = os.Stat(mysqlMigrations); !os.IsNotExist(err) {
baseLogger.Printf("loading migrations from the %s file\n", mysqlMigrations)
// load migrations from the applied migrations file
var cfg store.DBConfig
f, err2 := os.Open(mysqlMigrations)
if err2 != nil {
return fmt.Errorf("could not open file: %w", err2)
}
defer f.Close()

err = json.NewDecoder(f).Decode(&cfg)
if err != nil {
return fmt.Errorf("could not decode file: %w", err)
}

src, err = store.CreateSourceFromEbmedded(queries.Assets(), "migrations/postgres", cfg.AppliedMigrations)
if err != nil {
return fmt.Errorf("could not create source from embedded: %w", err)
}
} else if migrationDir == "" {
mmVersion, _ := cmd.Flags().GetString("mattermost-version")
if mmVersion == "" {
return fmt.Errorf("--mattermost-version needs to be supplied to run migrations")
}
v, err2 := semver.ParseTolerant(mmVersion)
if err2 != nil {
return fmt.Errorf("could not parse mattermost version: %w", err2)
}

tempDir, err3 := os.MkdirTemp("", "mattermost")
if err3 != nil {
return fmt.Errorf("could not create temp directory: %w", err3)
}

baseLogger.Printf("cloning %s@%s\n", "repository", v.String())
err = git.CloneMigrations(git.CloneOptions{
TempRepoPath: tempDir,
Output: "postgres",
DriverType: "postgres",
Version: v,
}, verboseLogger)
if err != nil {
return fmt.Errorf("error during cloning migrations: %w", err)
}

src, err = file.Open("postgres")
if err != nil {
return fmt.Errorf("could not read migrations: %w", err)
}
} else {
src, err = file.Open(migrationDir)
if err != nil {
return fmt.Errorf("could not read migrations: %w", err)
}
src, err := determineSource(mysqlMigrations, migrationDir, mmVersion, baseLogger, verboseLogger)
if err != nil {
return fmt.Errorf("could not determine source: %w", err)
}

// run the migrations
Expand Down Expand Up @@ -221,3 +167,67 @@ func runPostMigrateCmdF(c *cobra.Command, args []string) error {

return nil
}

func determineSource(appliedMigrations, userSuppliedMigrations, mmVersion string, baseLogger, verboseLogger logger.LogInterface) (sources.Source, error) {
switch {
case appliedMigrations != "":
baseLogger.Printf("loading migrations from the %s file\n", appliedMigrations)
// load migrations from the applied migrations file
var cfg store.DBConfig
f, err2 := os.Open(appliedMigrations)
if err2 != nil {
return nil, fmt.Errorf("could not open file: %w", err2)
}
defer f.Close()

err := json.NewDecoder(f).Decode(&cfg)
if err != nil {
return nil, fmt.Errorf("could not decode file: %w", err)
}

src, err := store.CreateSourceFromEmbedded(queries.Assets(), "migrations/postgres", cfg.AppliedMigrations)
if err != nil {
return nil, fmt.Errorf("could not create source from embedded: %w", err)
}

return src, nil
case userSuppliedMigrations != "":
src, err := file.Open(userSuppliedMigrations)
if err != nil {
return nil, fmt.Errorf("could not read migrations: %w", err)
}

return src, nil
default:
if mmVersion == "" {
return nil, fmt.Errorf("--mattermost-version needs to be supplied to run migrations")
}
v, err2 := semver.ParseTolerant(mmVersion)
if err2 != nil {
return nil, fmt.Errorf("could not parse mattermost version: %w", err2)
}

tempDir, err3 := os.MkdirTemp("", "mattermost")
if err3 != nil {
return nil, fmt.Errorf("could not create temp directory: %w", err3)
}

baseLogger.Printf("cloning %s@%s\n", "repository", v.String())
err := git.CloneMigrations(git.CloneOptions{
TempRepoPath: tempDir,
Output: "postgres",
DriverType: "postgres",
Version: v,
}, baseLogger)
if err != nil {
return nil, fmt.Errorf("error during cloning migrations: %w", err)
}

src, err := file.Open("postgres")
if err != nil {
return nil, fmt.Errorf("could not read migrations: %w", err)
}

return src, nil
}
}
24 changes: 24 additions & 0 deletions cmd/migration-assist/commands/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package commands

import (
"bufio"
"fmt"
"os"
)

func ConfirmationPrompt(question string) bool {
fmt.Fprintf(os.Stderr, "%s [y/N]: ", question)

rd := bufio.NewReader(os.Stdin)
r, err := rd.ReadString('\n')
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading input: %v\n", err)
return false
}

if len(r) > 0 && (r[0] == 'y' || r[0] == 'Y') {
return true
}

return false
}
2 changes: 1 addition & 1 deletion internal/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func (db *DB) RunMigrations(src sources.Source) error {
return nil
}

func CreateSourceFromEbmedded(assets embed.FS, dir string, versions []int) (sources.Source, error) {
func CreateSourceFromEmbedded(assets embed.FS, dir string, versions []int) (sources.Source, error) {
dirEntries, err := assets.ReadDir(dir)
if err != nil {
return nil, err
Expand Down

0 comments on commit d4edf0d

Please sign in to comment.