mirror of https://github.com/pressly/goose.git
feat: Set table name based on flag or environment variable (#932)
parent
b63ff992a7
commit
46ae662098
|
@ -247,6 +247,7 @@ arguments, you can set the following environment variables:
|
||||||
export GOOSE_DRIVER=DRIVER
|
export GOOSE_DRIVER=DRIVER
|
||||||
export GOOSE_DBSTRING=DBSTRING
|
export GOOSE_DBSTRING=DBSTRING
|
||||||
export GOOSE_MIGRATION_DIR=MIGRATION_DIR
|
export GOOSE_MIGRATION_DIR=MIGRATION_DIR
|
||||||
|
export GOOSE_TABLE=TABLENAME
|
||||||
```
|
```
|
||||||
|
|
||||||
**2. Via `.env` files with corresponding variables. `.env` file example**:
|
**2. Via `.env` files with corresponding variables. `.env` file example**:
|
||||||
|
@ -255,6 +256,7 @@ export GOOSE_MIGRATION_DIR=MIGRATION_DIR
|
||||||
GOOSE_DRIVER=postgres
|
GOOSE_DRIVER=postgres
|
||||||
GOOSE_DBSTRING=postgres://admin:admin@localhost:5432/admin_db
|
GOOSE_DBSTRING=postgres://admin:admin@localhost:5432/admin_db
|
||||||
GOOSE_MIGRATION_DIR=./migrations
|
GOOSE_MIGRATION_DIR=./migrations
|
||||||
|
GOOSE_TABLE=custom.goose_migrations
|
||||||
```
|
```
|
||||||
|
|
||||||
Loading from `.env` files is enabled by default. To disable this feature, set the `-env=none` flag.
|
Loading from `.env` files is enabled by default. To disable this feature, set the `-env=none` flag.
|
||||||
|
|
|
@ -28,7 +28,7 @@ var (
|
||||||
|
|
||||||
flags = flag.NewFlagSet("goose", flag.ExitOnError)
|
flags = flag.NewFlagSet("goose", flag.ExitOnError)
|
||||||
dir = flags.String("dir", DefaultMigrationDir, "directory with migration files, (GOOSE_MIGRATION_DIR env variable supported)")
|
dir = flags.String("dir", DefaultMigrationDir, "directory with migration files, (GOOSE_MIGRATION_DIR env variable supported)")
|
||||||
table = flags.String("table", "goose_db_version", "migrations table name")
|
table = flags.String("table", "", "migrations table name")
|
||||||
verbose = flags.Bool("v", false, "enable verbose mode")
|
verbose = flags.Bool("v", false, "enable verbose mode")
|
||||||
help = flags.Bool("h", false, "print help")
|
help = flags.Bool("h", false, "print help")
|
||||||
versionFlag = flags.Bool("version", false, "print version")
|
versionFlag = flags.Bool("version", false, "print version")
|
||||||
|
@ -83,7 +83,9 @@ func main() {
|
||||||
if *sequential {
|
if *sequential {
|
||||||
goose.SetSequential(true)
|
goose.SetSequential(true)
|
||||||
}
|
}
|
||||||
goose.SetTableName(*table)
|
|
||||||
|
// The order of precedence should be: flag > env variable > default value.
|
||||||
|
goose.SetTableName(firstNonEmpty(*table, envConfig.table, goose.DefaultTablename))
|
||||||
|
|
||||||
args := flags.Args()
|
args := flags.Args()
|
||||||
|
|
||||||
|
@ -421,6 +423,7 @@ type envConfig struct {
|
||||||
driver string
|
driver string
|
||||||
dbstring string
|
dbstring string
|
||||||
dir string
|
dir string
|
||||||
|
table string
|
||||||
noColor bool
|
noColor bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,6 +432,7 @@ func loadEnvConfig() *envConfig {
|
||||||
return &envConfig{
|
return &envConfig{
|
||||||
driver: envOr("GOOSE_DRIVER", ""),
|
driver: envOr("GOOSE_DRIVER", ""),
|
||||||
dbstring: envOr("GOOSE_DBSTRING", ""),
|
dbstring: envOr("GOOSE_DBSTRING", ""),
|
||||||
|
table: envOr("GOOSE_TABLE", ""),
|
||||||
dir: envOr("GOOSE_MIGRATION_DIR", DefaultMigrationDir),
|
dir: envOr("GOOSE_MIGRATION_DIR", DefaultMigrationDir),
|
||||||
// https://no-color.org/
|
// https://no-color.org/
|
||||||
noColor: noColorBool,
|
noColor: noColorBool,
|
||||||
|
@ -440,6 +444,7 @@ func (c *envConfig) listEnvs() []envVar {
|
||||||
{Name: "GOOSE_DRIVER", Value: c.driver},
|
{Name: "GOOSE_DRIVER", Value: c.driver},
|
||||||
{Name: "GOOSE_DBSTRING", Value: c.dbstring},
|
{Name: "GOOSE_DBSTRING", Value: c.dbstring},
|
||||||
{Name: "GOOSE_MIGRATION_DIR", Value: c.dir},
|
{Name: "GOOSE_MIGRATION_DIR", Value: c.dir},
|
||||||
|
{Name: "GOOSE_TABLE", Value: c.table},
|
||||||
{Name: "NO_COLOR", Value: strconv.FormatBool(c.noColor)},
|
{Name: "NO_COLOR", Value: strconv.FormatBool(c.noColor)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -457,3 +462,13 @@ func envOr(key, def string) string {
|
||||||
}
|
}
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// firstNonEmpty returns the first non-empty string from the provided input or an empty string if all are empty.
|
||||||
|
func firstNonEmpty(values ...string) string {
|
||||||
|
for _, v := range values {
|
||||||
|
if v != "" {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFirstNonEmpty(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input []string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no values",
|
||||||
|
input: []string{},
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "all empty values",
|
||||||
|
input: []string{"", "", ""},
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single non-empty value at start",
|
||||||
|
input: []string{"value", "", ""},
|
||||||
|
expected: "value",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single non-empty value in middle",
|
||||||
|
input: []string{"", "value", ""},
|
||||||
|
expected: "value",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single non-empty value at end",
|
||||||
|
input: []string{"", "", "value"},
|
||||||
|
expected: "value",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple non-empty values",
|
||||||
|
input: []string{"first", "second", "third"},
|
||||||
|
expected: "first",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "mixed empty and non-empty values",
|
||||||
|
input: []string{"", "value1", "", "value2"},
|
||||||
|
expected: "value1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "only one value, empty",
|
||||||
|
input: []string{""},
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "only one value, non-empty",
|
||||||
|
input: []string{"value"},
|
||||||
|
expected: "value",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := firstNonEmpty(tt.input...)
|
||||||
|
if result != tt.expected {
|
||||||
|
t.Errorf("expected %q, got %q", tt.expected, result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue