anyway_config 1.4.4 → 2.0.0.pre
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 +4 -4
- data/README.md +187 -51
- data/lib/anyway.rb +22 -2
- data/lib/anyway/config.rb +116 -98
- data/lib/anyway/dynamic_config.rb +27 -0
- data/lib/anyway/env.rb +2 -5
- data/lib/anyway/ext/deep_dup.rb +4 -4
- data/lib/anyway/ext/deep_freeze.rb +5 -0
- data/lib/anyway/ext/jruby.rb +9 -4
- data/lib/anyway/ext/string_serialize.rb +1 -7
- data/{spec/dummy/config.ru → lib/anyway/loaders/env_loader.rb} +0 -0
- data/lib/anyway/loaders/secrets_loader.rb +0 -0
- data/lib/anyway/loaders/yaml_loader.rb +0 -0
- data/lib/anyway/option_parser_builder.rb +2 -2
- data/lib/anyway/optparse_config.rb +90 -0
- data/lib/anyway/rails/config.rb +76 -24
- data/lib/anyway/railtie.rb +11 -0
- data/lib/anyway/testing.rb +13 -0
- data/lib/anyway/testing/helpers.rb +36 -0
- data/lib/anyway/version.rb +1 -1
- metadata +46 -48
- data/.gem_release.yml +0 -3
- data/.gitignore +0 -40
- data/.rubocop.yml +0 -50
- data/.travis.yml +0 -30
- data/CHANGELOG.md +0 -112
- data/Gemfile +0 -21
- data/Rakefile +0 -23
- data/anyway_config.gemspec +0 -29
- data/config/cool.yml +0 -5
- data/gemfiles/jruby.gemfile +0 -7
- data/gemfiles/rails42.gemfile +0 -6
- data/gemfiles/rails5.gemfile +0 -6
- data/gemfiles/railsmaster.gemfile +0 -7
- data/spec/anyway.yml +0 -2
- data/spec/config_spec.rb +0 -337
- data/spec/config_spec_norails.rb +0 -86
- data/spec/dummy/config/application.rb +0 -13
- data/spec/dummy/config/boot.rb +0 -5
- data/spec/dummy/config/cool.yml +0 -5
- data/spec/dummy/config/cool_custom.yml +0 -2
- data/spec/dummy/config/database.yml +0 -25
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/test.rb +0 -2
- data/spec/dummy/config/routes.rb +0 -2
- data/spec/dummy/config/secrets.yml +0 -30
- data/spec/env_spec.rb +0 -50
- data/spec/ext/deep_dup_spec.rb +0 -38
- data/spec/ext/deep_freeze_spec.rb +0 -32
- data/spec/ext/hash_spec.rb +0 -39
- data/spec/ext/string_serialize_spec.rb +0 -32
- data/spec/spec_helper.rb +0 -31
- data/spec/spec_norails_helper.rb +0 -26
- data/spec/support/cool_config.rb +0 -10
- data/spec/support/print_warning_matcher.rb +0 -34
- data/spec/support/small_config.rb +0 -7
- data/spec/support/test_config.rb +0 -16
data/anyway_config.gemspec
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
lib = File.expand_path('../lib', __FILE__)
|
4
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
-
require 'anyway/version'
|
6
|
-
|
7
|
-
Gem::Specification.new do |s|
|
8
|
-
s.name = "anyway_config"
|
9
|
-
s.version = Anyway::VERSION
|
10
|
-
s.authors = ["Vladimir Dementyev"]
|
11
|
-
s.email = ["dementiev.vm@gmail.com"]
|
12
|
-
s.homepage = "http://github.com/palkan/anyway_config"
|
13
|
-
s.summary = "Configuration DSL for Ruby libraries and applications"
|
14
|
-
s.description = %{
|
15
|
-
Configuration DSL for Ruby libraries and applications.
|
16
|
-
Allows you to easily follow the twelve-factor application principles (https://12factor.net/config).
|
17
|
-
}
|
18
|
-
|
19
|
-
s.license = "MIT"
|
20
|
-
|
21
|
-
s.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
22
|
-
s.require_paths = ["lib"]
|
23
|
-
s.required_ruby_version = '>= 2.3'
|
24
|
-
|
25
|
-
s.add_development_dependency "bundler", ">= 1.15"
|
26
|
-
s.add_development_dependency "rspec", "~> 3.5"
|
27
|
-
s.add_development_dependency "rubocop", "~> 0.60.0"
|
28
|
-
s.add_development_dependency "simplecov", ">= 0.3.8"
|
29
|
-
end
|
data/config/cool.yml
DELETED
data/gemfiles/jruby.gemfile
DELETED
data/gemfiles/rails42.gemfile
DELETED
data/gemfiles/rails5.gemfile
DELETED
data/spec/anyway.yml
DELETED
data/spec/config_spec.rb
DELETED
@@ -1,337 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe Anyway::Config do
|
6
|
-
let(:conf) { CoolConfig.new }
|
7
|
-
let(:test_conf) { Anyway::TestConfig.new }
|
8
|
-
|
9
|
-
context "config with name" do
|
10
|
-
before(:each) do
|
11
|
-
ENV.delete_if { |var| var =~ /^(cool|anyway)_/i }
|
12
|
-
end
|
13
|
-
|
14
|
-
specify { expect(CoolConfig.config_name).to eq "cool" }
|
15
|
-
|
16
|
-
describe "defaults" do
|
17
|
-
specify { expect(CoolConfig.defaults[:port]).to eq 8080 }
|
18
|
-
specify { expect(CoolConfig.defaults[:host]).to eq 'localhost' }
|
19
|
-
end
|
20
|
-
|
21
|
-
it "generates accessors", :aggregate_failures do
|
22
|
-
expect(conf).to respond_to(:meta)
|
23
|
-
expect(conf).to respond_to(:data)
|
24
|
-
expect(conf).to respond_to(:port)
|
25
|
-
expect(conf).to respond_to(:host)
|
26
|
-
expect(conf).to respond_to(:user)
|
27
|
-
end
|
28
|
-
|
29
|
-
describe "#to_h" do
|
30
|
-
subject(:config) { CoolConfig.new }
|
31
|
-
|
32
|
-
it "returns deeply frozen hash" do
|
33
|
-
hashed = config.to_h
|
34
|
-
|
35
|
-
expect(hashed).to be_a(Hash)
|
36
|
-
expect(hashed).to be_frozen
|
37
|
-
expect(hashed[:user]).to be_frozen
|
38
|
-
end
|
39
|
-
|
40
|
-
it "returns new hash every time" do
|
41
|
-
hashed = config.to_h
|
42
|
-
hashed2 = config.to_h
|
43
|
-
|
44
|
-
expect(hashed).to be_eql(hashed2)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
describe "load from files" do
|
49
|
-
it "set defaults" do
|
50
|
-
expect(conf.port).to eq 8080
|
51
|
-
end
|
52
|
-
|
53
|
-
it "load config from YAML" do
|
54
|
-
expect(conf.host).to eq "test.host"
|
55
|
-
end
|
56
|
-
|
57
|
-
it "sets overrides after loading YAML" do
|
58
|
-
config = CoolConfig.new(overrides: { host: 'overrided.host' })
|
59
|
-
expect(config.host).to eq "overrided.host"
|
60
|
-
end
|
61
|
-
|
62
|
-
if Rails.application.respond_to?(:secrets)
|
63
|
-
it "load config from secrets" do
|
64
|
-
expect(conf.user[:name]).to eq "test"
|
65
|
-
end
|
66
|
-
else
|
67
|
-
it "load config from file if no secrets" do
|
68
|
-
expect(conf.user[:name]).to eq "root"
|
69
|
-
expect(conf.user[:password]).to eq "root"
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
context "with overiden path" do
|
74
|
-
it "reads custom config path" do
|
75
|
-
ENV['COOL_CONF'] = Rails.root.join("config", "cool_custom.yml").to_s
|
76
|
-
expect(conf.host).to eq "custom.host"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
describe "load from env" do
|
82
|
-
context "when env_prefix is not specified" do
|
83
|
-
it "uses config_name as a prefix to load variables" do
|
84
|
-
ENV['COOL_PORT'] = '80'
|
85
|
-
ENV['COOL_USER__NAME'] = 'john'
|
86
|
-
Anyway.env.clear
|
87
|
-
expect(conf.port).to eq 80
|
88
|
-
expect(conf.user[:name]).to eq 'john'
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context "when env_prefix is specified" do
|
93
|
-
let(:conf) do
|
94
|
-
klass = CoolConfig.dup
|
95
|
-
klass.class_eval { env_prefix(:cool_env) }
|
96
|
-
klass.new
|
97
|
-
end
|
98
|
-
|
99
|
-
it "uses env_prefix value as a prefix to load variables" do
|
100
|
-
ENV['COOL_PORT'] = '80'
|
101
|
-
ENV['COOL_ENV_PORT'] = '8888'
|
102
|
-
ENV['COOL_USER__NAME'] = 'john'
|
103
|
-
ENV['COOL_ENV_USER__NAME'] = 'bill'
|
104
|
-
Anyway.env.clear
|
105
|
-
expect(conf.port).to eq 8888
|
106
|
-
expect(conf.user[:name]).to eq 'bill'
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
context "when config_name contains underscores" do
|
111
|
-
let(:conf) do
|
112
|
-
klass = CoolConfig.dup
|
113
|
-
klass.class_eval do
|
114
|
-
config_name :cool_thing
|
115
|
-
end
|
116
|
-
klass.new
|
117
|
-
end
|
118
|
-
|
119
|
-
context "when env_name is set" do
|
120
|
-
let(:conf) do
|
121
|
-
klass = CoolConfig.dup
|
122
|
-
klass.class_eval do
|
123
|
-
config_name :cool_thing
|
124
|
-
env_prefix :cool_thing
|
125
|
-
end
|
126
|
-
klass.new
|
127
|
-
end
|
128
|
-
|
129
|
-
it "doesn't print deprecation warning" do
|
130
|
-
expect { conf }.not_to print_warning
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
it "handle ENV in YML thru ERB" do
|
136
|
-
ENV['ANYWAY_SECRET_PASSWORD'] = 'my_pass'
|
137
|
-
expect(conf.user[:password]).to eq 'my_pass'
|
138
|
-
end
|
139
|
-
|
140
|
-
it "overrides loaded value by explicit" do
|
141
|
-
ENV['ANYWAY_SECRET_PASSWORD'] = 'my_pass'
|
142
|
-
|
143
|
-
config = CoolConfig.new(
|
144
|
-
overrides: {
|
145
|
-
user: { password: 'explicit_password' }
|
146
|
-
}
|
147
|
-
)
|
148
|
-
expect(config.user[:password]).to eq "explicit_password"
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
describe "clear" do
|
153
|
-
let(:conf_cleared) { conf.clear }
|
154
|
-
|
155
|
-
it "nullifies values", :aggregate_failures do
|
156
|
-
expect(conf_cleared.meta).to be_nil
|
157
|
-
expect(conf_cleared.data).to be_nil
|
158
|
-
expect(conf_cleared.host).to be_nil
|
159
|
-
expect(conf_cleared.user).to be_nil
|
160
|
-
expect(conf_cleared.port).to be_nil
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
describe "reload" do
|
165
|
-
it do
|
166
|
-
expect(conf.port).to eq 8080
|
167
|
-
ENV['COOL_PORT'] = '80'
|
168
|
-
ENV['COOL_USER__NAME'] = 'john'
|
169
|
-
Anyway.env.clear
|
170
|
-
conf.reload
|
171
|
-
expect(conf.port).to eq 80
|
172
|
-
expect(conf.user[:name]).to eq 'john'
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
context "config for name" do
|
178
|
-
before(:each) do
|
179
|
-
ENV.delete_if { |var| var =~ /^myapp_/i }
|
180
|
-
end
|
181
|
-
|
182
|
-
it "load data by config name", :aggregate_failures do
|
183
|
-
ENV['MY_APP_TEST'] = '1'
|
184
|
-
ENV['MY_APP_NAME'] = 'my_app'
|
185
|
-
Anyway.env.clear
|
186
|
-
data = Anyway::Config.for(:my_app)
|
187
|
-
expect(data[:test]).to eq 1
|
188
|
-
expect(data[:name]).to eq 'my_app'
|
189
|
-
expect(data[:secret]).to eq 'my_secret' if Rails.application.respond_to?(:secrets)
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
context "config without defaults" do
|
194
|
-
let(:conf) { SmallConfig.new }
|
195
|
-
|
196
|
-
it "works" do
|
197
|
-
expect(conf.meta).to be_nil
|
198
|
-
expect(conf.data).to be_nil
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
context "config with initial hash values" do
|
203
|
-
let(:conf) { SmallConfig.new(overrides: { 'meta': 'dummy' }) }
|
204
|
-
|
205
|
-
it "works" do
|
206
|
-
expect(conf.meta).to eq 'dummy'
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
context "when name is missing" do
|
211
|
-
let(:config) do
|
212
|
-
Class.new(described_class)
|
213
|
-
end
|
214
|
-
|
215
|
-
it "raises ArgumentError" do
|
216
|
-
expect { config.new }.to raise_error(ArgumentError)
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
context "extending config" do
|
221
|
-
let(:config) do
|
222
|
-
Class.new(described_class) do
|
223
|
-
config_name 'testo'
|
224
|
-
attr_config :test, debug: false
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
it "adds new params" do
|
229
|
-
old_config = config.new
|
230
|
-
|
231
|
-
expect(old_config.debug).to eq false
|
232
|
-
expect(old_config.test).to be_nil
|
233
|
-
|
234
|
-
config.attr_config new_param: 'a'
|
235
|
-
|
236
|
-
new_config = config.new
|
237
|
-
expect(new_config.debug).to eq false
|
238
|
-
expect(new_config.test).to be_nil
|
239
|
-
expect(new_config.new_param).to eq 'a'
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
describe "#parse_options!" do
|
244
|
-
let(:config_instance) { config.new }
|
245
|
-
|
246
|
-
context "when `ignore_options` is not provided" do
|
247
|
-
let(:config) do
|
248
|
-
Class.new(described_class) do
|
249
|
-
config_name 'optparse'
|
250
|
-
attr_config :host, :port, :log_level, :debug
|
251
|
-
flag_options :debug
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
it "parses ARGC string" do
|
256
|
-
config_instance.parse_options!(%w[--host localhost --port 3333 --log-level debug --debug])
|
257
|
-
expect(config_instance.host).to eq("localhost")
|
258
|
-
expect(config_instance.port).to eq(3333)
|
259
|
-
expect(config_instance.log_level).to eq("debug")
|
260
|
-
expect(config_instance.debug).to eq(true)
|
261
|
-
end
|
262
|
-
end
|
263
|
-
|
264
|
-
context 'when `ignore_options` is provided' do
|
265
|
-
let(:config) do
|
266
|
-
Class.new(described_class) do
|
267
|
-
config_name 'optparse'
|
268
|
-
attr_config :host, :log_level, :concurrency, server_args: {}
|
269
|
-
|
270
|
-
ignore_options :server_args
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
it "parses ARGC string" do
|
275
|
-
expect do
|
276
|
-
config_instance.parse_options!(
|
277
|
-
%w[--host localhost --concurrency 10 --log-level debug --server-args SOME_ARGS]
|
278
|
-
)
|
279
|
-
end.to raise_error(OptionParser::InvalidOption, /--server-args/)
|
280
|
-
|
281
|
-
expect(config_instance.host).to eq("localhost")
|
282
|
-
expect(config_instance.concurrency).to eq(10)
|
283
|
-
expect(config_instance.log_level).to eq("debug")
|
284
|
-
expect(config_instance.server_args).to eq({})
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
context 'when `describe_options` is provided' do
|
289
|
-
let(:config) do
|
290
|
-
Class.new(described_class) do
|
291
|
-
config_name 'optparse'
|
292
|
-
attr_config :host, :log_level, :concurrency, server_args: {}
|
293
|
-
|
294
|
-
describe_options(
|
295
|
-
concurrency: "number of threads to use"
|
296
|
-
)
|
297
|
-
end
|
298
|
-
end
|
299
|
-
|
300
|
-
it "contains options description" do
|
301
|
-
expect(config_instance.option_parser.help).to include("number of threads to use")
|
302
|
-
end
|
303
|
-
end
|
304
|
-
|
305
|
-
context "customization of option parser" do
|
306
|
-
let(:config) do
|
307
|
-
Class.new(described_class) do
|
308
|
-
config_name 'optparse'
|
309
|
-
attr_config :host, :log_level, :concurrency, server_args: {}
|
310
|
-
|
311
|
-
extend_options do |parser, config|
|
312
|
-
parser.banner = "mycli [options]"
|
313
|
-
|
314
|
-
parser.on("--server-args VALUE") do |value|
|
315
|
-
config.server_args = JSON.parse(value)
|
316
|
-
end
|
317
|
-
|
318
|
-
parser.on_tail "-h", "--help" do
|
319
|
-
puts parser
|
320
|
-
end
|
321
|
-
end
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
it "allows to customize the parser" do
|
326
|
-
expect(config_instance.option_parser.help).to include("mycli [options]")
|
327
|
-
end
|
328
|
-
|
329
|
-
it "passes config to extension" do
|
330
|
-
config_instance.parse_options!(
|
331
|
-
['--server-args', '{"host":"0.0.0.0"}']
|
332
|
-
)
|
333
|
-
expect(config_instance.server_args["host"]).to eq "0.0.0.0"
|
334
|
-
end
|
335
|
-
end
|
336
|
-
end
|
337
|
-
end
|
data/spec/config_spec_norails.rb
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'spec_norails_helper'
|
4
|
-
|
5
|
-
describe Anyway::Config do
|
6
|
-
let(:conf) { Anyway::TestConfig.new }
|
7
|
-
|
8
|
-
describe "config without Rails" do
|
9
|
-
before(:each) do
|
10
|
-
ENV.delete_if { |var| var =~ /^anyway_/i }
|
11
|
-
end
|
12
|
-
|
13
|
-
specify { expect(Anyway::TestConfig.config_name).to eq "anyway" }
|
14
|
-
|
15
|
-
it "has getters", :aggregate_failures do
|
16
|
-
expect(conf).to respond_to(:test)
|
17
|
-
expect(conf).to respond_to(:api)
|
18
|
-
expect(conf).to respond_to(:log)
|
19
|
-
expect(conf).to respond_to(:log_levels)
|
20
|
-
end
|
21
|
-
|
22
|
-
it "works", :aggregate_failures do
|
23
|
-
ENV['ANYWAY_CONF'] = File.join(File.dirname(__FILE__), "anyway.yml")
|
24
|
-
ENV['ANYWAY_API__KEY'] = 'test1'
|
25
|
-
ENV['ANYWAY_TEST'] = 'test'
|
26
|
-
ENV['ANYWAY_LOG__FORMAT__COLOR'] = 't'
|
27
|
-
ENV['ANYWAY_LOG_LEVELS'] = 'debug,warning,info'
|
28
|
-
|
29
|
-
Anyway.env.clear
|
30
|
-
expect(conf.api['key']).to eq "test1"
|
31
|
-
expect(conf.api['endpoint']).to eq "localhost"
|
32
|
-
expect(conf.test).to eq "test"
|
33
|
-
expect(conf.log['format']['color']).to eq true
|
34
|
-
expect(conf.log_levels).to eq(%w[debug warning info])
|
35
|
-
end
|
36
|
-
|
37
|
-
it "reloads config", :aggregate_failures do
|
38
|
-
ENV['ANYWAY_CONF'] = File.join(File.dirname(__FILE__), "anyway.yml")
|
39
|
-
|
40
|
-
expect(conf.api['key']).to eq ""
|
41
|
-
expect(conf.api['endpoint']).to eq 'localhost'
|
42
|
-
expect(conf.test).to be_nil
|
43
|
-
expect(conf.log['format']['color']).to eq false
|
44
|
-
|
45
|
-
ENV['ANYWAY_API__KEY'] = 'test1'
|
46
|
-
ENV['ANYWAY_API__SSL'] = 'yes'
|
47
|
-
ENV['ANYWAY_TEST'] = 'test'
|
48
|
-
ENV['ANYWAY_LOG__FORMAT__COLOR'] = 't'
|
49
|
-
Anyway.env.clear
|
50
|
-
|
51
|
-
conf.reload
|
52
|
-
expect(conf.api['key']).to eq "test1"
|
53
|
-
expect(conf.api['ssl']).to eq true
|
54
|
-
expect(conf.api['endpoint']).to eq "localhost"
|
55
|
-
expect(conf.test).to eq "test"
|
56
|
-
expect(conf.log['format']['color']).to eq true
|
57
|
-
end
|
58
|
-
|
59
|
-
context "config without keys" do
|
60
|
-
let(:empty_config_class) { Class.new(Anyway::Config) }
|
61
|
-
|
62
|
-
let(:conf) { empty_config_class.new }
|
63
|
-
|
64
|
-
specify { expect { conf.config_name }.to raise_error(ArgumentError) }
|
65
|
-
end
|
66
|
-
|
67
|
-
context "loading from default path" do
|
68
|
-
let(:conf) { CoolConfig.new }
|
69
|
-
|
70
|
-
before(:each) do
|
71
|
-
ENV.delete_if { |var| var =~ /^cool_/i }
|
72
|
-
end
|
73
|
-
|
74
|
-
it "loads from ./config", :aggregate_failures do
|
75
|
-
expect(conf.user).to eq("name" => "root", "password" => "root")
|
76
|
-
expect(conf.host).to eq "test.host"
|
77
|
-
expect(conf.port).to eq 9292
|
78
|
-
end
|
79
|
-
|
80
|
-
it "handle ENV in YML thru ERB" do
|
81
|
-
ENV["ANYWAY_COOL_PORT"] = "1957"
|
82
|
-
expect(conf.port).to eq 1957
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|