README.md in envied-0.9.3 vs README.md in envied-0.10.0.alpha1
- old
+ new
@@ -1,30 +1,37 @@
-# ENVied [![pipeline status](https://gitlab.com/envied/envied/badges/0-9-releases/pipeline.svg)](https://gitlab.com/envied/envied/commits/0-9-releases) [![project chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://envied-rb.zulipchat.com/)
+# ENVied [![pipeline status](https://gitlab.com/envied/envied/badges/master/pipeline.svg)](https://gitlab.com/envied/envied/commits/master) [![project chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://envied-rb.zulipchat.com/)
+_Canonical Repository:_ https://gitlab.com/envied/envied/tree/master#envied
+
### TL;DR ensure presence and type of your app's ENV-variables.
-For the rationale behind this project, see this [blogpost](http://www.gertgoet.com/2014/10/14/envied-or-how-i-stopped-worrying-about-ruby-s-env.html).
+For the rationale behind this project, see this [blogpost](https://www.gertgoet.com/2014/10/14/envied-or-how-i-stopped-worrying-about-ruby-s-env.html).
-## Features:
+## Features
* 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
+## Non-features
+
+* provide or load ENV-values
+
## Contents
* [Quickstart](#quickstart)
* [Installation](#installation)
* [Configuration](#configuration)
* [Types](#types)
+ * [Key alias](#key-alias-unreleased)
+ * [env-type](#env-type-unreleased)
* [Groups](#groups)
- * [Defaults](#defaults)
- * [More examples](#more-examples)
* [Command-line interface](#command-line-interface)
-* [How do I...?](#how-do-i)
+* [Best Practices](#best-practices)
+* [FAQ](#faq)
* [Testing](#testing)
-* [Developing](#developing)
+* [Development](#development)
* [Contributing](#contributing)
## Quickstart
### 1) Configure
@@ -43,12 +50,12 @@
# during initialization
ENVied.require
```
This will throw an error if:
-* both `ENV['FORCE_SSL']` and `ENV['PORT']` are *not present*.
-* the values *cannot* be coerced to a boolean and integer.
+* one of `ENV['FORCE_SSL']`, `ENV['PORT']` is absent.
+* or: their values *cannot* be coerced (resp. to boolean and integer).
### 3) Use coerced variables
Variables accessed via ENVied are of the correct type:
@@ -79,29 +86,86 @@
### Types
The following types are supported:
-* `:string` (implied)
+* `: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)
-* `:integer`
+* `:date` (e.g. '2014-3-26')
+* `:env` (similar to `:string`, but accessible via ENV - see [Key alias](#key-alias-unreleased) for details)
* `:float`
+* `:hash` (e.g. 'a=1&b=2' becomes `{'a' => '1', 'b' => '2'}`)
+* `:integer`
+* `:string` (implied)
* `:symbol`
-* `:date` (e.g. '2014-3-26')
* `:time` (e.g. '14:00')
-* `:hash` (e.g. 'a=1&b=2' becomes `{'a' => '1', 'b' => '2'}`)
-* `:array` (e.g. 'tag1,tag2' becomes `['tag1', 'tag2']`)
* `:uri` (e.g. 'http://www.google.com' becomes result of `URI.parse('http://www.google.com')`)
+
+### Key alias (unreleased)
+
+By default the value for variable `FOO` should be provided by `ENV['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 where `REDIS_URL` differs between the development and test environment. Normally you'd prepare different shells with different values for `REDIS_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 both `REDIS_URL_TEST` and `REDIS_URL_DEVELOPMENT` and the right value will be used for test and development.
+
+Full example:
+```
+# file: Envfile
+key_alias! { Rails.env }
+
+variable :REDIS_URL, :uri
+```
+
+Source the following in your environment:
+```
+# file: .envrc
+export REDIS_URL_DEVELOPMENT=redis://localhost:6379/0
+export REDIS_URL_TEST=redis://localhost:6379/1
+```
+Now commands like `rails console` and `rails test` automatically point to the right redis database.
+
+Note that `ENV['REDIS_URL']` is still considered but `REDIS_URL_<key_alias>` takes precedence.
+Also: any truthy value provided as key_alias is converted to an upcased string.
+Finally: this setting is optional.
+
+
+#### env-type (unreleased)
+
+Variables of type `:env` take the key alias into account when accessing `ENV['FOO']`.
+
+Say, your application uses `ENV['DATABASE_URL']` (wich you can't change to `ENVied.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: Envfile
+
+key_alias! { Rails.env }
+
+variable :DATABASE_URL, :env
+```
+
+The following now works:
+```shell
+$ DATABASE_URL_DEVELOPMENT=postgres://localhost/blog_development rails runner "p ENV['DATABASE_URL']"
+"postgres://localhost/blog_development"
+```
+
+Note: this also works for `ENV.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 for `DATABASE_URL_DEVELOPMENT` and `DATABASE_URL_TEST`, you no longer need a `config/database.yml`.
+
+
### Groups
Groups give you more flexibility to define when variables are needed.
It's similar to groups in a Gemfile:
```ruby
# file: Envfile
-variable :FORCE_SSL, :boolean, default: 'false'
+variable :FORCE_SSL, :boolean
group :production do
variable :SECRET_KEY_BASE
end
@@ -129,39 +193,10 @@
ENVied.require(:default)
ENVied.require('default')
ENVied.require(nil)
```
-### Defaults
-
-> *NOTE*: default values will be removed in the next minor-release (i.e. > v0.9). See https://gitlab.com/envied/envied/tree/master#what-happened-to-default-values for more information and how to migrate.
-> While your project depends on this feature it's recommended to pin the gem to 0.9-releases, i.e. `gem 'envied', '~> 0.9.3'`.
-
-In order to let other developers easily bootstrap the application, you can assign defaults to variables.
-Defaults can be a value or a `Proc` (see example below).
-
-Note that 'easily bootstrap' is quite the opposite of 'fail-fast when not all ENV-variables are present'. Therefore you should explicitly state when defaults are allowed:
-
-```ruby
-# Envfile
-enable_defaults! { ENV['RACK_ENV'] == 'development' }
-
-variable :FORCE_SSL, :boolean, default: 'false'
-variable :PORT, :integer, default: proc {|envied| envied.FORCE_SSL ? 443 : 80 }
-```
-
-Please remember that ENVied only **reads** from ENV; it doesn't mutate ENV.
-Don't let setting a default for, say `RAILS_ENV`, give you the impression that `ENV['RAILS_ENV']` is set.
-As a rule of thumb you should only use defaults:
-* for local development
-* for ENV-variables that are solely used by your application (i.e. for `ENV['STAFF_EMAILS']`, not for `ENV['RAILS_ENV']`)
-
-### More examples
-
-* See the [examples](/examples)-folder for a more extensive Envfile
-* See [the Envfile](https://github.com/eval/bunny_drain/blob/c54d7d977afb5e23a92da7a2fd0d39f6a7e29bf1/Envfile) for the bunny_drain application
-
## Command-line interface
For help on a specific command, use `envied help <command>`.
```bash
@@ -175,23 +210,69 @@
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
```
-## How do I
+## Best Practices
-### ...find all ENV-variables my app is currently using?
+Some best practices when using ENVied or working with env-configurable applications in general.
+### include a .envrc.sample
+
+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 load
+
+export DATABASE_URL=postgres://localhost/blog_development
+# export FORCE_SSL=true # only needed for production
+
+# you can find this token on the Heroku-dashboard
+export DEPLOY_TOKEN=1234-ABC-5678
+```
+
+### let [direnv](https://direnv.net/) manage your environment
+
+[direnv](https://direnv.net/) will auto-(un)load values from `.envrc` when you switch folders.
+
+As a bonus it has some powerful commands in it's [stdlib](https://direnv.net/#man/direnv-stdlib.1).
+For example:
+```
+# this adds the project's bin-folder to $PATH
+PATH_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 defaults
+if [ -f .envrc.sample ]; then
+ source_env .envrc.sample
+fi
+...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/.envrc
+source_up .envrc
+export DATABASE_URL=the-test-db-url
+```
+
+
+## FAQ
+
+### How to find all ENV-variables my app is currently using?
+
+```
$ bundle exec envied extract
```
This comes in handy when you're not using ENVied yet. It will find all `ENV['KEY']` and `ENV.fetch('KEY')` statements in your project.
It assumes a standard project layout (see the default value for the globs-option).
-### ...check the config of a Heroku app?
+### How to check the config of a Heroku app?
The easiest/quickest is to run:
```
$ heroku config --json | bundle exec envied check:heroku
@@ -210,21 +291,40 @@
This way you can do stuff like:
```
$ ./bin/heroku-env-check && git push live master
```
-## Testing
+### What happened to default values??
-```bash
-bundle install
-bundle exec rspec
-```
+The short version: simplicity, i.e. the best tool for the job.
-## Developing
+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 (see [Best Practices](#best-practices)).
+- made the code quite complex.
+As an alternative include a file `.envrc.sample` in the root of your project containing default values (ie `export FOO=bar`) that users can source in their shell. See also [Best Practices](#best-practices).
+
+
+## Development
+
```bash
-bin/console
+$ ./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 with [direnv](http://direnv.net/).
## Contributing
To suggest a new feature, [open an Issue](https://gitlab.com/envied/envied/issues/new) before opening a PR.