From 9974f3dadd5d8e6025c2a240049b85828313a2cc Mon Sep 17 00:00:00 2001 From: Quinten Palmer Date: Fri, 16 Nov 2018 13:33:22 -0500 Subject: [PATCH 1/3] Rename to GetConfigFromFile This function reads the map of config environments to Environment structs from the dbconfig.yml file. We want to allow these commands to also read from the shell environment, so for unambiguous names this is being renamed. --- sql-migrate/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql-migrate/config.go b/sql-migrate/config.go index 67906065..eb600c27 100644 --- a/sql-migrate/config.go +++ b/sql-migrate/config.go @@ -39,7 +39,7 @@ type Environment struct { SchemaName string `yaml:"schema"` } -func ReadConfig() (map[string]*Environment, error) { +func ReadConfigFromFile() (map[string]*Environment, error) { file, err := ioutil.ReadFile(ConfigFile) if err != nil { return nil, err @@ -55,7 +55,7 @@ func ReadConfig() (map[string]*Environment, error) { } func GetEnvironment() (*Environment, error) { - config, err := ReadConfig() + config, err := ReadConfigFromFile() if err != nil { return nil, err } From 0c5f5e41d16a9a7c9ea602a0e187be3b4dadfc55 Mon Sep 17 00:00:00 2001 From: Quinten Palmer Date: Fri, 16 Nov 2018 13:39:32 -0500 Subject: [PATCH 2/3] ReadEnvFromFile now returns the env instead of a config This is in the same vein of the previous commit where we want to be able to parse an Environment from the shell environment, so to make that switch easier, this function now returns the Environemnt and can be substituted for another function which reads from the environment. --- sql-migrate/config.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sql-migrate/config.go b/sql-migrate/config.go index eb600c27..b32c307a 100644 --- a/sql-migrate/config.go +++ b/sql-migrate/config.go @@ -39,7 +39,7 @@ type Environment struct { SchemaName string `yaml:"schema"` } -func ReadConfigFromFile() (map[string]*Environment, error) { +func ReadEnvFromFile() (*Environment, error) { file, err := ioutil.ReadFile(ConfigFile) if err != nil { return nil, err @@ -51,20 +51,20 @@ func ReadConfigFromFile() (map[string]*Environment, error) { return nil, err } - return config, nil + env := config[ConfigEnvironment] + if env == nil { + return nil, errors.New("No environment: " + ConfigEnvironment) + } + + return env, nil } func GetEnvironment() (*Environment, error) { - config, err := ReadConfigFromFile() + env, err := ReadEnvFromFile() if err != nil { return nil, err } - env := config[ConfigEnvironment] - if env == nil { - return nil, errors.New("No environment: " + ConfigEnvironment) - } - if env.Dialect == "" { return nil, errors.New("No dialect specified") } From b0d42304b35b60443fe1428726e4c70bc610a5a3 Mon Sep 17 00:00:00 2001 From: Quinten Palmer Date: Fri, 16 Nov 2018 14:30:01 -0500 Subject: [PATCH 3/3] Fallback to reading Environment from shell Env We want to build the ability for this command to accept the Environment through the shell env. If the file is not present, we optimistically look for the Environment in said shell env. There are existing zero-value checks to make sure that a user doesn't accidentally end up with no values for anything if their file was empty. We do a separate stat to check for the file to keep the complexity of the fallback simpler. The envconfig package can be researched more here: https://github.com/kelseyhightower/envconfig --- sql-migrate/config.go | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/sql-migrate/config.go b/sql-migrate/config.go index b32c307a..a845e4f8 100644 --- a/sql-migrate/config.go +++ b/sql-migrate/config.go @@ -8,6 +8,7 @@ import ( "io/ioutil" "os" + "github.com/kelseyhightower/envconfig" "github.com/rubenv/sql-migrate" "gopkg.in/gorp.v1" "gopkg.in/yaml.v2" @@ -32,11 +33,24 @@ func ConfigFlags(f *flag.FlagSet) { } type Environment struct { - Dialect string `yaml:"dialect"` - DataSource string `yaml:"datasource"` - Dir string `yaml:"dir"` - TableName string `yaml:"table"` - SchemaName string `yaml:"schema"` + Dialect string `yaml:"dialect" envconfig:"DIALECT"` + DataSource string `yaml:"datasource" envconfig:"DATASOURCE"` + Dir string `yaml:"dir" envconfig:"DIR"` + TableName string `yaml:"table" envconfig:"TABLE"` + SchemaName string `yaml:"schema" envconfig:"SCHEMA"` +} + +func ConfigPresent() bool { + _, err := os.Stat(ConfigFile) + return !os.IsNotExist(err) +} + +func ReadEnv() (*Environment, error) { + env := &Environment{} + if err := envconfig.Process("", env); err != nil { + return nil, err + } + return env, nil } func ReadEnvFromFile() (*Environment, error) { @@ -60,9 +74,19 @@ func ReadEnvFromFile() (*Environment, error) { } func GetEnvironment() (*Environment, error) { - env, err := ReadEnvFromFile() - if err != nil { - return nil, err + var env *Environment + if ConfigPresent() { + var err error + env, err = ReadEnvFromFile() + if err != nil { + return nil, err + } + } else { + var err error + env, err = ReadEnv() + if err != nil { + return nil, err + } } if env.Dialect == "" {