superconfig 1.0.0 → 2.0.1

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
  SHA256:
3
- metadata.gz: 75ba7c940329c14aed30b1442f6e78b50286adbd42ccc0f1110d8923ee2b8ef3
4
- data.tar.gz: 39430ed39dbc947935dee8705b52e52179f480867008f25b02f664fe47019581
3
+ metadata.gz: fbd7451e326a63df725764a9e0b29dec045b330b499eefefe40437808e0049b0
4
+ data.tar.gz: bfa6173594fe005b5a379e3208aaa2df3495ce9abbd25a25d443c8df282a97c9
5
5
  SHA512:
6
- metadata.gz: cb45a0fabec9816865b7635fa3bba29bd879f3b55997fa2dedb4703c3e7440774cb3e1c5d07421389fbdc04b27147954317ceabdc70b9695154aaee336d0b1f6
7
- data.tar.gz: d19ec7430c5780af73cf2d7d8f51608dbff7f4f3f40cb7eb7923769af2ddf6f4352428d044002a0cd4df2eb0290e42d3a86cbd6ba3b11fef596e98e6d54565a2
6
+ metadata.gz: e02df280e20253019f4f5d1e2c36df847c48e7057976371b6dd03ad19b873c42c9d2eba90d11a48a4e8cdd7059a7c488e6a986711ebe771d9380f115b96ebc01
7
+ data.tar.gz: 9151d646da85061a80cad78aa9ea58391319550e5d72afcf8a7793ebd40ed6f37f0af22932de46f309009fe14c8e6e597e07535a4ee3d2d377b2e983d94fef01
@@ -2,8 +2,10 @@
2
2
  name: ruby-tests
3
3
 
4
4
  on:
5
- pull_request:
5
+ pull_request_target:
6
6
  push:
7
+ branches:
8
+ - main
7
9
  workflow_dispatch:
8
10
  inputs: {}
9
11
 
@@ -11,23 +13,28 @@ jobs:
11
13
  build:
12
14
  name: Tests with Ruby ${{ matrix.ruby }} and ${{ matrix.gemfile }}
13
15
  runs-on: "ubuntu-latest"
16
+ if: |
17
+ github.actor == 'dependabot[bot]' && github.event_name == 'pull_request_target' ||
18
+ github.actor != 'dependabot[bot]'
14
19
  strategy:
15
20
  fail-fast: false
16
21
  matrix:
17
- ruby: ["2.7", "3.0"]
22
+ ruby: ["2.7", "3.0", "3.1"]
18
23
  gemfile:
19
24
  - Gemfile
20
25
 
21
26
  steps:
22
- - uses: actions/checkout@v1
27
+ - uses: actions/checkout@v3
23
28
 
24
- - uses: actions/cache@v2
29
+ - uses: actions/cache@v3
25
30
  with:
26
31
  path: vendor/bundle
27
32
  key: >
28
- ${{ runner.os }}-${{ matrix.ruby }}-gems-${{ hashFiles(matrix.gemfile) }}
33
+ ${{ runner.os }}-${{ matrix.ruby }}-gems-${{
34
+ hashFiles(matrix.gemfile) }}
29
35
  restore-keys: >
30
- ${{ runner.os }}-${{ matrix.ruby }}-gems-${{ hashFiles(matrix.gemfile) }}
36
+ ${{ runner.os }}-${{ matrix.ruby }}-gems-${{
37
+ hashFiles(matrix.gemfile) }}
31
38
 
32
39
  - name: Set up Ruby
33
40
  uses: ruby/setup-ruby@v1
data/.rubocop.yml CHANGED
@@ -7,6 +7,3 @@ AllCops:
7
7
  NewCops: enable
8
8
  Exclude:
9
9
  - vendor/**/*
10
-
11
- Metrics:
12
- Enabled: false
data/CHANGELOG.md CHANGED
@@ -11,6 +11,10 @@ Prefix your message with one of the following:
11
11
  - [Security] in case of vulnerabilities.
