snfoil 0.9.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/Gemfile +6 -0
  4. data/LICENSE.txt +201 -0
  5. data/README.md +95 -505
  6. data/docs/build-context.md +56 -0
  7. data/docs/create-context.md +109 -0
  8. data/docs/destroy-context.md +102 -0
  9. data/docs/index-context.md +70 -0
  10. data/docs/show-context.md +71 -0
  11. data/docs/update-context.md +107 -0
  12. data/lib/{sn_foil → snfoil}/adapters/orms/active_record.rb +14 -0
  13. data/lib/{sn_foil → snfoil}/adapters/orms/base_adapter.rb +15 -1
  14. data/lib/snfoil/crud/build_context.rb +49 -0
  15. data/lib/snfoil/crud/change_context.rb +48 -0
  16. data/lib/snfoil/crud/context.rb +41 -0
  17. data/lib/snfoil/crud/create_context.rb +45 -0
  18. data/lib/snfoil/crud/destroy_context.rb +57 -0
  19. data/lib/snfoil/crud/index_context.rb +46 -0
  20. data/lib/snfoil/crud/setup_context.rb +90 -0
  21. data/lib/snfoil/crud/show_context.rb +52 -0
  22. data/lib/snfoil/crud/update_context.rb +60 -0
  23. data/lib/snfoil/version.rb +19 -0
  24. data/lib/snfoil.rb +69 -0
  25. data/snfoil.gemspec +47 -0
  26. metadata +100 -33
  27. data/Rakefile +0 -4
  28. data/lib/sn_foil/context.rb +0 -24
  29. data/lib/sn_foil/contexts/build_context.rb +0 -67
  30. data/lib/sn_foil/contexts/change_context.rb +0 -101
  31. data/lib/sn_foil/contexts/create_context.rb +0 -158
  32. data/lib/sn_foil/contexts/destroy_context.rb +0 -164
  33. data/lib/sn_foil/contexts/index_context.rb +0 -64
  34. data/lib/sn_foil/contexts/setup_context.rb +0 -119
  35. data/lib/sn_foil/contexts/show_context.rb +0 -61
  36. data/lib/sn_foil/contexts/update_context.rb +0 -168
  37. data/lib/sn_foil/policy.rb +0 -55
  38. data/lib/sn_foil/searcher.rb +0 -123
  39. data/lib/sn_foil/version.rb +0 -5
  40. data/lib/sn_foil.rb +0 -49
data/README.md CHANGED
@@ -1,8 +1,15 @@
1
- # Sn::Foil
1
+ # SnFoil
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/sn_foil`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ ![build](https://github.com/limited-effort/snfoil/actions/workflows/main.yml/badge.svg) [![maintainability](https://api.codeclimate.com/v1/badges/86e0b2490738e140f2e2/maintainability)](https://codeclimate.com/github/limited-effort/snfoil/maintainability)
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ SnFoil has been broken into smaller modules. This gem serves to combine the most common gems in the SnFoil family and add some additional CRUD behavior.
6
+
7
+ This gem only uses [contexts](https://github.com/limited-effort/snfoil-context), [policies](https://github.com/limited-effort/snfoil-policy), and [searchers](https://github.com/limited-effort/snfoil-searcher) but you can check out all our modules here:
8
+ - [Contexts](https://github.com/limited-effort/snfoil-context) - Pipelined Business Logic
9
+ - [Controllers](https://github.com/limited-effort/snfoil-controller) - Separate HTTP Logic
10
+ - [Policies](https://github.com/limited-effort/snfoil-policy) - Authorization Checks
11
+ - [Rails](https://github.com/limited-effort/snfoil-rails) - Ruby on Rails Fluff
12
+ - [Searchers](https://github.com/limited-effort/snfoil-searcher) - Intuitive Search Classes
6
13
 
7
14
  ## Installation
8
15
 
@@ -11,546 +18,129 @@ Add this line to your application's Gemfile:
11
18
  ```ruby
12
19
  gem 'snfoil'
