README.md in envied-0.10.0.alpha3 vs README.md in envied-0.10.0
- old
+ new
@@ -1,38 +1,29 @@
-# 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/)
+# ENVied [![Tests](https://github.com/javierjulio/envied/actions/workflows/tests.yml/badge.svg)](https://github.com/javierjulio/envied/actions/workflows/tests.yml)
-_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](https://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](http://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)
-* [Best Practices](#best-practices)
-* [FAQ](#faq)
-* [Testing](#testing)
+* [How do I...?](#how-do-i)
* [Development](#development)
-* [Contributing](#contributing)
## Quickstart
### 1) Configure
@@ -45,17 +36,17 @@
```
### 2) Check for presence and coercibility
```ruby
-# during initialization
+# during initialization and in a pre-deploy confirmation workflow
ENVied.require
```
This will throw an error if:
-* one of `ENV['FORCE_SSL']`, `ENV['PORT']` is absent.
-* or: their values *cannot* be coerced (resp. to boolean and integer).
+* both `ENV['FORCE_SSL']` and `ENV['PORT']` are *not present*.
+* the values *cannot* be coerced to a boolean and integer.
### 3) Use coerced variables
Variables accessed via ENVied are of the correct type:
@@ -64,108 +55,79 @@
ENVied.FORCE_SSL # => false
```
## Installation
-Add this line to your application's Gemfile:
+Add `envied` to your `Gemfile`:
- gem 'envied'
+```ruby
+gem 'envied'
+```
-...then bundle:
+If you are using Rails, add this to `config/application.rb` immediately after `Bundler.require(*Rails.groups)`:
- $ bundle
-
-...then for Rails applications:
-
- $ bundle exec envied init:rails
-
-...or for non-Rails applications:
-
- $ bundle exec envied init
-
-## Configuration
-
-### Types
-
-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 - 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`
-* `:time` (e.g. '14:00')
-* `: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:
+```ruby
+ENVied.require(*ENV['ENVIED_GROUPS'] || Rails.groups)
```
-# file: Envfile
-key_alias! { Rails.env }
-variable :REDIS_URL, :uri
-```
+If you are not using Rails, add the following snippet (or similar) to your app's initialization:
-Source the following in your environment:
+```ruby
+ENVied.require(*ENV['ENVIED_GROUPS'] || [:default, ENV['RACK_ENV']])
```
-# 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.
+Create an `Envfile` with the following as a starter:
+```ruby
+enable_defaults! { ENV['RACK_ENV'] != 'production' }
-#### env-type (unreleased)
+variable :LOG_LEVEL, :string, default: 'debug'
-Variables of type `:env` take the key alias into account when accessing `ENV['FOO']`.
+group :production do
+ variable :SECRET_KEY_BASE
+end
+```
-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:
+Refer to the [Types](#types) section to start configuring your project's environment variables.
-```
-# file: Envfile
+### Pre-deploy ENV check
-key_alias! { Rails.env }
+To confirm that your ENV variables are set in a pre-deploy workflow, provide the application's current ENV to a Ruby script that loads it and runs the envied check.
-variable :DATABASE_URL, :env
+```ruby
+ENV.replace(your_current_env)
+ENVied.require(*RAILS_GROUPS)
+puts "All required ENV variables are present and valid."
```
-The following now works:
-```shell
-$ DATABASE_URL_DEVELOPMENT=postgres://localhost/blog_development rails runner "p ENV['DATABASE_URL']"
-"postgres://localhost/blog_development"
-```
+If any required ENV are missing, then the check will fail with an error message listing the missing environment variable names.
-Note: this also works for `ENV.fetch('FOO')`.
-Also: no coercion is done (like you would expect when accessing ENV-values directly).
+## Configuration
-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`.
+### Types
+The following types are supported:
+* `:string` (implied)
+* `:boolean` (e.g. '0'/'1', 'f'/'t', 'false'/'true', 'off'/'on', 'no'/'yes' for resp. false and true)
+* `:integer`
+* `:float`
+* `: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')`)
+
### 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
+variable :FORCE_SSL, :boolean, default: 'false'
group :production do
variable :SECRET_KEY_BASE
end
@@ -193,10 +155,36 @@
ENVied.require(:default)
ENVied.require('default')
ENVied.require(nil)
```
+### Defaults
+
+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
@@ -210,69 +198,23 @@
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
```
-## Best Practices
+## How do I
-Some best practices when using ENVied or working with env-configurable applications in general.
+### ...find all ENV-variables my app is currently using?
-### 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).
-### How to check the config of a Heroku app?
+### ...check the config of a Heroku app?
The easiest/quickest is to run:
```
$ heroku config --json | bundle exec envied check:heroku
@@ -291,46 +233,10 @@
This way you can do stuff like:
```
$ ./bin/heroku-env-check && git push live master
```
-### What happened to default values??
-
-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 (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/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.
-
-1. Fork it: https://gitlab.com/envied/envied/-/forks/new
-2. Create your feature branch: `git checkout -b my-new-feature`
-3. Commit your changes: `git commit -am 'Add some feature'`
-4. Push to the branch: `git push origin my-new-feature`
-5. Create a new pull request for your feature branch
+- `bin/setup`
+- Run tests: `RUBYOPT="-W:deprecated" bundle exec rspec`
+- For an interactive console: `bin/console`