12
12
  -->
13
13
 
14
- ## v1.0.0 - 2021-12-07
14
+ ## v2.0.1
15
15
 
16
- - Initial release as SuperConfig (previously known as env_vars).
16
+ - [Changed] Ensure bad JSON strings doesn't leak it's contents.
17
+
18
+ ## v2.0.0
19
+
20
+ - Initial release.
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ![SuperConfig: Access environment variables. Also includes presence validation, type coercion and default values.](https://raw.githubusercontent.com/fnando/superconfig/main/superconfig.png)
2
2
 
3
3
  <p align="center">
4
- <a href="https://github.com/fnando/superconfig/actions/workflows/tests.yml"><img src="https://github.com/fnando/superconfig/workflows/Tests/badge.svg" alt="Github Actions"></a>
4
+ <a href="https://github.com/fnando/superconfig/actions/workflows/ruby-tests.yml"><img src="https://github.com/fnando/superconfig/workflows/ruby-tests/badge.svg" alt="Github Actions"></a>
5
5
  <a href="https://codeclimate.com/github/fnando/superconfig"><img src="https://codeclimate.com/github/fnando/superconfig/badges/gpa.svg" alt="Code Climate"></a>
6
6
  <a href="https://rubygems.org/gems/superconfig"><img src="https://img.shields.io/gem/v/superconfig.svg" alt="Gem"></a>
7
7
  <a href="https://rubygems.org/gems/superconfig"><img src="https://img.shields.io/gem/dt/superconfig.svg" alt="Gem"></a>
@@ -118,6 +118,47 @@ You can coerce values to the following types:
118
118
  - `json`: E.g. `mandatory :keyring, json`. The environment variable must be
119
119
  parseable by `JSON.parse(content)`.
120
120
 
121
+ ### Report
122
+
123
+ Sometimes it gets hard to understand what's set and what's not. In this case,
124
+ you can get a report by calling `SuperConfig::Base#report`. If you're using
125
+ Rails, you can create a rake task like this:
126
+
127
+ ```ruby
128
+ # frozen_string_literal: true
129
+
130
+ desc "Show SuperConfig report"
131
+ task superconfig: [:environment] do
132
+ puts YourAppNamespace::Config.report
133
+ end
134
+ ```
135
+
136
+ Then, change your configuration so it doesn't raise an exception.
137
+
138
+ ```ruby
139
+ # frozen_string_literal: true
140
+ # file: config/config.rb
141
+
142
+ module YourAppNamespace
143
+ Config = SuperConfig.new(raise_exception: false) do
144
+ mandatory :database_url, string
145
+ optional :app_name, string
146
+ optional :wait, string
147
+ optional :force_ssl, bool, true
148
+ end
149
+ end
150
+ ```
151
+
152
+ Finally, run the following command:
153
+
154
+ ```console
155
+ $ rails superconfig
156
+ ❌ DATABASE_URL is not set (mandatory)
157
+ ✅ APP_NAME is set (optional)
158
+ ⚠️ WAIT is not set (optional)
159
+ ✅ FORCE_SSL is not set, but has default value (optional)
160
+ ```
161
+
121
162
  ### Dotenv integration
122
163
 
123
164
  If you're using [dotenv](https://rubygems.org/gems/dotenv), you can simply
data/lib/superconfig.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SuperConfig
4
- VERSION = "1.0.0"
4
+ VERSION = "2.0.1"
5
5
 
6
6
  MissingEnvironmentVariable = Class.new(StandardError)
7
7
  MissingCallable = Class.new(StandardError)
@@ -18,6 +18,7 @@ module SuperConfig
18
18
  @env = env
19
19
  @raise_exception = raise_exception
20
20
  @stderr = stderr
21
+ @attributes = {}
21
22
  @__cache__ = {}
22
23
  instance_eval(&block)
23
24
  end
@@ -37,6 +38,9 @@ module SuperConfig
37
38
  )
