unifig 0.1.0 → 0.2.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
  SHA256:
3
- metadata.gz: dbc1ebd81be5210930760f06ea0c36849862425a9f0831512efed9d4cc0a81a9
4
- data.tar.gz: 06c545484d1094f7a8d8609b48d077f602c689d0e505e01157e80d3adbedecb1
3
+ metadata.gz: 2daa78635ee2bccb9232401f2d8c26ad3845069ec0445ffbadf2657ac0ea85bd
4
+ data.tar.gz: 196d2431dc1025377ca12c5108dc6398c7c473b11d3daaf204dd3621a13cf4f7
5
5
  SHA512:
6
- metadata.gz: b6c024e5b3aefe1a2bba0da9908352a489263afa1d8deb047b9a0a54b29dfe621f23a71266bf12ae1a332c7a6d62a3871b596540e12f0a52a5ed62065b3be219
7
- data.tar.gz: 0ab9b4da14ee56d343dfbb95c6e73cdb81e924a8027686276c6c007bed49a017e0933a9023e644a4c8cd948d13c73b4963ef6d6b1bb9c6ec6ae2038120fa69f2
6
+ metadata.gz: 81359820cd6783317b0697ca4bac3161cd59650e76449d60a17e3b69eab1e5f46f7910643af53229859ebaa32886c9724728fbd490ddb7d76142593f1bae483a
7
+ data.tar.gz: d2f52f43b879df6941bcc790e22de92bc4ee75d5a0115b59b3b38454882481e525ff01847f09e009d6f3b0407fe66814426764981112a89d87b27996474b3cd5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
+ # [0.2.0][] (TBD)
2
+
3
+ - An environment is no longer required.
4
+
1
5
  # [0.1.0][] (2022-07-18)
2
6
 
3
7
  Initial release.
4
8
 
9
+ [0.2.0]: https://github.com/AaronLasseigne/unifig/compare/v0.1.0...v0.2.0
5
10
  [0.1.0]: https://github.com/AaronLasseigne/unifig/compare/v0.0.0...v0.1.0
data/CONTRIBUTING.md CHANGED
@@ -8,7 +8,7 @@ For features please open a [discussion][] and we can make sure the feature fits
8
8
  2. Add a breaking test for your change.
9
9
  3. Make the tests pass.
10
10
  4. Push your fork.
11
- 5. Submit a pull request.
11
+ 5. Submit a pull request against the `next` branch.
12
12
 
13
13
  ## Code Style
14
14
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # [Unifig][]
2
2
 
3
- Unifig lets you load external variables from one or more providers (e.g. local file, `ENV`).
3
+ Unifig is a pluggable system for loading external variables from one or more providers (e.g. `ENV`).
4
4
 
