chamber 0.0.4 → 1.0.0

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
  SHA1:
3
- metadata.gz: bdabeaa7f46f79f6e320ab4124bf84c971e83533
4
- data.tar.gz: 83de25cdc6048fdc681b0a69ed10a7b312a96637
3
+ metadata.gz: 5c054c5c22c6b6273bd39adecb26c84209e21930
4
+ data.tar.gz: dee881699926bd8f73055cdfb87c23bb9a439bb4
5
5
  SHA512:
6
- metadata.gz: 3cbf0a8825b0a40e6743effce5322db8ae5842e74c7454e39de340d8dad07338ce6970b3b07e0ef4b313aa97585da4ce1b2ee6cc5315a02293433d7ff76c0530
7
- data.tar.gz: 64998ca0ddad139b1a9127be272da8beb09f53726c902858c822ea15f50345ba9dafe19d701703bbedf1fc2fffb1263c76732879ddf32206b3f6e00cc8d08594
6
+ metadata.gz: abf527a63562fcc4a0b048a6de5a33ed1b240eb3c0bf2e140289c35ef0cee4264de48ce4199260ca1dbf56e1049b7202f5435bfbb888d0290c37475bad3bbace
7
+ data.tar.gz: f92834cf8cb8b504ca6d38c10558560851ed2dd36f09480ec64c41e8f97a685cf6851e4ae3f17dd8f9a716e32495f224c7a7cfb7a84ed104bc7f7549e36ce121
File without changes
data/README.md CHANGED
@@ -1,223 +1,814 @@
1
- # Chamber [![Build Status](https://travis-ci.org/stevenhallen/chamber.png)](https://travis-ci.org/stevenhallen/chamber)
1
+ # Chamber [![Build Status](https://travis-ci.org/m5rk/chamber.png)](https://travis-ci.org/m5rk/chamber) [![Code Climate](https://codeclimate.com/github/m5rk/chamber.png)](https://codeclimate.com/github/m5rk/chamber)
2
2
 
3
- Chamber lets you source your Settings from an arbitrary number of YAML files and
4
- provides a simple mechanism for overriding settings from the ENV, which is
5
- friendly to how Heroku addons work.
3
+ Chamber lets you source your settings from an arbitrary number of YAML files that
4
+ values convention over configuration and has an automatic mechanism for working
5
+ with Heroku's (or anyone else's) ENV variables.
6
6
 
7
7
  ## Installation
8
8
 
9
9
  Add this line to your application's Gemfile:
10
10
 
11
- gem 'chamber'
11
+ ```ruby
12
+ gem 'chamber'
13
+ ```
12
14
 
13
15
  And then execute:
14
16
 
15
- $ bundle
17
+ ```sh
18
+ $ bundle
19
+ ```
16
20
 
17
21
  Or install it yourself as:
18
22
 
19
- $ gem install chamber
23
+ ```sh
24
+ $ gem install chamber
25
+ ```
26
+
27
+ ## Basic Usage
20
28
 
21
- ## Usage
29
+ ### Convention Over Configuration
22
30
 
23
- The following instructions are for a Rails app hosted on heroku with both
24
- staging and production heroku environments.
31
+ By default Chamber only needs a base path to look for settings files. From
32
+ that path it will search for:
25
33
 
26
- Create a Settings class that extends Chamber in `app/models/settings.rb`:
34
+ * The file `<basepath>/credentials.yml`
35
+ * The file `<basepath>/settings.yml`
36
+ * A set of files ending in `.yml` in the `<basepath>/settings` directory
37
+
38
+ ### In Plain Old Ruby
27
39
 
28
40
  ```ruby
29
- class Settings
30
- extend Chamber
31
- end
41
+ Chamber.load basepath: '/path/to/my/application'
32
42
  ```
33
43
 
34
- Create a `config/settings.yml` that has this structure:
44
+ ### In Rails
35
45
 
