Skip to content

Commit 14a3bcd

Browse files
authored
Merge pull request #236 from KlotzAndrew/migrate-down-less-destructive
migrate down less destructive
2 parents d4e8e9a + ffea024 commit 14a3bcd

File tree

3 files changed

+88
-8
lines changed

3 files changed

+88
-8
lines changed

internal/cli/commands.go

+25
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,28 @@ func versionCmd(m *migrate.Migrate) {
182182
log.Println(v)
183183
}
184184
}
185+
186+
// numDownMigrationsFromArgs returns an int for number of migrations to apply
187+
// and a bool indicating if we need a confirm before applying
188+
func numDownMigrationsFromArgs(applyAll bool, args []string) (int, bool, error) {
189+
if applyAll {
190+
if len(args) > 0 {
191+
return 0, false, errors.New("-all cannot be used with other arguments")
192+
}
193+
return -1, false, nil
194+
}
195+
196+
switch len(args) {
197+
case 0:
198+
return -1, true, nil
199+
case 1:
200+
downValue := args[0]
201+
n, err := strconv.ParseUint(downValue, 10, 64)
202+
if err != nil {
203+
return 0, false, errors.New("can't read limit argument N")
204+
}
205+
return int(n), false, nil
206+
default:
207+
return 0, false, errors.New("too many arguments")
208+
}
209+
}

internal/cli/commands_test.go

+38
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,41 @@ func TestNextSeq(t *testing.T) {
7878
})
7979
}
8080
}
81+
82+
func TestNumDownFromArgs(t *testing.T) {
83+
cases := []struct {
84+
name string
85+
args []string
86+
applyAll bool
87+
expectedNeedConfirm bool
88+
expectedNum int
89+
expectedErrStr string
90+
}{
91+
{"no args", []string{}, false, true, -1, ""},
92+
{"down all", []string{}, true, false, -1, ""},
93+
{"down 5", []string{"5"}, false, false, 5, ""},
94+
{"down N", []string{"N"}, false, false, 0, "can't read limit argument N"},
95+
{"extra arg after -all", []string{"5"}, true, false, 0, "-all cannot be used with other arguments"},
96+
{"extra arg before -all", []string{"5", "-all"}, false, false, 0, "too many arguments"},
97+
}
98+
for _, c := range cases {
99+
t.Run(c.name, func(t *testing.T) {
100+
num, needsConfirm, err := numDownMigrationsFromArgs(c.applyAll, c.args)
101+
if needsConfirm != c.expectedNeedConfirm {
102+
t.Errorf("Incorrect needsConfirm was: %v wanted %v", needsConfirm, c.expectedNeedConfirm)
103+
}
104+
105+
if num != c.expectedNum {
106+
t.Errorf("Incorrect num was: %v wanted %v", num, c.expectedNum)
107+
}
108+
109+
if err != nil {
110+
if err.Error() != c.expectedErrStr {
111+
t.Error("Incorrect error: " + err.Error() + " != " + c.expectedErrStr)
112+
}
113+
} else if c.expectedErrStr != "" {
114+
t.Error("Expected error: " + c.expectedErrStr + " but got nil instead")
115+
}
116+
})
117+
}
118+
}

internal/cli/main.go

+25-8
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func Main(version string) {
3737
3838
Options:
3939
-source Location of the migrations (driver://url)
40-
-path Shorthand for -source=file://path
40+
-path Shorthand for -source=file://path
4141
-database Run migrations against this database (driver://url)
4242
-prefetch N Number of migrations to load in advance before executing (default 10)
4343
-lock-timeout N Allow N seconds to acquire database lock (default 15)
@@ -186,16 +186,33 @@ Database drivers: `+strings.Join(database.List(), ", ")+"\n")
186186
log.fatalErr(migraterErr)
187187
}
188188

189-
limit := -1
190-
if flag.Arg(1) != "" {
191-
n, err := strconv.ParseUint(flag.Arg(1), 10, 64)
192-
if err != nil {
193-
log.fatal("error: can't read limit argument N")
189+
downFlagSet := flag.NewFlagSet("down", flag.ExitOnError)
190+
applyAll := downFlagSet.Bool("all", false, "Apply all down migrations")
191+
192+
args := flag.Args()[1:]
193+
if err := downFlagSet.Parse(args); err != nil {
194+
log.fatalErr(err)
195+
}
196+
197+
downArgs := downFlagSet.Args()
198+
num, needsConfirm, err := numDownMigrationsFromArgs(*applyAll, downArgs)
199+
if err != nil {
200+
log.fatalErr(err)
201+
}
202+
if needsConfirm {
203+
log.Println("Are you sure you want to apply all down migrations? [y/N]")
204+
var response string
205+
fmt.Scanln(&response)
206+
response = strings.ToLower(strings.TrimSpace(response))
207+
208+
if response == "y" {
209+
log.Println("Applying all down migrations")
210+
} else {
211+
log.fatal("Not applying all down migrations")
194212
}
195-
limit = int(n)
196213
}
197214

198-
downCmd(migrater, limit)
215+
downCmd(migrater, num)
199216

200217
if log.verbose {
201218
log.Println("Finished after", time.Since(startTime))

0 commit comments

Comments
 (0)