- Notifications
You must be signed in to change notification settings - Fork42
Ensures presence and type of your app's ENV-variables (mirror)
License
eval/envied
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Seehttps://github.com/eval/nero for a modern replacement.
For the rationale behind this project, see thisblogpost.
- check for presence and correctness of ENV-variables
- access to typed ENV-variables (integers, booleans etc. instead of just strings)
- check the presence and correctness of a Heroku config
- provide or load ENV-values
- Quickstart
- Installation
- Configuration
- Command-line interface
- Best Practices
- FAQ
- Testing
- Development
- Contributing
Aftersuccessful installation, define some variables inEnvfile
:
# file: Envfilevariable:FORCE_SSL,:booleanvariable:PORT,:integer
# during initializationENVied.require
This will throw an error if:
- one of
ENV['FORCE_SSL']
,ENV['PORT']
is absent. - or: their valuescannot be coerced (resp. to boolean and integer).
Variables accessed via ENVied are of the correct type:
ENVied.PORT# => 3001ENVied.FORCE_SSL# => false
The following types are supported:
:array
(e.g. 'tag1,tag2' becomes['tag1', 'tag2']
):boolean
(e.g. '0'/'1', 'f'/'t', 'false'/'true', 'off'/'on', 'no'/'yes' for resp. false and true):date
(e.g. '2014-3-26'):env
(similar to:string
, but accessible via ENV - seeKey alias for details):float
:hash
(e.g. 'a=1&b=2' becomes{'a' => '1', 'b' => '2'}
):integer
:string
(implied):symbol
:time
(e.g. '14:00'):uri
(e.g. 'http://www.google.com' becomes result ofURI.parse('http://www.google.com')
)
By default the value for variableFOO
should be provided byENV['FOO']
. Sometimes though it's convenient to let a different key provide the value, based on some runtime condition. A key-alias will let you do this.
Consider for example local development whereREDIS_URL
differs between the development and test environment. Normally you'd prepare different shells with different values forREDIS_URL
: one shell you can run tests in, and other shells where you'd run the console/server etc. This is cumbersome and easy to get wrong.
With a key alias that's calculated at runtime (e.g.Rails.env
) you'd set values for bothREDIS_URL_TEST
andREDIS_URL_DEVELOPMENT
and the right value will be used for test and development.
Full example:
# file: Envfilekey_alias! { Rails.env }variable :REDIS_URL, :uri
Source the following in your environment:
# file: .envrcexport REDIS_URL_DEVELOPMENT=redis://localhost:6379/0export REDIS_URL_TEST=redis://localhost:6379/1
Now commands likerails console
andrails test
automatically point to the right redis database.
Note thatENV['REDIS_URL']
is still considered butREDIS_URL_<key_alias>
takes precedence.
Also: any truthy value provided as key_alias is converted to an upcased string.
Finally: this setting is optional.
Variables of type:env
take the key alias into account when accessingENV['FOO']
.
Say, your application usesENV['DATABASE_URL']
(wich you can't change toENVied.DATABASE_URL
). Normally this would mean that the key alias has no effect. For env-type variables however, the key alias is taken into account:
# file: Envfilekey_alias! { Rails.env }variable :DATABASE_URL, :env
The following now works:
$ DATABASE_URL_DEVELOPMENT=postgres://localhost/blog_development rails runner"p ENV['DATABASE_URL']""postgres://localhost/blog_development"
Note: this also works forENV.fetch('FOO')
.
Also: no coercion is done (like you would expect when accessing ENV-values directly).
This means that for Rails applications when you set values forDATABASE_URL_DEVELOPMENT
andDATABASE_URL_TEST
, you no longer need aconfig/database.yml
.
Groups give you more flexibility to define when variables are needed.It's similar to groups in a Gemfile:
# file: Envfilevariable:FORCE_SSL,:booleangroup:productiondovariable:SECRET_KEY_BASEendgroup:development,:stagingdovariable:DEV_KEYend
# For local development you would typically do:ENVied.require(:default)#=> Only ENV['FORCE_SSL'] is required# On the production server:ENVied.require(:default,:production)#=> ...also ENV['SECRET_KEY_BASE'] is required# You can also pass it a string with the groups separated by comma's:ENVied.require('default, production')# This allows for easily requiring groups using the ENV:ENVied.require(ENV['ENVIED_GROUPS'])# ...then from the prompt:$ENVIED_GROUPS='default,production'bin/railsserver# BTW the following are equivalent:ENVied.requireENVied.require(:default)ENVied.require('default')ENVied.require(nil)
For help on a specific command, useenvied help <command>
.
$ enviedhelpCommands: envied check# Checks whether you environment contains required variables envied check:heroku# Checks whether a Heroku config contains required variables envied check:heroku:binstub# Generates a shell script for the check:heroku-task envied extract# Grep code to find ENV-variables enviedhelp [COMMAND]# Describe available commands or one specific command envied init# Generates a default Envfile in the current working directory envied init:rails# Generate all files needed for a Rails project envied version, --version, -v# Shows version number
Some best practices when using ENVied or working with env-configurable applications in general.
While ENVied will warn you when you start an application that is 'under-configured', it won't tell users what good default values are. To solve this add a file to the root of your project that contains sane defaults and instructions:
# file: .envrc.sample# copy this file to .envrc and adjust values if needed# then do `source .envrc` to loadexport DATABASE_URL=postgres://localhost/blog_development# export FORCE_SSL=true # only needed for production# you can find this token on the Heroku-dashboardexport DEPLOY_TOKEN=1234-ABC-5678
letdirenv manage your environment
direnv will auto-(un)load values from.envrc
when you switch folders.
As a bonus it has some powerful commands in it'sstdlib.
For example:
# this adds the project's bin-folder to $PATHPATH_add bin# so instead of `./bin/rails -h` you can do `rails -h` from anywhere (deep) in the project# the following will use the .envrc.sample as a basis# when new variables are introduced upstream, you'll automatically use these defaultsif [ -f .envrc.sample ]; then source_env .envrc.samplefi...your overrides# a variant of this is source_up# an .envrc in a subfolder can load the .envrc from the root of the project and override specific values# this would allow e.g. for a specific test-environment in the subfolder:# in my-project/test/.envrcsource_up .envrcexport DATABASE_URL=the-test-db-url
$ bundle exec envied extract
This comes in handy when you're not using ENVied yet. It will find allENV['KEY']
andENV.fetch('KEY')
statements in your project.
It assumes a standard project layout (see the default value for the globs-option).
The easiest/quickest is to run:
$ heroku config --json | bundle exec envied check:heroku
This is equivalent to having the heroku config as your local environment and runningenvied check:heroku --groups default production
.
You want to run this right before a deploy to Heroku. This prevents that your app will crash during bootup because ENV-variables are missing from heroku config.
You can turn the above into a handy binstub like so:
$ bundle exec envied check:heroku:binstub# created bin/heroku-env-check
This way you can do stuff like:
$ ./bin/heroku-env-check && git push live master
The short version: simplicity, i.e. the best tool for the job.
In the early days of ENVied it was possible to provide default values for a variable.
While convenient, it had several drawbacks:
- it would introduce a value for ENVied.FOO, while ENV['FOO'] was nil: confusing and a potential source of bugs.
- it hides the fact that an application can actually be configged via the environment.
- it creates an in-process environment which is hard to inspect (as opposed to doing
printenv FOO
in a shell, after or before starting the application). - there are better ways: e.g. a sample file in a project with a bunch of exports (ie
export FOO=sane-default # and even some documentation
) that someone can source in their shell (seeBest Practices). - made the code quite complex.
As an alternative include a file.envrc.sample
in the root of your project containing default values (ieexport FOO=bar
) that users can source in their shell. See alsoBest Practices.
$ ./bin/setup# run tests$ ./bin/rspec# hack with pry$ ./bin/console# run CLI:$ ./bin/envied
There's a.envrc.sample
included that can be used in combination withdirenv.
To suggest a new feature,open an Issue before opening a PR.
- Fork it:https://gitlab.com/envied/envied/-/forks/new
- Create your feature branch:
git checkout -b my-new-feature
- Commit your changes:
git commit -am 'Add some feature'
- Push to the branch:
git push origin my-new-feature
- Create a new pull request for your feature branch
About
Ensures presence and type of your app's ENV-variables (mirror)
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors11
Uh oh!
There was an error while loading.Please reload this page.