chamber 0.0.4 → 1.0.0

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
  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