38
39
  name = name.to_s
39
40
  env_var = name.upcase
41
+
42
+ @attributes[env_var] = {required: required, default: default}
43
+
40
44
  name = "#{name}?" if type == bool
41
45
 
42
46
  validate!(env_var, required, description)
@@ -44,7 +48,7 @@ module SuperConfig
44
48
  define_singleton_method(name) do
45
49
  return default unless @env.key?(env_var)
46
50
 
47
- coerce(type, @env[env_var])
51
+ coerce(env_var, type, @env[env_var])
48
52
  end
49
53
 
50
54
  aliases.each do |alias_name|
@@ -139,41 +143,69 @@ module SuperConfig
139
143
  :json
140
144
  end
141
145
 
142
- private def coerce_to_string(value)
146
+ def report
147
+ attrs = @attributes.sort
148
+
149
+ report = attrs.each_with_object([]) do |(env_var, info), buffer|
150
+ icon, message = if @env.key?(env_var)
151
+ ["✅", "is set"]
152
+ elsif info[:required]
153
+ ["❌", "is not set"]
154
+ elsif !info[:required] && !info[:default].nil?
155
+ ["✅", "is not set, but has default value"]
156
+ else
157
+ ["⚠️", "is not set"]
158
+ end
159
+
160
+ label = if info[:required]
161
+ "mandatory"
162
+ else
163
+ "optional"
164
+ end
165
+
166
+ buffer << [icon, env_var, message, "(#{label})"].join(" ")
167
+ end
168
+
169
+ "#{report.join("\n")}\n"
170
+ end
171
+
172
+ private def coerce_to_string(_name, value)
143
173
  value
144
174
  end
145
175
 
146
- private def coerce_to_bool(value)
176
+ private def coerce_to_bool(_name, value)
147
177
  BOOL_TRUE.include?(value)
148
178
  end
149
179
 
150
- private def coerce_to_int(value)
180
+ private def coerce_to_int(_name, value)
151
181
  Integer(value) if !BOOL_FALSE.include?(value) && value
152
182
  end
153
183
 
154
- private def coerce_to_float(value)
184
+ private def coerce_to_float(_name, value)
155
185
  Float(value) if value
156
186
  end
157
187
 
158
- private def coerce_to_bigdecimal(value)
188
+ private def coerce_to_bigdecimal(_name, value)
159
189
  BigDecimal(value) if value
160
190
  end
161
191
 
162
- private def coerce_to_symbol(value)
192
+ private def coerce_to_symbol(_name, value)
163
193
  value&.to_sym
164
194
  end
165
195
 
166
- private def coerce_to_array(value, type)
167
- value&.split(/, */)&.map {|v| coerce(type, v) }
196
+ private def coerce_to_array(name, value, type)
197
+ value&.split(/, */)&.map {|v| coerce(name, type, v) }
168
198
  end
169
199
 
170
- private def coerce_to_json(value)
200
+ private def coerce_to_json(name, value)
171
201
  value && JSON.parse(value)
202
+ rescue JSON::ParserError
203
+ raise ArgumentError, "#{name} is not a valid JSON string"
172
204
  end
173
205
 
174
- private def coerce(type, value)
206
+ private def coerce(name, type, value)
175
207
  main_type, sub_type = type
176
- args = [value]
208
+ args = [name, value]
177
209
  args << sub_type if sub_type
178
210
 
179
211
  send("coerce_to_#{main_type}", *args)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: superconfig
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-07 00:00:00.000000000 Z
11
+ date: 2023-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -184,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
184
184
  - !ruby/object:Gem::Version
185
185
  version: '0'
186
186
  requirements: []
187
- rubygems_version: 3.2.32
187
+ rubygems_version: 3.4.6
188
188
  signing_key:
189
189
  specification_version: 4
190
190
  summary: Access environment variables. Also includes presence validation, type coercion