36
- ```yml
37
- development:
38
- some_setting: value for dev
39
- some_password:
40
- environment: ENV_VAR_NAME
41
- test:
42
- some_setting: value for test
43
- some_password:
44
- environment: ENV_VAR_NAME
45
- staging:
46
- some_setting: value for staging
47
- some_password:
48
- environment: ENV_VAR_NAME
49
- production:
50
- some_setting: value for production
51
- some_password:
52
- environment: ENV_VAR_NAME
46
+ If you're running a Rails app, by default Chamber will set the basepath to your
47
+ Rails app's `config` directory, which is the equivalent of:
48
+
49
+ ```ruby
50
+ Chamber.load basepath: Rails.root.join('config')
51
+ ```
52
+
53
+ ### Accessing Settings
54
+
55
+ The YAML data will be loaded and you will have access to the settings
56
+ through the `Chamber` class.
57
+
58
+ **Example:**
59
+
60
+ Given a `settings.yml` file containing:
61
+
62
+ ```yaml
63
+ smtp:
64
+ server: "example.com"
65
+ username: "my_user"
66
+ password: "my_pass"
53
67
  ```
54
68
 
55
- Call `source` in your Settings class:
69
+ can be accessed as follows:
56
70
 
57
71
  ```ruby
58
- class Settings
59
- extend Chamber
72
+ Chamber[:smtp][:server]
73
+ # => example.com
74
+ ```
60
75
 
61
- source Rails.root.join('config', 'settings.yml'), namespace: Rails.env, override_from_environment: true
62
- end
76
+ or via object notation syntax:
77
+
78
+ ```ruby
79
+ Chamber.env.smtp.server
80
+ # => example.com
63
81
  ```
64
82
 
65
- Add environment-specific files for development and test to supply the values for
66
- those environments. Make sure to add these to .gitignore.
83
+ ### Keeping Your Settings Files Secure
84
+
85
+ Check out [Keeping Private Settings Private](#keeping-private-settings-private)
86
+ below.
87
+
88
+ ### Existing Environment Variables (aka Heroku)
89
+
90
+ If deploying to a system which has all of your environment variables already
91
+ set, you're not going to use all of the values stored in the YAML files.
92
+ Instead, you're going to want to pull certain values from environment variables.
67
93
 
68
- Add another call to `source` for these files:
94
+ **Example:**
95
+
96
+ Given a `settings.yml` file containing:
97
+
98
+ ```yaml
99
+ smtp:
100
+ server: "example.com"
101
+ username: "my_user"
102
+ password: "my_pass"
103
+ ```
104
+
105
+ If an environment variable is already set like so:
106
+
107
+ ```sh
108
+ export SMTP_SERVER="myotherserverisapentium.com"
109
+ ```
110
+
111
+ Then when you ask Chamber to give you the SMTP server:
69
112
 
70
113
  ```ruby
71
- class Settings
72
- extend Chamber
114
+ Chamber[:smtp][:server]
115
+ # => "myotherserverisapentium.com"
116
+ ```
73
117
 
74
- source Rails.root.join('config', 'settings.yml'), namespace: Rails.env, override_from_environment: true
75
- source Rails.root.join('config', "credentials-#{Rails.env}.yml")
118
+ It will return not what is in the YAML file, but what is in the environment
119
+ variable.
76
120
 
77
- load!
78
- end
121
+ ## Deploying to Heroku
122
+
123
+ If you're deploying to Heroku, they won't let you upload custom config files. If
124
+ you do not have your config files all stored in your repo (which you shouldn't
125
+ if some of the information is sensitive), it becomes more difficult to gain
126
+ access to that information on Heroku.
127
+
128
+ To solve this problem, Heroku allows you to set environment variables in your
129
+ application. Unfortunately this has the nasty side effect of being a pain to
130
+ deal with. For one, you have to deal with environment variables with unweildy
131
+ names. For another, it makes the organization of those variables difficult.
132
+
133
+ Fortunately, Chamber allows you to organize your environment variables in
134
+ separate files and access them easily using hash or object notation, however at
135
+ the same time, it provides a convenient way to push all of those sensitive
136
+ configuration settings up to Heroku as environment variables.
137
+
138
+ When Chamber accesses those same hash/object notated config values, it will
139
+ first look to see if an associated environment variable exists. If it does, it
140
+ will use that in place of any values inside of the config files.
141
+
142
+ Simply run:
143
+
144
+ ```sh
145
+ # In the root folder of your Rails app:
146
+
147
+ chamber heroku push --preset=rails
148
+
149
+ # In the root folder of another type of application:
150
+
151
+ chamber heroku push --basepath=./
152
+ ```
153
+
154
+ And all of your settings will be converted to environment variable versions
155
+ and set on your Heroku app.
156
+
157
+ _**Note:** For the full set of options, see [The chamber Command Line
158
+ App](#the-chamber-command-line-app) below._
159
+
160
+ ## Deploying to Travis CI
161
+
162
+ When deploying to Travis CI, it has similar environment variable requirements as
163
+ Heroku, however Travis allows the encryption of environment variables before
164
+ they are stored in the .travis.yml file. This allows for that file to be
165
+ checked into git without worrying about prying eyes figuring out your secret
166
+ information.
167
+
168
+ To execute this, simply run:
169
+
170
+ ```sh
171
+ chamber travis secure --basepath=./
79
172
  ```
80
173
 
81
- Finally, after all your `source` calls, you must call `load!`:
174
+ This will add `secure` entries into your `.travis.yml` file. Each one will
175
+ contain one environment variable.
176
+
177
+ _**Warning:** Each time you execute this command it will delete all secure
178
+ entries under 'env.global' in your `.travis.yml` file._
179
+
180
+ _**Note:** For the full set of options, see [The chamber Command Line
181
+ App](#the-chamber-command-line-app) below._
182
+
183
+ ## Advanced Usage
184
+
185
+ ### Explicitly Specifying Settings Files
186
+
187
+ Using convention over configuration, Chamber handles the 90% case by default,
188
+ however there may be times at which you would like to explicitly specify which
189
+ settings files are loaded. In these cases, Chamber has you covered:
82
190
 
83
191
  ```ruby
