envied 0.9.3 → 0.10.0.alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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