diff --git a/CHANGELOG.md b/CHANGELOG.md index f1f93d9dab8..ce3ef0f62a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ ## Next release +### cli: add support for .env file + +ENV vars can now be read from .env file present at the project root directory. A global flag, `--envfile`, is added so you can explicitly provide the .env filename, which defaults to `.env` filename if no flag is provided. + +**Example**: + +``` +hasura console --envfile production.env +``` +The above command will read ENV vars from `production.env` file present at the project root directory. + +(close #4129) (#4454) + ### console: allow setting post-update check in update permissions Along with the check for filtering rows that can be updated, you can now set a post-update permission check that needs to be satisfied by the updated rows after the update is made. diff --git a/cli/cli.go b/cli/cli.go index b3eefbc380b..8e317223763 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -30,6 +30,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/viper" + "github.com/subosito/gotenv" "golang.org/x/crypto/ssh/terminal" "gopkg.in/yaml.v2" ) @@ -206,6 +207,8 @@ type ExecutionContext struct { // ExecutionDirectory is the directory in which command is being executed. ExecutionDirectory string + // Envfile is the .env file to load ENV vars from + Envfile string // MigrationDir is the name of directory where migrations are stored. MigrationDir string // MetadataDir is the name of directory where metadata files are stored. @@ -412,6 +415,11 @@ func (ec *ExecutionContext) Validate() error { return errors.Wrap(err, "validating current directory failed") } + // load .env file + err = ec.loadEnvfile() + if err != nil { + return errors.Wrap(err, "loading .env file failed") + } // set names of config file ec.ConfigFile = filepath.Join(ec.ExecutionDirectory, "config.yaml") @@ -588,6 +596,25 @@ func (ec *ExecutionContext) Spin(message string) { } } +// loadEnvfile loads .env file +func (ec *ExecutionContext) loadEnvfile() error { + envfile := filepath.Join(ec.ExecutionDirectory, ec.Envfile) + err := gotenv.Load(envfile) + if err != nil { + // return error if user provided envfile name + if ec.Envfile != ".env" { + return err + } + if !os.IsNotExist(err) { + ec.Logger.Warn(err) + } + } + if err == nil { + ec.Logger.Debug("ENV vars read from: ", envfile) + } + return nil +} + // setupLogger creates a default logger if context does not have one set. func (ec *ExecutionContext) setupLogger() { if ec.Logger == nil { diff --git a/cli/commands/root.go b/cli/commands/root.go index 59235c04910..85f6dc4d2a9 100644 --- a/cli/commands/root.go +++ b/cli/commands/root.go @@ -77,6 +77,7 @@ func init() { f.StringVar(&ec.ExecutionDirectory, "project", "", "directory where commands are executed (default: current dir)") f.BoolVar(&ec.SkipUpdateCheck, "skip-update-check", false, "Skip automatic update check on command execution") f.BoolVar(&ec.NoColor, "no-color", false, "do not colorize output (default: false)") + f.StringVar(&ec.Envfile, "envfile", ".env", ".env filename to load ENV vars from") } // NewDefaultHasuraCommand creates the `hasura` command with default arguments diff --git a/cli/go.mod b/cli/go.mod index 396d6d28277..800d822ac1f 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -53,6 +53,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.6.1 github.com/stretchr/testify v1.4.0 + github.com/subosito/gotenv v1.2.0 github.com/theplant/cldr v0.0.0-20190423050709-9f76f7ce4ee8 // indirect github.com/theplant/htmltestingutils v0.0.0-20190423050759-0e06de7b6967 // indirect github.com/theplant/testingutils v0.0.0-20190603093022-26d8b4d95c61 // indirect