envied 0.9.3 → 0.10.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dcc781ac6f01f4925045b61ca88d14b41dbccebe46dc34582a391c884bb99e4a
4
- data.tar.gz: 542a7c711445013a845478f716cddf7ac82b7834365429ebf24ed36b08462ca2
3
+ metadata.gz: 995cd4c0c3790b6eabd16fe27f110ddde99d9efcd52863bc0fdfec9fc7d9ac7f
4
+ data.tar.gz: 2ae7aebddb419a142c77d2ff3ac878ee22428356ed1d26d1b7b0396741760c14
5
5
  SHA512:
6
- metadata.gz: 2c976e128a2c3c8ab59c31fbec653aa7fe3b8d01973e92e4da220deff09cdee826c34627ca873d4eb612292f175419914c4235932002422cab3454f72b3da2d8
7
- data.tar.gz: f37e48c5f981902d2db3e46dfa2a6101998ef11987e48e59ac9fc8e951d5b48d4e1cc6da756ff9b1860bb01e2abf6c72d0f1563a453f3e412754c2f0b8cfcbbb
6
+ metadata.gz: cc80db096389ad6e7f0d66d615a7697d85a550e10307314ebf98d14cb01172f31a2e29684eb47da2c5693c68e0266fd84cbcc44b1345567e81086fe4ffb690d4
7
+ data.tar.gz: '08d2dc26b39cc8bd52ed5b40293dff4df06301f645ee5d3d56e52f10c9b6176c9792b2e48a0fc7a0b5358a2805a0a5319555f969ea27913ebcfd02489a10552b'
@@ -0,0 +1,9 @@
1
+ # Copy this file to .envrc, adjust values if needed and
2
+ # `source .envrc` to apply it.
3
+ # Or use [direnv](https://direnv.net/) to auto-(un)load it.
4
+
5
+ # using direnv
6
+ # PATH_add bin
7
+
8
+ # without direnv
9
+ # export PATH="$(pwd)/bin:${PATH}"
@@ -0,0 +1,2 @@
1
+ *NOTE* the canonical repository for this project can be found at **https://gitlab.com/envied/envied**.
2
+ Please open issues and send patches there.
data/.gitignore CHANGED
@@ -12,3 +12,4 @@
12
12
  .rspec_status
13
13
 
14
14
  Gemfile.lock
15
+ .envrc
@@ -8,7 +8,7 @@
8
8
  - 'git -v || apk --update add git'
9
9
  - bundle install -j $(nproc)
10
10
  script:
11
- - bundle exec rake
11
+ - ./bin/rspec
12
12
 
13
13
  rspec ruby-2.4:
14
14
  image: ruby:2.4-alpine
@@ -30,7 +30,7 @@ rspec jruby-9.2:
30
30
  image: jruby:9.2-alpine
31
31
  <<: *rspec
32
32
  only:
33
- - 0-9-releases
33
+ - master
34
34
 
35
35
  release:
36
36
  stage: deploy
@@ -46,4 +46,5 @@ release:
46
46
  - chmod 600 ~/.gem/credentials
47
47
  - bundle exec rake release
48
48
  only:
49
- - tags
49
+ - tags
50
+ environment: production
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --color
2
2
  --require spec_helper
3
+ --format documentation
@@ -1,4 +1,16 @@
1
- ## 0.9.2 / 2019-06-29
1
+ ## master / unreleased
2
+
3
+ ### Added
4
+
5
+ * key alias
6
+
7
+ # file: Envfile
8
+ key_alias! { Rails.env }
9
+ variable :FOO
10
+
11
+ The value of ENV['FOO_DEVELOPMENT'] will take precedence over ENV['FOO'] when running in development.
12
+
13
+ ## 0.9.3 / 2019-06-29
2
14
 
3
15
  * Project moved to GitLab (https://gitlab.com/envied/envied)
4
16
  * Now requiring Ruby 2.4+ [#48], [#51]
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014 Gert Goet
1
+ Copyright (c) 2014-2019 Gert Goet, ThinkCreate
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,28 +1,35 @@
1
- # 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/)
1
+ # 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/)
2
+
3
+ _Canonical Repository:_ https://gitlab.com/envied/envied/tree/master#envied
2
4
 
3
5
  ### TL;DR ensure presence and type of your app's ENV-variables.
4
6
 
5
- 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).
7
+ 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).
6
8
 
7
- ## Features:
9
+ ## Features
8
10
 
9
11
  * check for presence and correctness of ENV-variables
10
12
  * access to typed ENV-variables (integers, booleans etc. instead of just strings)
11
13
  * check the presence and correctness of a Heroku config
12
14
 
