superconfig 2.1.0 → 2.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: c9e0e414be8780a5a7815b5cdceb25a430f86363bf9120e42b1d3a55ca756f46
4
- data.tar.gz: 0a216ce70e1f2430517dec63f62efc22654c051898837e17979c3f91a6ebe565
3
+ metadata.gz: 38c1ba78820c0d5133c121b5b4157a94c0f49030ae4ae3ee700e231564d4bfc6
4
+ data.tar.gz: '014789c1819732d0b4e213d59189a5c958b60475ec06d71c3d25bdcc1c9bd0f9'
5
5
  SHA512:
6
- metadata.gz: aa41c22654cec2830fc13fed09ff67b1db897b554d56109da014ba15152801a599524c88fedb482e4780cad795494ec36f49e39fd4e5b8d3d59e867418fc01a3
7
- data.tar.gz: 2967f86046040444020ef8f04b8fe0161d1f27bf748b8c3c1ac464ebae342031ab1b5562c0194c1d780c4e13f19747c3b7ec2b5a6ae1ff1035d592adbeb2591d
6
+ metadata.gz: 43da8d2e33cdbcc32bc1c53d89bec045049500a6dca584d86eb8ce51fa6a14db3104b955d17cab3a5a3f493e831da923226a05399a07b6438ddf93cd3da52e21
7
+ data.tar.gz: 57723e9ac840ddf395a63496836770f4905ee4a2747f77fb72a19b49c8e81a51e1dffd9cff4ec2b99376caf94789d46c7a0a4e0f1750abe60d93b87241ac6b8f
@@ -19,14 +19,14 @@ jobs:
19
19
  strategy:
20
20
  fail-fast: false
21
21
  matrix:
22
- ruby: ["2.7", "3.0", "3.1"]
22
+ ruby: ["3.1", "3.2", "3.3"]
23
23
  gemfile:
24
24
  - Gemfile
25
25
 
26
26
  steps:
27
- - uses: actions/checkout@v2.4.0
27
+ - uses: actions/checkout@v4
28
28
 
29
- - uses: actions/cache@v2
29
+ - uses: actions/cache@v4
30
30
  with:
31
31
  path: vendor/bundle
32
32
  key: >
data/.rubocop.yml CHANGED
@@ -3,7 +3,7 @@ inherit_gem:
3
3
  rubocop-fnando: .rubocop.yml
4
4
 
5
5
  AllCops:
6
- TargetRubyVersion: 2.7
6
+ TargetRubyVersion: 3.1
7
7
  NewCops: enable
8
8
  Exclude:
9
9
  - vendor/**/*
data/CHANGELOG.md CHANGED
@@ -11,6 +11,14 @@ Prefix your message with one of the following:
11
11
  - [Security] in case of vulnerabilities.
12
12
  -->
13
13
 
14
- ## Unreleased
14
+ # Unreleased
15
+
16
+ - [Added] `SuperConfig#set(key, value)` method to set arbitrary values.
17
+
18
+ ## v2.1.1
19
+
20
+ - [Changed] Ensure bad JSON strings doesn't leak it's contents.
21
+
22
+ ## v2.0.0
15
23
 
16
24
  - Initial release.
data/README.md CHANGED
@@ -73,6 +73,14 @@ Config = SuperConfig.new do
73
73
  end
74
74
  ```
75
75
 
76
+ You can also set values using `SuperConfig#set`.
77
+
78
+ ```ruby
79
+ Config = SuperConfig.new do
80
+ set :domain, "example.com"
81
+ end
82
+ ```
83
+
76
84
  You may want to start a debug session without raising exceptions for missing
77
85
  variables. In this case, just pass `raise_exception: false` instead to log error
78
86
  messages to `$stderr`. This is especially great with Rails' credentials command
data/lib/superconfig.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SuperConfig
4
- VERSION = "2.1.0"
4
+ VERSION = "2.2.0"
5
5
 
6
6
  MissingEnvironmentVariable = Class.new(StandardError)
7
7
  MissingCallable = Class.new(StandardError)
8
8
 
9
- def self.new(**kwargs, &block)
10
- Base.new(**kwargs, &block)
9
+ def self.new(...)
10
+ Base.new(...)
11
11
  end
12
12
 
13
13
  class Base
@@ -28,34 +28,6 @@ module SuperConfig
28
28
  end
29
29
  alias inspect to_s
30
30
 
31
- def set(
32
- name,
33
- type,
34
- default = nil,
35
- required: false,
36
- aliases: [],
37
- description: nil
38
- )
39
- name = name.to_s
40
- env_var = name.upcase
41
-
42
- @attributes[env_var] = {required: required, default: default}
43
-
44
- name = "#{name}?" if type == bool
45
-
46
- validate!(env_var, required, description)
47
-
48
- define_singleton_method(name) do
49
- return default unless @env.key?(env_var)
50
-
51
- coerce(type, @env[env_var])
52
- end
53
-
54
- aliases.each do |alias_name|
55
- define_singleton_method(alias_name, method(name))
56
- end
57
- end
58
-
59
31
  def validate!(env_var, required, description)
60
32
  return unless required
61
33
  return if @env.key?(env_var)
@@ -72,21 +44,25 @@ module SuperConfig
72
44
  end
73
45
 
74
46
  def mandatory(name, type, aliases: [], description: nil)