13
20
  ```
21
+ ## Usage
14
22
 
15
- And then execute:
23
+ ### Contexts
16
24
 
17
- $ bundle
25
+ There is where the magic of the original gem started. The idea was to make a pipleline of logic that you could "plug" into certain intervals at. You can find the [full documentation for contexts here](https://github.com/limited-effort/snfoil-context).
18
26
 
19
- Or install it yourself as:
27
+ SnFoil adds six CRUD-centeric contexts prewired to get you off the ground as fast as possible. Each context sets up intervals for you, and generally follow the same pattern for calls: `setup`, `setup_<action>`, `before_<action>`, `after_<action>_success`, `after_<action>_failure`, and `after_<action>`. You can find more information about each by clicking their respective links.
28
+ - [SnFoil::CRUD::BuildContext](docs/build-context.md) - for setting up an object.
29
+ - [SnFoil::CRUD::CreateContext](docs/create-context.md) - for setting up and saving an object to a data source.
30
+ - [SnFoil::CRUD::DestroyContext](docs/destroy-context.md) - find and destroy an object
31
+ - [SnFoil::CRUD::IndexContext](docs/index-context.md) - query for objects
32
+ - [SnFoil::CRUD::ShowContext](docs/show-context.md) - find an object
33
+ - [SnFoil::CRUD::UpdateContext](docs/update-context.md) find and update an object
20
34
 
21
- $ gem install snfoil
35
+ You can pick and choose which features you want to use by including the specific file
22
36
 
23
- ## Usage
37
+ ```ruby
38
+ require 'snfoil/crud/index_context'
39
+ require 'snfoil/crud/show_context'
24
40
 
41
+ class PeopleContext
42
+ include SnFoil::CRUD::IndexContext
43
+ include SnFoil::CRUD::ShowContext
44
+
45
+ # hooks and methods here
46
+ end
47
+ ```
25
48
 
26
- ### Major Components
27
-
28
- #### Model
29
- #### Policy
30
- #### Searcher
31
-
32
- ## Contexts
33
- Contexts are groupings of common actions that a certain entity can perform.
34
-
35
- ### Data
36
-
37
- ### Actions
38
-
39
- SnFoil Contexts handle basic CRUD through a few different actions
40
-
41
- <table>
42
- <thead>
43
- <th>Action</th>
44
- <th>Description</th>
45
- </thead>
46
- <tbody>
47
- <tr>
48
- <td>Build</td>
49
- <td>
50
- The action on setting up a model but not persiting.
51
- <div>
52
- <i>Author's note:</i> So far I have just been using this so factories in testing follow the same setup logic as a context would.
53
- </div>
54
- </td>
55
- </tr>
56
- <tr>
57
- <td>Create</td>
58
- <td>The action of setting up a model and persisting it.</td>
59
- </tr>
60
- <tr>
61
- <td>Update</td>
62
- <td>The action of finding a pre-existing model and updating the attributes.</td>
63
- </tr>
64
- <tr>
65
- <td>Destroy</td>
66
- <td>The action of finding a pre-existing model and destroying it.</td>
67
- </tr>
68
- <tr>
69
- <td>Show</td>
70
- <td>The action of finding a pre-existing model by an identifier.</td>
71
- </tr>
72
- <tr>
73
- <td>Index</td>
74
- <td>The action of finding a pre-existing models by using a searcher.</td>
75
- </tr>
76
- </tbody>
77
- </table>
78
-
79
- ### Methods
80
- Methods allow users to create inheritable actions that occur in a specific order. Methods will always run before their hook counterpart. Since these are inheritable, you can chain needed actions all the way through the parent heirarchy by using the `super` keyword.
81
-
82
- <strong>Important Note</strong> Methods <u>always</u> need to return the options hash at the end.
83
-
84
- <i>Author's opinion:</i> While simplier than hooks, they do not allow for as clean of a composition as hooks.
85
-
86
- #### Example
49
+ Or you can add all them in one go with `SnFoil::CRUD::Context`.
87
50
 
88
51
  ```ruby
89
- # Call the webhooks for third party integrations
90
- # Commit business logic to internal process
91
- def after_create_success(**options)
92
- options = super
52
+ require 'snfoil/crud/context'
93
53
 