15
+ ## Non-features
16
+
17
+ * provide or load ENV-values
18
+
13
19
  ## Contents
14
20
 
15
21
  * [Quickstart](#quickstart)
16
22
  * [Installation](#installation)
17
23
  * [Configuration](#configuration)
18
24
  * [Types](#types)
25
+ * [Key alias](#key-alias-unreleased)
26
+ * [env-type](#env-type-unreleased)
19
27
  * [Groups](#groups)
20
- * [Defaults](#defaults)
21
- * [More examples](#more-examples)
22
28
  * [Command-line interface](#command-line-interface)
23
- * [How do I...?](#how-do-i)
29
+ * [Best Practices](#best-practices)
30
+ * [FAQ](#faq)
24
31
  * [Testing](#testing)
25
- * [Developing](#developing)
32
+ * [Development](#development)
26
33
  * [Contributing](#contributing)
27
34
 
28
35
  ## Quickstart
@@ -45,8 +52,8 @@ ENVied.require
45
52
  ```
46
53
 
47
54
  This will throw an error if:
48
- * both `ENV['FORCE_SSL']` and `ENV['PORT']` are *not present*.
49
- * the values *cannot* be coerced to a boolean and integer.
55
+ * one of `ENV['FORCE_SSL']`, `ENV['PORT']` is absent.
56
+ * or: their values *cannot* be coerced (resp. to boolean and integer).
50
57
 
51
58
  ### 3) Use coerced variables
52
59
 
@@ -81,17 +88,74 @@ Add this line to your application's Gemfile:
81
88
 
82
89
  The following types are supported:
83
90
 
84
- * `:string` (implied)
91
+ * `:array` (e.g. 'tag1,tag2' becomes `['tag1', 'tag2']`)
85
92
  * `:boolean` (e.g. '0'/'1', 'f'/'t', 'false'/'true', 'off'/'on', 'no'/'yes' for resp. false and true)
86
- * `:integer`
93
+ * `:date` (e.g. '2014-3-26')
94
+ * `:env` (similar to `:string`, but accessible via ENV - see [Key alias](#key-alias-unreleased) for details)
87
95
  * `:float`
96
+ * `:hash` (e.g. 'a=1&b=2' becomes `{'a' => '1', 'b' => '2'}`)
97
+ * `:integer`
98
+ * `:string` (implied)
88
99
  * `:symbol`
89
- * `:date` (e.g. '2014-3-26')
90
100
  * `:time` (e.g. '14:00')
91
- * `:hash` (e.g. 'a=1&b=2' becomes `{'a' => '1', 'b' => '2'}`)
92
- * `:array` (e.g. 'tag1,tag2' becomes `['tag1', 'tag2']`)
93
101
  * `:uri` (e.g. 'http://www.google.com' becomes result of `URI.parse('http://www.google.com')`)
94
102
 
103
+
104
+ ### Key alias (unreleased)
105
+
106
+ 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.
107
+
108
+ 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.
109
+
110
+ 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.
111
+
112
+ Full example:
113
+ ```
114
+ # file: Envfile
115
+ key_alias! { Rails.env }
116
+
117
+ variable :REDIS_URL, :uri
118
+ ```
119
+
120
+ Source the following in your environment:
121
+ ```
122
+ # file: .envrc
123
+ export REDIS_URL_DEVELOPMENT=redis://localhost:6379/0
124
+ export REDIS_URL_TEST=redis://localhost:6379/1
125
+ ```
126
+ Now commands like `rails console` and `rails test` automatically point to the right redis database.
127
+
128
+ Note that `ENV['REDIS_URL']` is still considered but `REDIS_URL_<key_alias>` takes precedence.
129
+ Also: any truthy value provided as key_alias is converted to an upcased string.
130
+ Finally: this setting is optional.
131
+
132
+
133
+ #### env-type (unreleased)
134
+
135
+ Variables of type `:env` take the key alias into account when accessing `ENV['FOO']`.
136
+
137
+ 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:
138
+
139
+ ```
140
+ # file: Envfile
141
+
142
+ key_alias! { Rails.env }
143
+
144
+ variable :DATABASE_URL, :env
145
+ ```
146
+
147
+ The following now works:
148
+ ```shell
149
+ $ DATABASE_URL_DEVELOPMENT=postgres://localhost/blog_development rails runner "p ENV['DATABASE_URL']"
150
+ "postgres://localhost/blog_development"
151
+ ```
152
+
153
+ Note: this also works for `ENV.fetch('FOO')`.
154
+ Also: no coercion is done (like you would expect when accessing ENV-values directly).
155
+
156
+ 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`.
157
+
158
+
95
159
  ### Groups
96
160
 
97
161
  Groups give you more flexibility to define when variables are needed.
@@ -99,7 +163,7 @@ It's similar to groups in a Gemfile:
99
163
 
100
164
  ```ruby
101
165
  # file: Envfile
102
- variable :FORCE_SSL, :boolean, default: 'false'
166
+ variable :FORCE_SSL, :boolean
103
167
 
104
168
  group :production do
105
169
  variable :SECRET_KEY_BASE
@@ -131,35 +195,6 @@ ENVied.require('default')
131
195
  ENVied.require(nil)
132
196
  ```
133
197
 
134
- ### Defaults
135
-
136
- > *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.
137
- > 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'`.
138
-
139
- In order to let other developers easily bootstrap the application, you can assign defaults to variables.
140
- Defaults can be a value or a `Proc` (see example below).
141
-
142
- 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:
143
-
144
- ```ruby
145
- # Envfile
146
- enable_defaults! { ENV['RACK_ENV'] == 'development' }
147
-
148
- variable :FORCE_SSL, :boolean, default: 'false'
149
- variable :PORT, :integer, default: proc {|envied| envied.FORCE_SSL ? 443 : 80 }
150
- ```
151
-
152
- Please remember that ENVied only **reads** from ENV; it doesn't mutate ENV.
153
- Don't let setting a default for, say `RAILS_ENV`, give you the impression that `ENV['RAILS_ENV']` is set.
154
- As a rule of thumb you should only use defaults:
155
- * for local development
156
- * for ENV-variables that are solely used by your application (i.e. for `ENV['STAFF_EMAILS']`, not for `ENV['RAILS_ENV']`)
157
-
158
- ### More examples
159
-
160
- * See the [examples](/examples)-folder for a more extensive Envfile
161
- * See [the Envfile](https://github.com/eval/bunny_drain/blob/c54d7d977afb5e23a92da7a2fd0d39f6a7e29bf1/Envfile) for the bunny_drain application
162
-
163
198
  ## Command-line interface
164
199
 
165
200
  For help on a specific command, use `envied help <command>`.
@@ -177,9 +212,55 @@ Commands:
177
212
  envied version, --version, -v # Shows version number
178
213
  ```
179
214
 
180
- ## How do I
215
+ ## Best Practices
216
+
217
+ Some best practices when using ENVied or working with env-configurable applications in general.
218
+
219
+ ### include a .envrc.sample
220
+
221
+ 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:
222
+ ```
223
+ # file: .envrc.sample
224
+ # copy this file to .envrc and adjust values if needed
225
+ # then do `source .envrc` to load
226
+
227
+ export DATABASE_URL=postgres://localhost/blog_development
228
+ # export FORCE_SSL=true # only needed for production
229
+
230
+ # you can find this token on the Heroku-dashboard
231
+ export DEPLOY_TOKEN=1234-ABC-5678
232
+ ```
233
+
234
+ ### let [direnv](https://direnv.net/) manage your environment
235
+
236
+ [direnv](https://direnv.net/) will auto-(un)load values from `.envrc` when you switch folders.
237
+
238
+ As a bonus it has some powerful commands in it's [stdlib](https://direnv.net/#man/direnv-stdlib.1).
239
+ For example:
240
+ ```
241
+ # this adds the project's bin-folder to $PATH
242
+ PATH_add bin
243
+ # so instead of `./bin/rails -h` you can do `rails -h` from anywhere (deep) in the project
244
+
245
+ # the following will use the .envrc.sample as a basis
246
+ # when new variables are introduced upstream, you'll automatically use these defaults
247
+ if [ -f .envrc.sample ]; then
248
+ source_env .envrc.sample
249
+ fi
250
+ ...your overrides
251
+
252
+ # a variant of this is source_up
253
+ # an .envrc in a subfolder can load the .envrc from the root of the project and override specific values
254
+ # this would allow e.g. for a specific test-environment in the subfolder:
255
+ # in my-project/test/.envrc
256
+ source_up .envrc
257
+ export DATABASE_URL=the-test-db-url
258
+ ```
259
+
260
+
261
+ ## FAQ
181
262
 
182
- ### ...find all ENV-variables my app is currently using?
263
+ ### How to find all ENV-variables my app is currently using?
183
264
 
184
265
  ```
185
266
  $ bundle exec envied extract
@@ -189,7 +270,7 @@ This comes in handy when you're not using ENVied yet. It will find all `ENV['KEY
189
270
 
190
271
  It assumes a standard project layout (see the default value for the globs-option).
191
272
 
192
- ### ...check the config of a Heroku app?
273
+ ### How to check the config of a Heroku app?
193
274
 
194
275
  The easiest/quickest is to run:
195
276
 
@@ -212,19 +293,38 @@ This way you can do stuff like:
212
293
  $ ./bin/heroku-env-check && git push live master
213
294
  ```
214
295
 
215
- ## Testing
296
+ ### What happened to default values??
297
+
298
+ The short version: simplicity, i.e. the best tool for the job.
299
+
300
+ In the early days of ENVied it was possible to provide default values for a variable.
301
+ While convenient, it had several drawbacks:
302
+ - it would introduce a value for ENVied.FOO, while ENV['FOO'] was nil: confusing and a potential source of bugs.
303
+ - it hides the fact that an application can actually be configged via the environment.
304
+ - 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).
305
+ - 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)).
306
+ - made the code quite complex.
307
+
308
+ 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).
216
309
 
217
- ```bash
218
- bundle install
219
- bundle exec rspec
220
- ```
221
310
 
222
- ## Developing
311
+ ## Development
223
312
 
224
313
  ```bash
225
- bin/console
314
+ $ ./bin/setup
315
+
316
+ # run tests
317
+ $ ./bin/rspec
318
+
319
+ # hack with pry
320
+ $ ./bin/console
321
+
322
+ # run CLI:
323
+ $ ./bin/envied
226
324
  ```
227
325
 
326
+ There's a `.envrc.sample` included that can be used in combination with [direnv](http://direnv.net/).
327
+
228
328
  ## Contributing
229
329
 
230
330
  To suggest a new feature, [open an Issue](https://gitlab.com/envied/envied/issues/new) before opening a PR.
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'bundle' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "rubygems"
12
+
13
+ m = Module.new do
14
+ module_function
15
+
16
+ def invoked_as_script?
17
+ File.expand_path($0) == File.expand_path(__FILE__)
18
+ end
19
+
20
+ def env_var_version
21
+ ENV["BUNDLER_VERSION"]
22
+ end
23
+
24
+ def cli_arg_version
25
+ return unless invoked_as_script? # don't want to hijack other binstubs
26
+ return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
27
+ bundler_version = nil
28
+ update_index = nil
29
+ ARGV.each_with_index do |a, i|
30
+ if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
31
+ bundler_version = a
32
+ end
33
+ next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
34
+ bundler_version = $1 || ">= 0.a"
35
+ update_index = i
36
+ end
37
+ bundler_version
38
+ end
39
+
40
+ def gemfile
41
+ gemfile = ENV["BUNDLE_GEMFILE"]
42
+ return gemfile if gemfile && !gemfile.empty?
43
+
44
+ File.expand_path("../../Gemfile", __FILE__)
45
+ end
46
+
47
+ def lockfile
48
+ lockfile =
49
+ case File.basename(gemfile)
50
+ when "gems.rb" then gemfile.sub(/\.rb$/, gemfile)
51
+ else "#{gemfile}.lock"
52
+ end
53
+ File.expand_path(lockfile)
54
+ end
55
+
56
+ def lockfile_version
57
+ return unless File.file?(lockfile)
58
+ lockfile_contents = File.read(lockfile)
59
+ return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
60
+ Regexp.last_match(1)
61
+ end
62
+
63
+ def bundler_version
64
+ @bundler_version ||= begin
65
+ env_var_version || cli_arg_version ||
66
+ lockfile_version || "#{Gem::Requirement.default}.a"
67
+ end
68
+ end
69
+
70
+ def load_bundler!
71
+ ENV["BUNDLE_GEMFILE"] ||= gemfile
72
+
73
+ # must dup string for RG < 1.8 compatibility
74
+ activate_bundler(bundler_version.dup)
75
+ end
76
+
77
+ def activate_bundler(bundler_version)
78
+ if Gem::Version.correct?(bundler_version) && Gem::Version.new(bundler_version).release < Gem::Version.new("2.0")
79
+ bundler_version = "< 2"
80
+ end
81
+ gem_error = activation_error_handling do
82
+ gem "bundler", bundler_version
83
+ end
84
+ return if gem_error.nil?
85
+ require_error = activation_error_handling do
86
+ require "bundler/version"
87
+ end
88
+ return if require_error.nil? && Gem::Requirement.new(bundler_version).satisfied_by?(Gem::Version.new(Bundler::VERSION))
89
+ warn "Activating bundler (#{bundler_version}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_version}'`"
90
+ exit 42
91
+ end
92
+
93
+ def activation_error_handling
94
+ yield
95
+ nil
96
+ rescue StandardError, LoadError => e
97
+ e
98
+ end
99
+ end
100
+
101
+ m.load_bundler!
102
+
103
+ if m.invoked_as_script?
104
+ load Gem.bin_path("bundler", "bundle")
105
+ end