75
- set(
47
+ assign(
76
48
  name,
77
49
  type,
78
50
  required: true,
79
- aliases: aliases,
80
- description: description
51
+ aliases:,
52
+ description:
81
53
  )
82
54
  end
83
55
 
84
56
  def optional(name, type, default = nil, aliases: [], description: nil)
85
- set(name, type, default, aliases: aliases, description: description)
57
+ assign(name, type, default, aliases:, description:)
58
+ end
59
+
60
+ def set(name, value)
61
+ property(name) { value }
86
62
  end
87
63
 
88
64
  def property(name, func = nil, cache: true, description: nil, &block) # rubocop:disable Lint/UnusedMethodArgument
89
- callable = (func || block)
65
+ callable = func || block
90
66
 
91
67
  unless callable
92
68
  raise MissingCallable, "arg[1] must respond to #call or pass a block"
@@ -103,7 +79,7 @@ module SuperConfig
103
79
 
104
80
  def credential(name, &block)
105
81
  define_singleton_method(name) do
106
- @__cache__["_credential_#{name}".to_sym] ||= begin
82
+ @__cache__[:"_credential_#{name}"] ||= begin
107
83
  value = Rails.application.credentials.fetch(name)
108
84
  block ? block.call(value) : value # rubocop:disable Performance/RedundantBlockCall
109
85
  end
@@ -169,44 +145,74 @@ module SuperConfig
169
145
  "#{report.join("\n")}\n"
170
146
  end
171
147
 
172
- private def coerce_to_string(value)
148
+ private def coerce_to_string(_name, value)
173
149
  value
174
150
  end
175
151
 
176
- private def coerce_to_bool(value)
152
+ private def coerce_to_bool(_name, value)
177
153
  BOOL_TRUE.include?(value)
178
154
  end
179
155
 
180
- private def coerce_to_int(value)
156
+ private def coerce_to_int(_name, value)
181
157
  Integer(value) if !BOOL_FALSE.include?(value) && value
182
158
  end
183
159
 
184
- private def coerce_to_float(value)
160
+ private def coerce_to_float(_name, value)
185
161
  Float(value) if value
186
162
  end
187
163
 
188
- private def coerce_to_bigdecimal(value)
164
+ private def coerce_to_bigdecimal(_name, value)
189
165
  BigDecimal(value) if value
190
166
  end
191
167
 
192
- private def coerce_to_symbol(value)
168
+ private def coerce_to_symbol(_name, value)
193
169
  value&.to_sym
194
170
  end
195
171
 
196
- private def coerce_to_array(value, type)
197
- value&.split(/, */)&.map {|v| coerce(type, v) }
172
+ private def coerce_to_array(name, value, type)
173
+ value&.split(/, */)&.map {|v| coerce(name, type, v) }
198
174
  end
199
175
 
200
- private def coerce_to_json(value)
176
+ private def coerce_to_json(name, value)
201
177
  value && JSON.parse(value)
178
+ rescue JSON::ParserError
179
+ raise ArgumentError, "#{name} is not a valid JSON string"
202
180
  end
203
181
 
204
- private def coerce(type, value)
182
+ private def coerce(name, type, value)
205
183
  main_type, sub_type = type
206
- args = [value]
184
+ args = [name, value]
207
185
  args << sub_type if sub_type
208
186
 
209
- send("coerce_to_#{main_type}", *args)
187
+ send(:"coerce_to_#{main_type}", *args)
188
+ end
189
+
190
+ private def assign(
191
+ name,
192
+ type,
193
+ default = nil,
194
+ required: false,
195
+ aliases: [],
196
+ description: nil
197
+ )
198
+ name = name.to_s
199
+ env_var = name.upcase
200
+
201
+ @attributes[env_var] = {required:, default:}
202
+
203
+ name = "#{name}?" if type == bool
204
+
205
+ validate!(env_var, required, description)
206
+
207
+ define_singleton_method(name) do
208
+ return default unless @env.key?(env_var)
209
+
210
+ coerce(env_var, type, @env[env_var])
211
+ end
212
+
213
+ aliases.each do |alias_name|
214
+ define_singleton_method(alias_name, method(name))
215
+ end
210
216
  end
211
217
  end
212
218
  end
data/superconfig.gemspec CHANGED
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "./lib/superconfig"
3
+ require_relative "lib/superconfig"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "superconfig"
7
7
  spec.version = SuperConfig::VERSION
8
8
  spec.authors = ["Nando Vieira"]
9
9
  spec.email = ["me@fnando.com"]
10
- spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
10
+ spec.required_ruby_version = Gem::Requirement.new(">= 3.1.0")
11
11
  spec.metadata = {"rubygems_mfa_required" => "true"}
12
12
 
13
13
  spec.summary = "Access environment variables. Also includes presence " \
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: superconfig
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2022-01-16 00:00:00.000000000 Z
10
+ date: 2025-02-10 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: bundler
@@ -169,7 +168,6 @@ licenses:
169
168
  - MIT
170
169
  metadata:
171
170
  rubygems_mfa_required: 'true'
172
- post_install_message:
173
171
  rdoc_options: []
174
172
  require_paths:
175
173
  - lib
@@ -177,15 +175,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
177
175
  requirements:
178
176
  - - ">="
179
177
  - !ruby/object:Gem::Version
180
- version: 2.7.0
178
+ version: 3.1.0
181
179
  required_rubygems_version: !ruby/object:Gem::Requirement
182
180
  requirements:
183
181
  - - ">="
184
182
  - !ruby/object:Gem::Version
185
183
  version: '0'
186
184
  requirements: []
187
- rubygems_version: 3.3.3
188
- signing_key:
185
+ rubygems_version: 3.6.2
189
186
  specification_version: 4
190
187
  summary: Access environment variables. Also includes presence validation, type coercion
191
188
  and default values.