84
- class Settings
85
- extend Chamber
192
+ Chamber.load files: [
193
+ '/path/to/my/application/chamber/credentials.yml',
194
+ '/path/to/my/application/application*.yml',
195
+ '/path/to/my/application/chamber/*.yml',
196
+ ]
197
+ ```
86
198
 
87
- source Rails.root.join('config', 'settings.yml'), namespace: Rails.env, override_from_environment: true
88
- source Rails.root.join('config', "credentials-#{Rails.env}.yml")
199
+ In this case, Chamber will load *only* the `credentials.yml` file *without ever*
200
+ looking for a namespaced file. Then it will load `application.yml` *and* any
201
+ associated namespaced files. Finally it will load all \*.yml files in the
202
+ `chamber` directory *except* `credentials.yml` because it has previously been
203
+ loaded.
89
204
 
90
- load!
91
- end
205
+ ### Object-Based Environment Variable Access
206
+
207
+ If you aren't a fan of the hash-based access, you can also access them
208
+ using methods:
209
+
210
+ ```ruby
211
+ Chamber.env.smtp.server
92
212
  ```
93
213
 
94
- Use `heroku config` to set the `ENV_VAR_NAME` value for the staging and
95
- production remotes.
214
+ ### Predicate Methods
215
+
216
+ When using object notation, all settings have `?` and `_` predicate methods
217
+ defined on them. They work like so:
218
+
219
+ #### '?' Predicates Check For Falsity
96
220
 
97
- Now you can access your settings in your code as properties of your `Settings`
98
- class (assuming you extended Chamber in a class named `Settings`).
221
+ ```ruby
222
+ Chamber.env.my_setting # => nil
223
+ Chamber.env.my_setting? # => false
99
224
 
100
- In other words, given a configuration file like this:
225
+ Chamber.env.my_other_setting # => false
226
+ Chamber.env.my_other_setting? # => false
101
227
 
102
- ```yml
103
- s3:
104
- access_key_id: value
105
- secret_access_key: value
106
- bucket: value
228
+ Chamber.env.another_setting # => 'my value'
229
+ Chamber.env.another_setting? # => true
107
230
  ```
108
231
 
109
- the corresponding Paperclip configuration would look like this:
232
+ #### '\_' Predicates Allow for Multi-Level Testing
110
233
 
111
234
  ```ruby
112
- Paperclip::Attachment.default_options.merge!(
113
- storage: 's3',
114
- s3_credentials: {
115
- access_key_id: Settings.s3.access_key_id,
116
- secret_access_key: Settings.s3.secret_access_key
117
- },
118
- bucket: Settings.s3.bucket,
119
- ...
235
+ Chamber.env.empty? # => true
236
+ Chamber.env.my_setting_group_.my_setting? # => false
120
237
  ```
121
238
 
122
- ## General Principles
239
+ #### 'key?' Checks For Existence
123
240
 
124
- ### Support best practices with sensitive information
241
+ The `?` method will return false if a key has been set to `false` or `nil`. In
242
+ order to check if a key has been set at all, use the `key?('some_key')` method
243
+ instead.
125
244
 
126
- Generally this is expressed in this overly simplified form: "Don't store
127
- sensitive information in git." A better way to say it is that you should store
128
- sensitive information separate from non-sensitive information. There's nothing
129
- inherently wrong with storing sensitive information in git. You just wouldn't
130
- want to store it in a public repository.
245
+ Notice the difference:
131
246
 
