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_DBSTRING=DBSTRING
|
||||
export GOOSE_MIGRATION_DIR=MIGRATION_DIR
|
||||
export GOOSE_TABLE=TABLENAME
|
||||
```
|
||||
|
||||
**2. Via `.env` files with corresponding variables. `.env` file example**:
|
||||
|
@ -255,6 +256,7 @@ export GOOSE_MIGRATION_DIR=MIGRATION_DIR
|
|||
GOOSE_DRIVER=postgres
|
||||
GOOSE_DBSTRING=postgres://admin:admin@localhost:5432/admin_db
|
||||
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.
|
||||
|
|
|
@ -28,7 +28,7 @@ var (
|
|||
|
||||
flags = flag.NewFlagSet("goose", flag.ExitOnError)
|
||||
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")
|
||||
help = flags.Bool("h", false, "print help")
|
||||
versionFlag = flags.Bool("version", false, "print version")
|
||||
|
@ -83,7 +83,9 @@ func main() {
|
|||
if *sequential {
|
||||
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()
|
||||
|
||||
|
@ -421,6 +423,7 @@ type envConfig struct {
|
|||
driver string
|
||||
dbstring string
|
||||
dir string
|
||||
table string
|
||||
noColor bool
|
||||
}
|
||||
|
||||
|
@ -429,6 +432,7 @@ func loadEnvConfig() *envConfig {
|
|||
return &envConfig{
|
||||
driver: envOr("GOOSE_DRIVER", ""),
|
||||
dbstring: envOr("GOOSE_DBSTRING", ""),
|
||||
table: envOr("GOOSE_TABLE", ""),
|
||||
dir: envOr("GOOSE_MIGRATION_DIR", DefaultMigrationDir),
|
||||
// https://no-color.org/
|
||||
noColor: noColorBool,
|
||||
|
@ -440,6 +444,7 @@ func (c *envConfig) listEnvs() []envVar {
|
|||
{Name: "GOOSE_DRIVER", Value: c.driver},
|
||||
{Name: "GOOSE_DBSTRING", Value: c.dbstring},
|
||||
{Name: "GOOSE_MIGRATION_DIR", Value: c.dir},
|
||||
{Name: "GOOSE_TABLE", Value: c.table},
|
||||
{Name: "NO_COLOR", Value: strconv.FormatBool(c.noColor)},
|
||||
}
|
||||
}
|
||||
|
@ -457,3 +462,13 @@ func envOr(key, def string) string {
|
|||
}
|
||||
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