94
- call_webhook_for_model(options[:object])
95
- finalize_business_logic(options[:object])
54
+ class PeopleContext
55
+ include SnFoil::CRUD::Context
96
56
 
97
- options
57
+ # hooks and methods here
98
58
  end
59
+ ```
60
+
61
+ Each of the CRUD contexts allows a Searcher, Policy, and Model to be added to the class. These are there so each function of the CRUD context can proceed without a lot of bootstrap code.
99
62
 
100
- # notify error tracker
101
- def after_create_error(**options)
102
- options = super
63
+ #### Searchers
64
+ Any time a model is fetched, that process goes through a searcher. This ensures that authorization logic is always followed - lowering the likelyhood of entity/user getting access to a model they shouldn't
103
65
 
104
- notify_errors(options[:object].errors)
66
+ ```ruby
67
+ class PeopleContext
68
+ include SnFoil::CRUD::Context
105
69
 
106
- options
70
+ searcher PeopleSearcher
107
71
  end
108
72
  ```
109
73
 
110
- ### Hooks
111
- Hooks make it very easy to compose multiple actions that need to occur in a specific order. You can have as many repeated hooks as you would like. This makes defining single responsibility hooks very simple, and they will get called in the order they are defined. The major downside of hooks are that they are currently not inheritable.
74
+ #### Policies
75
+ Policies serve two purposes:
76
+ - Authorization
77
+ - Scopes
78
+
79
+ Authorization is pretty self explainatory. It is the logic of whether or not an entity is allowed to perform an action.
112
80
 
113
- <strong>Important Note</strong> Hooks <u>always</u> need to return the options hash at the end.
81
+ Scopes are definition of data that an entity/user is allowed to access. While they are not required for SnFoil::Policies, they are required for SnFoil's CRUD helpers.
114
82
 
115
- #### Example
116
- Lets take the Method example and make it into hooks instead.
117
83
  ```ruby
118
- # Call the webhooks for third party integrations
119
- after_create_success do |options|
120
- call_webhook_for_model(options[:object])
121
- options
122
- end
84
+ class PeopleContext
85
+ include SnFoil::CRUD::Context
123
86
 
124
- # Commit business logic to internal process
125
- after_create_success do |options|
126
- finalize_business_logic(options[:object])
127
- options
87
+ policy PersonPolicy
128
88
  end
89
+ ```
90
+
91
+ #### Models
129
92
 
130
- # notify error tracker
131
- after_create_error do |options|
132
- notify_errors(options[:object].errors)
133
- options
93
+ Models are just the entity that the primary action of the CRUD context operates on. Simply put, its the Model.
94
+
95
+ ```ruby
96
+ class PeopleContext
97
+ include SnFoil::CRUD::Context
98
+
99
+ model Person
134
100
  end