132
- If it weren't for this concern, managing settings would be trivial, easily
133
- solved use any number of approaches; e.g., [like using YAML and ERB in an
134
- initializer](http://urgetopunt.com/rails/2009/09/12/yaml-config-with-erb.html).
247
+ ```ruby
248
+ Chamber.env.my_setting # => false
249
+ Chamber.env.my_setting? # => false
250
+
251
+ Chamber.env.key?('my_setting') # => true
252
+ Chamber.env.key?('my_non_existent_key') # => false
253
+ ```
254
+
255
+ ### ERB Preprocessing
256
+
257
+ One of the nice things about Chamber is that it runs each settings file through
258
+ ERB before it tries to parse it as YAML. The main benefit of this is that you
259
+ can use settings from previous files in ERB for later files. This is mainly
260
+ used if you follow our convention of putting all of your sensitive information
261
+ in your `credentials.yml` file.
135
262
 
136
- I recommend adding a pattern like this to `.gitignore`:
263
+ **Example:**
137
264
 
265
+ ```yaml
266
+ # credentials.yml
267
+
268
+ production:
269
+ my_secret_key: 123456789
138
270
  ```
139
- # Ignore the environment-specific files that contain the real credentials:
140
- /config/credentials-*.yml
141
271
 
142
- # But don't ignore the example file that shows the structure:
143
- !/config/credentials-example.yml
272
+ ```erb
273
+ <%# settings.yml %>
274
+
275
+ production:
276
+ my_url: http://my_username:<%= Chamber[:my_secret_key] %>@my-url.com
277
+ ```
278
+
279
+ Because by default Chamber processes `credentials` settings files before
280
+ anything else, this works.
281
+
282
+ But it's all ERB so you can do as much crazy ERB stuff in your settings files as
283
+ you'd like:
284
+
285
+ ```erb
286
+ <%# settings.yml %>
287
+
288
+ <% %w{development test production}.each do |environment| %>
289
+ <%= environment %>:
290
+ hostname_with_subdomain: <%= environment %>.example.com:3000
291
+
292
+ <% end %>
144
293
  ```
145
294
 
146
- You would then use Chamber like this:
295
+ Would result in the following settings being set:
296
+
297
+ ```yaml
298
+ development:
299
+ hostname_with_subdomain: development.example.com:3000
300
+
301
+ test:
302
+ hostname_with_subdomain: test.example.com:3000
303
+
304
+ production:
305
+ hostname_with_subdomain: production.example.com:3000
306
+ ```
307
+
308
+ ### Namespacing
309
+
310
+ If, when running your app, you would like to have certain files loaded only
311
+ under specific circumstances, you can use Chamber's namespaces.
312
+
313
+ **Example:**
147
314
 
148
315
  ```ruby
149
- class Settings
150
- extend Chamber
151
- source Rails.root.join('config', "credentials-#{Rails.env}.yml")
152
- end
316
+ Chamber.load( :basepath => '/tmp',
317
+ :namespaces => {
318
+ :environment => -> { ::Rails.env } } )
153
319
  ```
154
320
 
155
- ### Support arbitrary organization
321
+ For this class, it will not only try and load the file `config/settings.yml`,
322
+ it will _also_ try and load the file `config/settings-<environment>.yml`
323
+ where `<environment>` is whatever Rails environment you happen to be running.
156
324
 
157
- You should be able to organize your settings files however you like. You want
158
- one big jumbo settings.yml? You can do that with Chamber. You want a distinct
159
- settings file for each specific concern? You can do that too.
325
+ #### Inline Namespaces
160
326
 
161
- Chamber supports this by allowing:
327
+ If having a file per namespace value isn't your thing, you can inline your
328
+ namespaces. Taking the example from above, rather than having `settings.yml`,
329
+ `settings-development.yml`, `settings-test.yml`, `settings-staging.yml` and
330
+ `settings-production.yml`, you could do something like this:
162
331
 
163
- * Arbitrary number of files:
332
+ ```yaml
333
+ # settings.yml
334
+
335
+ development:
336
+ smtp:
337
+ username: my_development_username
338
+ password: my_development_password`
339
+
340
+ test:
341
+ smtp:
342
+ username: my_test_username
343
+ password: my_test_password`
344
+
345
+ staging:
346
+ smtp:
347
+ username: my_staging_username
348
+ password: my_staging_password`
349
+
350
+ production:
351
+ smtp:
352
+ username: my_production_username
353
+ password: my_production_password`
354
+ ```
355
+
356
+ You can even mix and match.
357
+
358
+ ```yaml
359
+ # settings.yml
360
+
361
+ development:
362
+ smtp:
363
+ username: my_development_username
364
+ password: my_development_password`
365
+
366
+ test:
367
+ smtp:
368
+ username: my_test_username
369
+ password: my_test_password`
370
+
371
+ staging:
372
+ smtp:
373
+ username: my_staging_username
374
+ password: my_staging_password`
375
+ ```
376
+
377
+ ```yaml
378
+ # settings-production.yml
379
+
380
+ smtp:
381
+ username: my_production_username
382
+ password: my_production_password`
383
+ ````
384
+
385
+ The above will yield the same results, but allows you to keep the production
386
+ values in a separate file which can be secured separately.
387
+
388
+ #### Multiple Namespaces
389
+
390
+ Multiple namespaces can be defined by passing multiple items to the loader:
164
391
 
165
392
  ```ruby
166
- class Settings
167
- extend Chamber
393
+ Chamber.load( :basepath => '/tmp',
394
+ :namespaces => {
395
+ :environment => -> { ::Rails.env },
396
+ :hostname => -> { ENV['HOST'] } } )
397
+ ```
168
398
 
169
- source Rails.root.join('config', 'settings.yml')
170
- source Rails.root.join('config', 'facebook.yml')
171
- source Rails.root.join('config', 'twitter.yml')
172
- source Rails.root.join('config', 'google-plus.yml')
173
- end
399
+ When accessed within the `test` environment on a system named `tumbleweed`, it
400
+ will load the following files in the following order:
401
+
402
+ * `settings.yml`
403
+ * `settings-test.yml`
404
+ * `settings-tumbleweed.yml`
405
+
406
+ If a file does not exist, it is skipped.
407
+
408
+ #### What Happens With Duplicate Entries?
409
+
410
+ Similarly named settings in later files can override settings defined in earlier
411
+ files.
412
+
413
+ If `settings.yml` contains a value:
414
+
415
+ ```yaml
416
+ smtp:
417
+ server: "generalserver.com"
418
+ ```
419
+
420
+ And then `settings-test.yml` contains this:
421
+
422
+ ```yaml
423
+ smtp:
424
+ server: "testserver.com"
174
425
  ```
175
426
 
176
- * Environment-specific filenames (e.g., `settings-#{Rails.env}.yml`)
427
+ The when you access the value with `Chamber[:smtp][:server]` you will receive
428
+ `testserver.com`.
429
+
430
+ ### Outputting Your Settings
177
431
 
178
- * Namespaces:
432
+ Chamber makes it dead simple to output your environment settings in a variety of
433
+ formats.
434
+
435
+ The simplest is:
179
436
 
180
437
  ```ruby
181
- class Settings
182
- extend Chamber
438
+ Chamber.to_s
439
+ # => MY_SETTING="my value" MY_OTHER_SETTING="my other value"
440
+ ```
183
441
 
184
- source Rails.root.join('config', 'settings.yml'), namespace: Rails.env
442
+ But you can pass other options to customize the string:
443
+
444
+ * `pair_separator`
445
+ * `value_surrounder`
446
+ * `name_value_separator`
447
+
448
+ ```ruby
449
+ Chamber.to_s pair_separator: "\n",
450
+ value_surrounder: "'",
451
+ name_value_separator: ': '
452
+
453
+ # => MY_SETTING: 'my value'
454
+ # => MY_OTHER_SETTING: 'my other value'
455
+ ```
456
+
457
+ ### The chamber Command Line App
458
+
459
+ Chamber provides a flexible binary that you can use to make working with your
460
+ configurations easier. Let's take a look:
461
+
462
+ #### Common Options
463
+
464
+ Each of the commands described below takes a few common options.
465
+
466
+ * `--preset` (or `-p`): Allows you to quickly set the basepath, files and/or
467
+ namespaces for a given situation (eg working with a Rails app).
468
+
469
+ **Example:** `--preset=rails`
470
+
471
+ * `--files` (or `-f`): Allows you to specifically set the file patterns that
472
+ Chamber should look at in determining where to load settings information from.
473
+
474
+ **Example:** `--files=/path/to/my/application/secret.yml /path/to/my/application/settings/*.yml`
475
+
476
+ * `--basepath` (or `-b`): Sets the base path that Chamber will use to look for
477
+ its [common settings files](#convention-over-configuration).
478
+
479
+ **Example:** `--basepath=/path/to/my/application`
480
+
481
+ * `--namespaces` (or `-n`): The namespace values which will be considered for
482
+ loading settings files.
483
+
484
+ **Example:** `--namespaces=development`
485
+
486
+ _**Note:** `--basepath`, `--preset` and `--files` are mutually exclusive._
487
+
488
+ #### Settings
489
+
490
+ ##### Settings Commands
491
+
492
+ ###### Show
493
+
494
+ Gives users an easy way of looking at all of the settings that Chamber knows
495
+ about for a given context. It will be output as a hash of hashes by default.
496
+
497
+ * `--as-env`: Instead of outputting the settings as a hash of hashes, convert
498
+ the settings into environment variable-compatible versions.
499
+
500
+ **Example:** `--as-env`
501
+
502
+ **Example:** `chamber settings show -p=rails`
503
+
504
+ ###### Files
505
+
506
+ Very useful for troubleshooting, this will output all of the files that
507
+ Chamber considers relevant based on the given options passed.
508
+
509
+ Additionally, the order is significant. Chamber will load settings from the
510
+ top down so any duplicate items in subsequent entries will override items from
511
+ previous ones.
512
+
513
+ **Example:** `chamber settings files -p=rails`
514
+
515
+ ###### Compare
516
+
517
+ Will display a diff of the settings for one set of namespaces vs the settings
518
+ for a second set of namespaces.
519
+
520
+ This is extremely handy if, for example, you would like to see whether the
521
+ settings you're using for development match up with the settings you're using
522
+ for production, or if you're setting all of the same settings for any two
523
+ environments.
524
+
525
+ * `--keys-only`: This is the default. When performing a comparison, only the
526
+ keys will be considered since values between namespaces will often (and
527
+ should often) be different.
528
+
529
+ **Example:** `--keys-only`, `--no-keys-only`
530
+
531
+ * `--first`: This is an array of the first set of namespace settings that you
532
+ would like to compare from. You can list one or more.
533
+
534
+ **Example:** `--first=development`, `--first=development my_host_name`
535
+
536
+ * `--second`: This is an array of the second set of namespace settings that
537
+ you would like to compare against that specified by `--first`. You can list
538
+ one or more.
539
+
540
+ **Example:** `--second=staging`, `--second=staging my_host_name`
541
+
542
+ **Example:** `chamber settings compare --first=development --second=staging -p=rails`
543
+
544
+ #### Heroku
545
+
546
+ As we described above, working with Heroku environment variables is tedious at
547
+ best. Chamber gives you a few ways to help with that.
548
+
549
+ _**Note:** I'll be using the `--preset` shorthand `-p` for brevity below but the
550
+ examples will work with any of the other options described
551
+ [above](#common-options)._
552
+
553
+ ##### Heroku Common Options
554
+
555
+ * `--app` (or `-a`): Heroku application name for which you would like to affect
556
+ its environment variables.
557
+
558
+ **Example:** `--app=my-heroku-app-name`
559
+
560
+ * `--dry-run` (or `-d`): The command will not actually execute, but will show
561
+ you a summary of what *would* have happened.
562
+
563
+ **Example:** `--dry-run`
564
+
565
+ * `--only-ignored` (or `-o`): This is the default. Because Heroku has no issues
566
+ reading from the config files you have stored in your repo, there is no need
567
+ to set *all* of your settings as environment variables. So by default,
568
+ Chamber will only convert and push those settings which have been gitignored.
569
+
570
+ To push everything, use the `--no-only-ignored` flag.
571
+
572
+ **Example:** `--only-ignored`, `--no-only-ignored`
573
+
574
+ ##### Heroku Commands
575
+
576
+ ###### Push
577
+
578
+ As we described above, this command will take your current settings and push
579
+ them to Heroku as environment variables that Chamber will be able to
580
+ understand.
581
+
582
+ **Example:** `chamber heroku push -a=my-heroku-app -p=rails -n=staging`
583
+
584
+ _**Note:** To see exactly how Chamber sees your settings as environment variables, see
585
+ the [chamber settings show](#general-settings-commands) command above._
586
+
587
+ ###### Pull
588
+
589
+ Will display the list of environment variables that you have set on your
590
+ Heroku instance.
591
+
592
+ This is similar to just executing `heroku config --shell` except that you can
593
+ specify the following option:
594
+
595
+ * `--into`: The file which the pulled settings will be copied into. This file
596
+ *will* be overridden.
597
+
598
+ _**Note:** Eventually this will be parsed into YAML that Chamber can load
599
+ straight away, but for now, it's basically just redirecting the output._
600
+
601
+ **Example:** `--into=/path/to/my/app/settings/heroku.yml`
602
+
603
+ **Example:** `chamber heroku pull -a=my-heroku-app --into=/path/to/my/app/heroku.yml`
604
+
605
+ ###### Diff
606
+
607
+ Will use git's diff function to display the difference between what Chamber
608
+ knows about locally and what Heroku currently has set. This is very handy for
609
+ knowing what changes may be made if `chamber heroku push` is executed.
610
+
611
+ **Example:** `chamber heroku diff -a=my-heroku-app -p=rails -n=staging`
612
+
613
+ ###### Clear
614
+
615
+ Will remove any environment variables from Heroku that Chamber knows about.
616
+ This is useful for clearing out Chamber-related settings without touching
617
+ Heroku addon-specific items.
618
+
619
+ **Example:** `chamber heroku clear -a=my-heroku-app -p=rails -n=staging`
620
+
621
+ #### Travis CI
622
+
623
+ ##### Travis Common Options
624
+
625
+ * `--dry-run` (or `-d`): The command will not actually execute, but will show
626
+ you a summary of what *would* have happened.
627
+
628
+ **Example:** `--dry-run`
629
+
630
+ * `--only-ignored` (or `-o`): This is the default. Because Travis has no issues
631
+ reading from the config files you have stored in your repo, there is no need
632
+ to set *all* of your settings as environment variables. So by default,
633
+ Chamber will only convert and push those settings which have been gitignored.
634
+
635
+ To push everything, use the `--no-only-ignored` flag.
636
+
637
+ **Example:** `--only-ignored`, `--no-only-ignored`
638
+
639
+ ##### Travis Commands
640
+
641
+ ###### Secure
642
+
643
+ Travis CI allows you to use the public key on your Travis repo to encrypt
644
+ items such as environment variables which you would like for Travis to be able
645
+ to have access to, but which you wouldn't necessarily want to be in plain text
646
+ inside of your repo.
647
+
648
+ This command takes the settings that Chamber knows about, encrypts them, and
649
+ puts them inside of your .travis.yml at which point they can be safely
650
+ committed.
651
+
652
+ _**Warning:** This will delete *all* of your previous 'secure' entries under
653
+ 'env.global' in your .travis.yml file._
654
+
655
+ **Example:** `chamber travis secure -p=rails -n=continuous_integration`
656
+
657
+ ### Basic Boolean Conversion
658
+
659
+ One of the things that is a huge pain when dealing with environment variables is
660
+ that they can only be strings. Unfortunately this is kind of a problem for
661
+ settings which you would like to use to set whether a specific item is enabled
662
+ or disabled. Because this:
663
+
664
+ ```yaml
665
+ # settings.yml
666
+
667
+ my_feature:
668
+ enabled: false
669
+ ```
670
+
671
+ ```ruby
672
+ if Chamber.env.my_feature.enabled?
673
+ # Do stuff with my feature
185
674
  end
186
675
  ```
187
676
 
188
- ### Support overriding setting values at runtime from ENV
677
+ Will always return true because `false` becomes `'false'` on Heroku which, as
678
+ far as Ruby is concerned, is `true`. Now, you could completely omit the
679
+ `enabled` key, however this causes issues if you would like to audit your
680
+ settings (say for each environment) to make sure they are all the same. Some
681
+ will have the `enabled` setting and some will not, which will give you false
682
+ positives.
189
683
 
190
- [heroku](http://heroku.com) addons are configured from ENV. To support this,
191
- Chamber's `source` method provides an `override_from_environment` option; e.g.,
684
+ You could work around it by doing this:
192
685
 
193
686
  ```ruby
194
- class Settings
195
- extend Chamber
687
+ if Chamber.env.my_feature.enabled == 'true'
688
+ # Do stuff with my feature
689
+ end
690
+ ```
691
+
692
+ but that looks awful.
693
+
694
+ To solve this problem, Chamber reviews all of your settings values and, if they
695
+ are any of the following exact strings (case insensitive):
196
696
 
197
- source Rails.root.join('config', 'settings.yml'), override_from_environment: true
697
+ * 'false'
698
+ * 'f'
699
+ * 'no'
700
+ * 'true'
701
+ * 't'
702
+ * 'yes'
703
+
704
+ The value will be converted to the proper Boolean value. In which case the
705
+ above `Chamber.env.my_feature.enabled?` will work as expected and your
706
+ environment audit will pass.
707
+
708
+ ### In Order to Add Advanced Functionality
709
+
710
+ In any case that you need to set configuration options or do advanced post
711
+ processing on your YAML data, you'll want to create your own object for
712
+ accessing it. Don't worry, Chamber will take you 98% of the way there.
713
+
714
+ Just include it like so:
715
+
716
+ ```ruby
717
+ class Settings < Chamber
198
718
  end
199
719
  ```
200
720
 
201
- ## Ideas
721
+ Now, rather than using `Chamber[:application_host]` to access your
722
+ environment, you can simply use `Settings[:application_host]`.
202
723
 
203
- * Add a rake task for validating environments (do all environments have the same
204
- settings?)
724
+ ## Best Practices
205
725
 
206
- * Add a rake task for setting Heroku environment variables.
726
+ ### Why Do We Need Chamber?
207
727
 
208
- ## Alternatives
728
+ > Don't store sensitive information in git.
729
+
730
+ A better way to say it is that you should store sensitive information separate
731
+ from non-sensitive information. There's nothing inherently wrong with storing
732
+ sensitive information in git. You just wouldn't want to store it in a public
733
+ repository.
209
734
 
210
- ### figaro
735
+ If it weren't for this concern, managing settings would be trivial, easily
736
+ solved use any number of approaches; e.g., [like using YAML and ERB in an
737
+ initializer](http://urgetopunt.com/rails/2009/09/12/yaml-config-with-erb.html).
738
+
739
+ ### Organizing Your Settings
740
+
741
+ We recommend starting with a single `config/settings.yml` file. Once this file
742
+ begins to become too unwieldy, you can begin to extract common options (let's
743
+ say SMTP settings) into another file (perhaps `config/settings/smtp.yml`).
211
744
 
212
- [figaro](https://github.com/laserlemon/figaro)
745
+ ### Keeping Private Settings Private
213
746
 
214
- ### idkfa
747
+ Obviously the greater the number of files which need to be kept private the more
748
+ difficult it is to manage the settings. Therefore we suggest beginning with one
749
+ private file that stores all of your credentials.
215
750
 
216
- [idkfa](https://github.com/bendyworks/idkfa)
751
+ ### Ignoring Settings Files
217
752
 
218
- ### settingslogic
753
+ We recommend adding the following to your `.gitignore` file:
754
+
755
+ ```
756
+ # Ignore the environment-specific files that contain the real credentials:
757
+ /config/credentials.yml
758
+ /config/credentials-*.yml
759
+
760
+ # But don't ignore the example file that shows the structure:
761
+ !/config/credentials-example.yml
762
+ ```
763
+
764
+ Along with any namespace-specific exclusions. For example, if you're using
765
+ Rails, you may want to exclude some of your environment-specific files:
766
+
767
+ ```
768
+ *-staging.yml
769
+ *-production.yml
770
+ ```
771
+
772
+ ### Full Example
773
+
774
+ Let's walk through how you might use Chamber to configure your SMTP settings:
775
+
776
+ ```yaml
777
+ # config/settings.yml
778
+
779
+ stuff:
780
+ not: "Not Related to SMTP"
781
+
782
+ # config/settings/smtp.yml
783
+
784
+ smtp:
785
+ headers:
786
+ X-MYAPP-NAME: My Application Name
787
+ X-MYAPP-STUFF: Other Stuff
788
+
789
+ # config/settings/smtp-staging.yml
790
+
791
+ smtp:
792
+ username: my_test_user
793
+ password: my_test_password
794
+ ```
795
+
796
+ Now you can access both `username` and `headers` off of `smtp` like so:
797
+
798
+ ```ruby
799
+ Chamber[:smtp][:headers]
800
+ # => { X-MYAPP-NAME: 'My Application Name', X-MYAPP-STUFF: 'Other Stuff' }
801
+
802
+ Chamber[:smtp][:password]
803
+ # => my_test_password
804
+ ```
805
+
806
+ ## Alternatives
219
807
 
220
- [settingslogic](https://github.com/binarylogic/settingslogic)
808
+ * [dotenv](https://github.com/bkeepers/dotenv)
809
+ * [figaro](https://github.com/laserlemon/figaro)
810
+ * [idkfa](https://github.com/bendyworks/idkfa)
811
+ * [settingslogic](https://github.com/binarylogic/settingslogic)
221
812
 
222
813
  ### Others?
223
814