5
5
  [![Version](https://img.shields.io/gem/v/unifig.svg?style=flat-square)](https://rubygems.org/gems/unifig)
6
6
  [![Test](https://img.shields.io/github/workflow/status/AaronLasseigne/unifig/Test?label=Test&style=flat-square)](https://github.com/AaronLasseigne/unifig/actions?query=workflow%3ATest)
@@ -10,13 +10,13 @@ Unifig lets you load external variables from one or more providers (e.g. local f
10
10
  Add it to your Gemfile:
11
11
 
12
12
  ``` rb
13
- gem 'unifig', '~> 0.1.0'
13
+ gem 'unifig', '~> 0.2.0'
14
14
  ```
15
15
 
16
16
  Or install it manually:
17
17
 
18
18
  ``` sh
19
- $ gem install unifig --version '~> 0.1.0'
19
+ $ gem install unifig --version '~> 0.2.0'
20
20
  ```
21
21
 
22
22
  This project uses [Semantic Versioning][].
@@ -24,27 +24,56 @@ Check out [GitHub releases][] for a detailed list of changes.
24
24
 
25
25
  ## Usage
26
26
 
27
+ ### Basics
28
+
29
+ Unifig loads a [YAML configuration][] that instructs it on how to retrieve various external variables.
30
+ These variable values come from providers.
31
+ Unifig comes with a `local` provider which reads values straight from the configuration file.
32
+ Additional providers may be installed.
33
+
34
+ The most minimal configuration would be:
35
+
36
+ ```yml
37
+ config:
38
+ providers: local
39
+
40
+ HELLO:
41
+ value: "world"
42
+ ```
43
+
44
+ Given that configuration, Unifig will attach two new methods to the `Unifig` class.
45
+ From in your code you can call `Unifig.hello` to get the value of the variable and `Unifig.hello?` to see if the value was retrieved (for optional values).
46
+
47
+ Unifig also allows you to override the overall configuration or the individual configuration by using environments.
48
+ Here is an example where the `production` environment only pull from the `env` provider and in the `test` environment `Unifig.hello` will return `dlrow`:
49
+
50
+ ```yml
51
+ config:
52
+ providers: [local, env]
53
+ envs:
54
+ production:
55
+ providers: env
56
+
57
+ HELLO:
58
+ value: "world"
59
+ envs:
60
+ test:
61
+ value: "dlrow"
62
+ ```
63
+
27
64
  ### Loading
28
65
 
29
- Unifig loads a [YAML configuration][] which it uses to create methods allowing access to the variable values for a given environment.
30
- Loading is handled through the `Unifig::Init` class and methods are made available on the `Unifig` class.
66
+ Loading a configuration is handled through the `Unifig::Init` class.
31
67
  From `Unifig::Init` you can load the YAML as a string with `.load` or a file with `.load_file`.
32
68
 
33
- All variables are converted into two methods on the `Unifig` class.
34
- A predicate method shows whether the variable was provided and a regular method provides access to the value.
35
-
36
69
  All variables are assumed to be required (not `nil` or a blank string).
37
- They can be made optional using the `:optional` setting.
70
+ Variables can be made optional by using the `:optional` setting.
38
71
  If there is a required variable without a value, Unifig will throw an error when loading.
39
72
 
40
73
  ``` rb
41
- Unifig::Init.load(<<~YAML, :production)
74
+ Unifig::Init.load(<<~YAML, env: :production)
42
75
  config:
43
- envs:
44
- development:
45
- providers: local
46
- production:
47
- providers: local
76
+ providers: local
48
77
 
49
78
  HOST:
50
79
  value: github.com
@@ -81,17 +110,24 @@ If we replaced `:development` with `:production` inside the `load` call we'd get
81
110
  # => nil
82
111
  ```
83
112
 
113
+ You can load from a configuration file by using `load_file`.
114
+
115
+ ``` rb
116
+ Unifig::Init.load_file('unifig.yml', env: :production)
117
+ ```
118
+
84
119
  [API Documentation][]
85
120
 
86
121
  ### YAML Configuration
87
122
 
88
123
  The configuration YAML must contain a `config` key.
89
- Inside that all environments to be used must be listed under the `envs` key using the environment name.
90
- Each environment must list a provider or providers that are checked in order to find the value for each variable.
124
+ A list of one or more providers must be given.
125
+ They are are checked in order to find the value for each variable.
91
126
  Variables are then listed by name.
92
127
 
93
- The first level of settings apply to all environments.
128
+ The first level of configurations apply to all environments.
94
129
  These can be overridden by setting the `envs` key and a key with the name of then environment and then redefining any settings.
130
+ This is the case for the overall configuration as well as any variable configurations.
95
131
 
96
132
  ### Providers
97
133
 
data/lib/unifig/config.rb CHANGED
@@ -3,15 +3,15 @@
3
3
  module Unifig
4
4
  # @private
5
5
  class Config
6
- def initialize(config, env)
7
- @config = config
8
- @env = @config.dig(:envs, env)
9
- end
6
+ def initialize(config, env: nil)
7
+ @env_config = config.slice(:providers)
8
+ @env = env
10
9
 
11
- attr_reader :env
10
+ @env_config.merge!(config.dig(:envs, env) || {}) if @env
11
+ end
12
12
 
13
13
  def providers
14
- @providers ||= Array(env[:providers]).map(&:to_sym).freeze
14
+ @providers ||= Array(@env_config[:providers]).map(&:to_sym).freeze
15
15
  end
16
16
  end
17
17
  end
data/lib/unifig/init.rb CHANGED
@@ -8,7 +8,7 @@ module Unifig
8
8
  # Loads a string of YAML to configure Unifig.
9
9
  #
10
10
  # @example
11
- # Unifig::Init.load(<<~YML, :development)
11
+ # Unifig::Init.load(<<~YML, env: :development)
12
12
  # config:
13
13
  # envs:
14
14
  # development:
@@ -24,9 +24,9 @@ module Unifig
24
24
  # @raise [YAMLSyntaxError] - Invalid YAML
25
25
  # @raise (see #initialize)
26
26
  # @raise (see Unifig::Providers.list)
27
- def self.load(str, env)
27
+ def self.load(str, env: nil)
28
28
  yml = Psych.load(str, symbolize_names: true)
29
- new(yml, env).exec!
29
+ new(yml, env: env).exec!
30
30
  rescue Psych::SyntaxError, Psych::BadAlias => e
31
31
  raise YAMLSyntaxError, e.message
32
32
  end
@@ -34,29 +34,29 @@ module Unifig
34
34
  # Loads a YAML file to configure Unifig.
35
35
  #
36
36
  # @example
37
- # Unifig::Init.load_file('config.yml', :development)
37
+ # Unifig::Init.load_file('config.yml', env: :development)
38
38
  #
39
39
  # @param file_path [String] The path to a YAML config file.
40
40
  # @param env [Symbol] An environment name to load.
41
41
  #
42
42
  # @raise (see Unifig::Init.load)
43
- def self.load_file(file_path, env)
43
+ def self.load_file(file_path, env: nil)
44
44
  # Ruby 2.7 Psych.load_file doesn't support the :symbolize_names flag.
45
45
  # After Ruby 2.7 this can be changed to Psych.load_file if that's faster.
46
- load(File.read(file_path), env)
46
+ load(File.read(file_path), env: env)
47
47
  end
48
48
 
49
49
  # @private
50
50
  #
51
51
  # @raise [MissingConfig] - No config section was provided in the YAML.
52
- def initialize(yml, env)
52
+ def initialize(yml, env: nil)
53
53
  @yml = yml
54
54
  @env = env
55
55
 
56
56
  config = @yml.delete(:config)
57
57
  raise MissingConfig unless config
58
58
 
59
- @config = Config.new(config, @env)
59
+ @config = Config.new(config, env: @env)
60
60
  end
61
61
 
62
62
  # @private
@@ -2,11 +2,8 @@
2
2
 
3
3
  module Unifig
4
4
  module Providers
5
- # A provider to retrieve values from the unifig.yml file.
5
+ # @private
6
6
  module Local
7
- # Returns the name of the provider.
8
- #
9
- # @return [Symbol]
10
7
  def self.name
11
8
  :local
12
9
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Unifig
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -1,29 +1,29 @@
1
1
  RSpec.describe Unifig::Config do
2
- subject(:config) { described_class.new(config_hash, env) }
2
+ subject(:config) { described_class.new(config_hash, env: env) }
3
3
 
4
- let(:env) { :development }
5
- let(:env_config) do
6
- {
7
- providers: 'local'
8
- }
9
- end
4
+ let(:env) { nil }
10
5
  let(:config_hash) do
11
6
  {
7
+ providers: 'local',
12
8
  envs: {
13
- "#{env}": env_config
9
+ development: {
10
+ providers: %w[local forty_two]
11
+ }
14
12
  }
15
13
  }
16
14
  end
17
15
 
18
- describe '#env' do
19
- it 'returns the env config' do
20
- expect(config.env).to eql env_config
21
- end
22
- end
23
-
24
16
  describe '#providers' do
25
17
  it 'returns a list of providers for the selected env' do
26
18
  expect(config.providers).to eql %i[local]
27
19
  end
20
+
21
+ context 'with an :env' do
22
+ let(:env) { :development }
23
+
24
+ it 'returns the list of providers for that env' do
25
+ expect(config.providers).to eql %i[local forty_two]
26
+ end
27
+ end
28
28
  end
29
29
  end
@@ -20,8 +20,8 @@ RSpec.shared_examples 'basic load tests' do
20
20
  context 'without a config' do
21
21
  let(:str) do
22
22
  <<~YML
23
- FOO_BAR:
24
- value: "baz"
23
+ ONE:
24
+ value: 1
25
25
  YML
26
26
  end
27
27
 
@@ -34,20 +34,18 @@ RSpec.shared_examples 'basic load tests' do
34
34
  let(:str) do
35
35
  <<~YML
36
36
  config:
37
- envs:
38
- development:
39
- providers: local
37
+ providers: local
40
38
 
41
- FOO_BAR:
42
- value: baz
39
+ ONE:
40
+ value: 1
43
41
  YML
44
42
  end
45
43
 
46
44
  it 'loads up a string of yaml' do
47
45
  subject
48
46
 
49
- expect(Unifig).to respond_to(:foo_bar)
50
- expect(Unifig.foo_bar).to eql 'baz'
47
+ expect(Unifig).to respond_to(:one)
48
+ expect(Unifig.one).to be 1
51
49
  end
52
50
  end
53
51
  end
@@ -56,7 +54,7 @@ RSpec.describe Unifig::Init do
56
54
  let(:env) { :development }
57
55
 
58
56
  describe '.load' do
59
- subject(:load) { described_class.load(str, env) }
57
+ subject(:load) { described_class.load(str, env: env) }
60
58
 
61
59
  include_examples 'basic load tests'
62
60
 
@@ -64,21 +62,19 @@ RSpec.describe Unifig::Init do
64
62
  let(:str) do
65
63
  <<~YML
66
64
  config:
67
- envs:
68
- development:
69
- providers: [local, forty_two]
65
+ providers: [local, forty_two]
70
66
 
71
- FOO:
72
- BAR:
73
- value: bar
67
+ ONE:
68
+ TWO:
69
+ value: 2
74
70
  YML
75
71
  end
76
72
 
77
73
  it 'returns the values from the providers in order' do
78
74
  load
79
75
 
80
- expect(Unifig.foo).to be 42
81
- expect(Unifig.bar).to eql 'bar'
76
+ expect(Unifig.one).to be 42
77
+ expect(Unifig.two).to be 2
82
78
  end
83
79
  end
84
80
 
@@ -89,22 +85,20 @@ RSpec.describe Unifig::Init do
89
85
  let(:str) do
90
86
  <<~YML
91
87
  config:
92
- envs:
93
- development:
94
- providers: local
88
+ providers: local
95
89
 
96
- FOO_BAR:
90
+ ONE:
97
91
  optional: true
98
- value: baz
92
+ value: 1
99
93
  YML
100
94
  end
101
95
 
102
96
  it 'loads the var' do
103
- expect(Unifig.foo_bar).to eql 'baz'
97
+ expect(Unifig.one).to be 1
104
98
  end
105
99
 
106
100
  it 'sets the predicate to true' do
107
- expect(Unifig).to be_foo_bar
101
+ expect(Unifig).to be_one
108
102
  end
109
103
  end
110
104
 
@@ -112,21 +106,19 @@ RSpec.describe Unifig::Init do
112
106
  let(:str) do
113
107
  <<~YML
114
108
  config:
115
- envs:
116
- development:
117
- providers: local
109
+ providers: local
118
110
 
119
- FOO_BAR:
111
+ ONE:
120
112
  optional: true
121
113
  YML
122
114
  end
123
115
 
124
116
  it 'makes the var nil' do
125
- expect(Unifig.foo_bar).to be_nil
117
+ expect(Unifig.one).to be_nil
126
118
  end
127
119
 
128
120
  it 'sets the predicate to false' do
129
- expect(Unifig).to_not be_foo_bar
121
+ expect(Unifig).to_not be_one
130
122
  end
131
123
  end
132
124
 
@@ -134,22 +126,20 @@ RSpec.describe Unifig::Init do
134
126
  let(:str) do
135
127
  <<~YML
136
128
  config:
137
- envs:
138
- development:
139
- providers: local
129
+ providers: local
140
130
 
141
- FOO_BAR:
131
+ ONE:
142
132
  optional: true
143
133
  value: ' '
144
134
  YML
145
135
  end
146
136
 
147
137
  it 'makes the var nil' do
148
- expect(Unifig.foo_bar).to be_nil
138
+ expect(Unifig.one).to be_nil
149
139
  end
150
140
 
151
141
  it 'sets the predicate to false' do
152
- expect(Unifig).to_not be_foo_bar
142
+ expect(Unifig).to_not be_one
153
143
  end
154
144
  end
155
145
  end
@@ -161,21 +151,19 @@ RSpec.describe Unifig::Init do
161
151
  let(:str) do
162
152
  <<~YML
163
153
  config:
164
- envs:
165
- development:
166
- providers: local
154
+ providers: local
167
155
 
168
- FOO_BAR:
169
- value: baz
156
+ ONE:
157
+ value: 1
170
158
  YML
171
159
  end
172
160
 
173
161
  it 'loads the var' do
174
- expect(Unifig.foo_bar).to eql 'baz'
162
+ expect(Unifig.one).to be 1
175
163
  end
176
164
 
177
165
  it 'sets the predicate to true' do
178
- expect(Unifig).to be_foo_bar
166
+ expect(Unifig).to be_one
179
167
  end
180
168
  end
181
169
 
@@ -183,11 +171,9 @@ RSpec.describe Unifig::Init do
183
171
  let(:str) do
184
172
  <<~YML
185
173
  config:
186
- envs:
187
- development:
188
- providers: local
174
+ providers: local
189
175
 
190
- FOO_BAR:
176
+ ONE:
191
177
  value:
192
178
  YML
193
179
  end
@@ -201,11 +187,9 @@ RSpec.describe Unifig::Init do
201
187
  let(:str) do
202
188
  <<~YML
203
189
  config:
204
- envs:
205
- development:
206
- providers: local
190
+ providers: local
207
191
 
208
- FOO_BAR:
192
+ ONE:
209
193
  value: ' '
210
194
  YML
211
195
  end
@@ -218,7 +202,7 @@ RSpec.describe Unifig::Init do
218
202
  end
219
203
 
220
204
  describe '.load_file' do
221
- subject(:load_file) { described_class.load_file(file_path, env) }
205
+ subject(:load_file) { described_class.load_file(file_path, env: env) }
222
206
 
223
207
  let(:file) do
224
208
  Tempfile.new(%w[test .yml]).tap do |file|
metadata CHANGED
@@ -1,16 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unifig
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Lasseigne
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-18 00:00:00.000000000 Z
11
+ date: 2022-07-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: A way to load external variables from one or more sources (e.g. ENV).
13
+ description: A pluggable system for loading external variables from one or more providers
14
+ (e.g. ENV).
14
15
  email:
15
16
  - aaron.lasseigne@gmail.com
16
17
  executables: []
@@ -60,7 +61,8 @@ requirements: []
60
61
  rubygems_version: 3.3.7
61
62
  signing_key:
62
63
  specification_version: 4
63
- summary: A way to load external variables from one or more sources (e.g. ENV).
64
+ summary: A pluggable system for loading external variables from one or more providers
65
+ (e.g. ENV).
64
66
  test_files:
65
67
  - spec/spec_helper.rb
66
68
  - spec/unifig/config_spec.rb