135
101
  ```
136
102
 
137
- <table>
138
- <thead>
139
- <th>Name</th>
140
- <th>Timing</th>
141
- <th>Description</th>
142
- </thead>
143
- <tbody>
144
- <tr>
145
- <td>setup</td>
146
- <td>-Always at the beginning</td>
147
- <td>Primarily used for basic setup logic that always needs to occur</td>
148
- </tr>
149
- <tr>
150
- <td>setup_&lt;action&gt;</td>
151
- <td>-Before the object has been found or created</td>
152
- <td>Primarily used for basic setup logic that only needs to occur for certain actions</td>
153
- </tr>
154
- <tr>
155
- <td>before_&lt;action&gt;</td>
156
- <td>
157
- <div>-After the object has been found or created</div>
158
- <div>-Before the object has been persisted/altered</div>
159
- </td>
160
- <td></td>
161
- </tr>
162
- <tr>
163
- <td>after_&lt;action&gt;_success</td>
164
- <td>-After the object has been successfully been persisted/altered</td>
165
- <td></td>
166
- </tr>
167
- <tr>
168
- <td>after_&lt;action&gt;_failure</td>
169
- <td>-After an error has occured persisting/altering the object</td>
170
- <td></td>
171
- <tr>
172
- <td>after_&lt;action&gt;</td>
173
- <td>-Always at the end</td>
174
- <td></td>
175
- </tr>
176
- </tr>
177
- </tbody>
178
- <table>
179
-
180
- ### Call Order
181
-
182
- The call order for actions is extremely important because SnFoil passes the options hash throughout the entire process. So any data you may need down the call order can be added earlier in the stack.
183
-
184
- <table>
185
- <thead>
186
- <tr>
187
- <th rowspan="2">Action</th>
188
- <th colspan="2">Order</th>
189
- </tr>
190
- <tr>
191
- <th>Type</th>
192
- <th>Name</th>
193
- </tr>
194
- </thead>
195
- <tbody>
196
- <tr>
197
- <td rowspan="5">Build</td>
198
- </tr>
199
- <tr>
200
- <td>Method</td>
201
- <td>setup</td>
202
- </tr>
203
- <tr>
204
- <td>Hooks</td>
205
- <td>setup</td>
206
- </tr>
207
- <tr>
208
- <td>Method</td>
209
- <td>setup_build</td>
210
- </tr>
211
- <tr>
212
- <td>Hooks</td>
213
- <td>setup_build</td>
214
- </tr>
215
- <tr><td rowspan="25">Create</td></tr>
216
- <tr>
217
- <td>Method</td>
218
- <td>setup</td>
219
- </tr>
220
- <tr>
221
- <td>Hooks</td>
222
- <td>setup</td>
223
- </tr>
224
- <tr>
225
- <td>Method</td>
226
- <td>setup_build</td>
227
- </tr>
228
- <tr>
229
- <td>Hooks</td>
230
- <td>setup_build</td>
231
- </tr>
232
- <tr>
233
- <td>Method</td>
234
- <td>setup_change</td>
235
- </tr>
236
- <tr>
237
- <td>Hooks</td>
238
- <td>setup_change</td>
239
- </tr>
240
- <tr>
241
- <td>Method</td>
242
- <td>setup_create</td>
243
- </tr>
244
- <tr>
245
- <td>Hooks</td>
246
- <td>setup_create</td>
247
- </tr>
248
- <tr>
249
- <td>Method</td>
250
- <td>before_change</td>
251
- </tr>
252
- <tr>
253
- <td>Hooks</td>
254
- <td>before_change</td>
255
- </tr>
256
- <tr>
257
- <td>Method</td>
258
- <td>before_create</td>
259
- </tr>
260
- <tr>
261
- <td>Hooks</td>
262
- <td>before_create</td>
263
- </tr>
264
- <tr>
265
- <td>Method</td>
266
- <td><i>*after_change_success</i</td>
267
- </tr>
268
- <tr>
269
- <td>Hooks</td>
270
- <td><i>*after_change_success</i</td>
271
- </tr>
272
- <tr>
273
- <td>Method</td>
274
- <td><i>*after_create_success</i</td>
275
- </tr>
276
- <tr>
277
- <td>Hooks</td>
278
- <td><i>*after_create_success</i</td>
279
- </tr>
280
- <tr>
281
- <td>Method</td>
282
- <td><i>*after_change_failure</i</td>
283
- </tr>
284
- <tr>
285
- <td>Hooks</td>
286
- <td><i>*after_change_failure</i</td>
287
- </tr>
288
- <tr>
289
- <td>Method</td>
290
- <td><i>*after_create_failure</i</td>
291
- </tr>
292
- <tr>
293
- <td>Hooks</td>
294
- <td><i>*after_create_failure</i</td>
295
- </tr>
296
- <tr>
297
- <td>Method</td>
298
- <td>after_change</td>
299
- </tr>
300
- <tr>
301
- <td>Hooks</td>
302
- <td>after_change</td>
303
- </tr>
304
- <tr>
305
- <td>Method</td>
306
- <td>after_create</td>
307
- </tr>
308
- <tr>
309
- <td>Hooks</td>
310
- <td>after_create</td>
311
- </tr>
312
- <tr><td rowspan="23">Update</td></tr>
313
- <tr>
314
- <td>Method</td>
315
- <td>setup</td>
316
- </tr>
317
- <tr>
318
- <td>Hooks</td>
319
- <td>setup</td>
320
- </tr>
321
- <tr>
322
- <td>Method</td>
323
- <td>setup_change</td>
324
- </tr>
325
- <tr>
326
- <td>Hooks</td>
327
- <td>setup_change</td>
328
- </tr>
329
- <tr>
330
- <td>Method</td>
331
- <td>setup_update</td>
332
- </tr>
333
- <tr>
334
- <td>Hooks</td>
335
- <td>setup_update</td>
336
- </tr>
337
- <tr>
338
- <td>Method</td>
339
- <td>before_change</td>
340
- </tr>
341
- <tr>
342
- <td>Hooks</td>
343
- <td>before_change</td>
344
- </tr>
345
- <tr>
346
- <td>Method</td>
347
- <td>before_update</td>
348
- </tr>
349
- <tr>
350
- <td>Hooks</td>
351
- <td>before_update</td>
352
- </tr>
353
- <tr>
354
- <td>Method</td>
355
- <td><i>*after_change_success</i</td>
356
- </tr>
357
- <tr>
358
- <td>Hooks</td>
359
- <td><i>*after_change_success</i</td>
360
- </tr>
361
- <tr>
362
- <td>Method</td>
363
- <td><i>*after_update_success</i</td>
364
- </tr>
365
- <tr>
366
- <td>Hooks</td>
367
- <td><i>*after_update_success</i</td>
368
- </tr>
369
- <tr>
370
- <td>Method</td>
371
- <td><i>*after_change_failure</i</td>
372
- </tr>
373
- <tr>
374
- <td>Hooks</td>
375
- <td><i>*after_change_failure</i</td>
376
- </tr>
377
- <tr>
378
- <td>Method</td>
379
- <td><i>*after_update_failure</i</td>
380
- </tr>
381
- <tr>
382
- <td>Hooks</td>
383
- <td><i>*after_update_failure</i</td>
384
- </tr>
385
- <tr>
386
- <td>Method</td>
387
- <td>after_change</td>
388
- </tr>
389
- <tr>
390
- <td>Hooks</td>
391
- <td>after_change</td>
392
- </tr>
393
- <tr>
394
- <td>Method</td>
395
- <td>after_update</td>
396
- </tr>
397
- <tr>
398
- <td>Hooks</td>
399
- <td>after_update</td>
400
- </tr>
401
- <tr><td rowspan="23">Destroy</td></tr>
402
- <tr>
403
- <td>Method</td>
404
- <td>setup</td>
405
- </tr>
406
- <tr>
407
- <td>Hooks</td>
408
- <td>setup</td>
409
- </tr>
410
- <tr>
411
- <td>Method</td>
412
- <td>setup_change</td>
413
- </tr>
414
- <tr>
415
- <td>Hooks</td>
416
- <td>setup_change</td>
417
- </tr>
418
- <tr>
419
- <td>Method</td>
420
- <td>setup_destroy</td>
421
- </tr>
422
- <tr>
423
- <td>Hooks</td>
424
- <td>setup_destroy</td>
425
- </tr>
426
- <tr>
427
- <td>Method</td>
428
- <td>before_change</td>
429
- </tr>
430
- <tr>
431
- <td>Hooks</td>
432
- <td>before_change</td>
433
- </tr>
434
- <tr>
435
- <td>Method</td>
436
- <td>before_destroy</td>
437
- </tr>
438
- <tr>
439
- <td>Hooks</td>
440
- <td>before_destroy</td>
441
- </tr>
442
- <tr>
443
- <td>Method</td>
444
- <td><i>*after_change_success</i</td>
445
- </tr>
446
- <tr>
447
- <td>Hooks</td>
448
- <td><i>*after_change_success</i</td>
449
- </tr>
450
- <tr>
451
- <td>Method</td>
452
- <td><i>*after_destroy_success</i</td>
453
- </tr>
454
- <tr>
455
- <td>Hooks</td>
456
- <td><i>*after_destroy_success</i</td>
457
- </tr>
458
- <tr>
459
- <td>Method</td>
460
- <td><i>*after_change_failure</i</td>
461
- </tr>
462
- <tr>
463
- <td>Hooks</td>
464
- <td><i>*after_change_failure</i</td>
465
- </tr>
466
- <tr>
467
- <td>Method</td>
468
- <td><i>*after_destroy_failure</i</td>
469
- </tr>
470
- <tr>
471
- <td>Hooks</td>
472
- <td><i>*after_destroy_failure</i</td>
473
- </tr>
474
- <tr>
475
- <td>Method</td>
476
- <td>after_change</td>
477
- </tr>
478
- <tr>
479
- <td>Hooks</td>
480
- <td>after_change</td>
481
- </tr>
482
- <tr>
483
- <td>Method</td>
484
- <td>after_destroy</td>
485
- </tr>
486
- <tr>
487
- <td>Hooks</td>
488
- <td>after_destroy</td>
489
- </tr>
490
- <tr>
491
- <td rowspan="5">Show</td>
492
- </tr>
493
- <tr>
494
- <td>Method</td>
495
- <td>setup</td>
496
- </tr>
497
- <tr>
498
- <td>Hooks</td>
499
- <td>setup</td>
500
- </tr>
501
- <tr>
502
- <td>Method</td>
503
- <td>setup_show</td>
504
- </tr>
505
- <tr>
506
- <td>Hooks</td>
507
- <td>setup_show</td>
508
- </tr>
509
- <tr>
510
- <td rowspan="5">Index</td>
511
- </tr>
512
- <tr>
513
- <td>Method</td>
514
- <td>setup</td>
515
- </tr>
516
- <tr>
517
- <td>Hooks</td>
518
- <td>setup</td>
519
- </tr>
520
- <tr>
521
- <td>Method</td>
522
- <td>setup_index</td>
523
- </tr>
524
- <tr>
525
- <td>Hooks</td>
526
- <td>setup_index</td>
527
- </tr>
528
- </tbody>
529
- <table>
530
-
531
- <div>
532
- * only occurs depeding on the success or failure of the action
533
- </div>
534
-
535
- ## Policies
536
-
537
- ## Searchers
103
+ ### ORM Adapters
104
+
105
+ In order to be able to work with multiple data sources SnFoil allows you to create adapters for interacting with object. Adapters are just wrapper for your objects that add specific functionality needed by the base `SnFoil::CRUD` methods. SnFoil handles the wrapping and unwrapping for you under the hood.
106
+
107
+ We created an adapter for `ActiveRecord` for you, but you can also create your own by inheriting from `SnFoil::Adapters::ORMs::BaseAdapter`.
108
+
109
+ Just make sure your adapter defines the following methods:
110
+ - `new` - method to create a new datasource object. This should not commit to the data source
111
+ - `all` - method to grab all of a type from the data source
112
+ - `save` - method to commit an object to the data source
113
+ - `destroy` - method to remove an object from the data source
114
+ - `attributes=` - method for assigning a hash of attributes to the object
115
+
116
+ You can set your custom adapter by directly assigning it
117
+
118
+ ```ruby
119
+ SnFoil.orm = CustomAdapter
120
+ ```
121
+
122
+ Or if you prefer an initializer style
538
123
 
124
+ ```ruby
125
+ SnFoil.configure do |config|
126
+ config.orm = CustomAdapter
127
+ end
128
+ ```
539
129
 
540
130
  ## Development
541
131
 
542
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
132
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
543
133
 
544
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
134
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
545
135
 
546
136
  ## Contributing
547
137
 
548
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/snfoil. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
138
+ Bug reports and pull requests are welcome on GitHub at https://github.com/limited-effort/snfoil. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/limited-effort/snfoil/blob/main/CODE_OF_CONDUCT.md).
549
139
 
550
140
  ## License
551
141
 
552
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
142
+ The gem is available as open source under the terms of the [Apache 2 License](https://opensource.org/licenses/Apache-2.0).
553
143
 
554
144
  ## Code of Conduct
555
145
 
556
- Everyone interacting in the Sn::Foil projects codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/snfoil/blob/master/CODE_OF_CONDUCT.md).
146
+ Everyone interacting in the Snfoil::Context project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/limited-effort/snfoil/blob/main/CODE_OF_CONDUCT.md).