environment_helpers 1.2.1 → 1.4.0

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: 71bfb123e7f90d29f9e038849bc995207b9c11b166aae7e0938cf162e7ed70f5
4
- data.tar.gz: bb88e8d31c0c343a54f7be6a6919af08446a2a9fff973868b9ba22a9f1fc3f9a
3
+ metadata.gz: 977bcb9a26d78cbddc4857274e59ed796d9454993fa5bc307c3643af08ed53e2
4
+ data.tar.gz: 4696a62fd389365b56c79e952a1f4ac947970483faf17122e21cc312a1eff2c4
5
5
  SHA512:
6
- metadata.gz: f9adafc223d6c2edff2c4179bb86d172e2febe28d8761a2d55b9b76db02d6076ce981229cd8f758c905c4e4e524ad4b6b6e589ff55ced624fbc510ad8a183ed1
7
- data.tar.gz: 7d6ae5d630de28a2d5db1776d06ed7d2a6117a905b66c12aa61b2b7fe5c4dd64dd8cd5e764c450fcf846b077ee23c7f74f6bd393d3cec8b161f6365a27cd498b
6
+ metadata.gz: 1fca3efa7549d3464b174bb84fdaab9d5f0a6c150121d50cf715891eafcca4f097f24c2624f8cab10812260e0c1358928eac811cf299b232afd0a4971641f084
7
+ data.tar.gz: 2240bb669c7d0852c581b4ab0c0c343cdc1c1dece4da9b8b1d34c2b08658c9aa4e5a8ddfb6e6c864751ee4f6fd82d1ad351721213b005270faa233aa0f957a79
@@ -0,0 +1,29 @@
1
+ name: Quiet Quality
2
+
3
+ on: push
4
+ permissions: write-all
5
+
6
+ jobs:
7
+ check:
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - uses: actions/checkout@v3
11
+ with:
12
+ fetch-depth: 0
13
+
14
+ - name: Show the merge-base
15
+ run: git merge-base origin/main ${{ github.sha }}
16
+ if: github.branch != 'main'
17
+
18
+ - name: Set up Ruby
19
+ uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: 3.2
22
+
23
+ - name: Install gems
24
+ run: bundle install --jobs 4 --retry 3
25
+
26
+ - name: Run QuietQuality
27
+ run: |
28
+ gem install quiet_quality standard rubocop
29
+ qq -C .quiet_quality.ci-cd.yml
@@ -8,7 +8,7 @@ jobs:
8
8
  strategy:
9
9
  fail-fast: false
10
10
  matrix:
11
- ruby-version: ['2.6', '2.7', '3.0', '3.1', '3.2', 'head']
11
+ ruby-version: ['2.7', '3.0', '3.1', '3.2', 'head']
12
12
 
13
13
  steps:
14
14
  - uses: actions/checkout@v3
data/.mdl_rules.rb ADDED
@@ -0,0 +1,2 @@
1
+ all
2
+ rule "MD013", ignore_code_blocks: true
data/.mdlrc ADDED
@@ -0,0 +1,2 @@
1
+ style File.expand_path("../.mdl_rules.rb", __FILE__)
2
+ git_recurse true
@@ -0,0 +1,7 @@
1
+ ---
2
+ default_tools: ["standardrb", "rubocop", "markdown_lint", "rspec"]
3
+ executor: concurrent
4
+ comparison_branch: origin/main
5
+ annotator: github_stdout
6
+ changed_files: false
7
+ filter_messages: false
@@ -0,0 +1,7 @@
1
+ ---
2
+ default_tools: ["standardrb", "rubocop", "markdown_lint", "rspec"]
3
+ executor: concurrent
4
+ comparison_branch: origin/main
5
+ logging: light
6
+ changed_files: false
7
+ filter_messages: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,32 @@
1
+ # Changelog
2
+
3
+ ## Release 1.4.0
4
+
5
+ * Drop support for ruby 2.6
6
+ * Setup `quiet_quality` through the gemspec
7
+ * Setup `markdownlint` and comply with its rules (#25)
8
+ * Setup `rspec-cover_it` to enforce test-coverage (#24)
9
+
10
+ ## Release 1.3.0
11
+
12
+ * Support `ENV.date_time` (#19, resolves #6)
13
+
14
+ ## Release 1.2.1
15
+
16
+ * Require `set` before loading the gem, since we support rubies before 3.2 (#18)
17
+
18
+ ## Release 1.2.0
19
+
20
+ * Support `ENV.file_path` returning Pathname objects (#16, resolves #13)
21
+
22
+ ## Release 1.1.0
23
+
24
+ * Support `ENV.integer_range` (#15, resolves #5)
25
+
26
+ ## Release 1.0.1
27
+
28
+ * Specify dependencies more tightly (#14)
29
+
30
+ ## Release 1.0.0
31
+
32
+ (Initial release)
data/README.md CHANGED
@@ -1,36 +1,40 @@
1
1
  # EnvironmentHelpers
2
- This gem adds a set of convenience helpers to `ENV`, allowing you to access environment variables
3
- in a more structures and consistent way. Have you seen any line like these?
4
2
 
5
- ```
3
+ This gem adds a set of convenience helpers to `ENV`, allowing you to access
4
+ environment variables in a more structures and consistent way. Have you seen
5
+ any line like these?
6
+
7
+ ```ruby
6
8
  enable_bar = ENV.fetch("ENABLE_BAR", "false") == "true"
7
9
  foo_count = ENV.fetch("FOO_TOTAL", "100").to_i
8
10
  ```
9
11
 
10
- This works okay! And it's not really that complicated, working out what's going on here isn't
11
- that difficult. How about this?
12
+ This works okay! And it's not really that complicated, working out what's going
13
+ on here isn't that difficult. How about this?
12
14
 
13
- ```
15
+ ```ruby
14
16
  enable_foo = ENV.fetch("ENABLE_FOO", "false") != "true"
15
17
  ```
16
18
 
17
- That.. looks very similar, but means the opposite thing. Also not that tricky. You don't start
18
- to _wish_ for a tool like EnvironmentHelpers until these constructions get complex and compounded.
19
- But.. if you're using a 12-factor style of configuration, you probably have these ENV-fetches
20
- sprinkled _everywhere_, so making them moderately clearer or simpler can pay off fairly quickly.
19
+ That.. looks very similar, but means the opposite thing. Also not that tricky.
20
+ You don't start to _wish_ for a tool like EnvironmentHelpers until these
21
+ constructions get complex and compounded. But.. if you're using a 12-factor
22
+ style of configuration, you probably have these ENV-fetches sprinkled
23
+ _everywhere_, so making them moderately clearer or simpler can pay off fairly
24
+ quickly.
21
25
 
22
26
  ## Installation
23
27
 
24
- ```
28
+ ```ruby
25
29
  gem "environment_helper"
26
30
  ```
27
31
 
28
- There's not much to it - add the gem to your gemfile and when it's loaded it'll add some extra
29
- methods onto `ENV` for your use.
32
+ There's not much to it - add the gem to your gemfile and when it's loaded it'll
33
+ add some extra methods onto `ENV` for your use.
30
34
 
31
35
  ## Usage
32
36
 
33
- ```shell
37
+ ```ruby
34
38
  ENV.string("APP_NAME", default: "local")
35
39
  ENV.symbol("BUSINESS_DOMAIN", default: :engineering, required: true)
36
40
  ENV.boolean("ENABLE_FEATURE_FOO", default: false)
@@ -38,29 +42,44 @@ ENV.integer_range("ID_RANGE", default: (500..6000))
38
42
  ENV.integer("MAX_THREAD_COUNT", default: 5)
39
43
  ENV.file_path("FILE_PATH", default: "/some/path", required: true)
40
44
  ENV.date("SCHEDULED_DATE", required: true, format: "%Y-%m-%d")
45
+ ENV.date_time("RUN_AT", required: true, default: DateTime.now)
41
46
  ```
42
47
 
43
- Each of the supplied methods takes a positional parameter for the name of the environment variable,
44
- and then two optional named parameters `default` and `required` (there's no point in supplying
45
- both, but nothing stops you from doing so). The `default` value is the value used if the variable
46
- isn't present in the environment. If `required` is set to a truthy value, then if the variable isn't
47
- present in the environment, an `EnvironmentHelpers::MissingVariableError` is raised.
48
+ Each of the supplied methods takes a positional parameter for the name of the
49
+ environment variable, and then two optional named parameters `default` and
50
+ `required` (there's no point in supplying both, but nothing stops you from doing
51
+ so). The `default` value is the value used if the variable isn't present in the
52
+ environment. If `required` is set to a truthy value, then if the variable isn't
53
+ present in the environment, an `EnvironmentHelpers::MissingVariableError` is
54
+ raised.
48
55
 
49
56
  The available methods added to `ENV`:
50
57
 
51
- * `string` - environment values are already strings, so this is the simplest of the methods.
52
- * `symbol` - produces a symbol, and enforces that the default value is either `nil` or a Symbol.
53
- * `boolean` - produces `nil`, `true`, or `false` (and only allows those as defaults). Supports..
54
- a fair variety of strings to map onto those boolean value, though you should probably just use
55
- "true" and "false" really. If you specify `required: true` and get a value like "maybe?", it'll
56
- raise an `EnvironmentHelpers::InvalidBooleanText` exception.
57
- * `integer_range` - produces an integer Range object. It accepts `N-N`, `N..N`, or `N...N`, (the
58
- latter means 'excluding the upper bound, as in ruby).
59
- * `integer` - produces an integer from the environment variable, by calling `to_i` on it (if it's
60
- present). Note that this means that providing a value like "hello" means you'll get `0`, since
61
- that's what ruby does when you call `"hello".to_i`.
62
- * `file_path` - produces a `Pathname` initialized with the path specified by the environment variable.
63
- * `date` - produces a `Date` object, using `Date.strptime`. The default format string is `%Y-%m-%d`,
64
- which would parse a date like `2023-12-25`. It will handle invalid values (or format strings) like
65
- the variable not being present, though if it's specified as `required`, you will see a different
66
- exception in each case.
58
+ * `string` - environment values are already strings, so this is the simplest of
59
+ the methods.
60
+ * `symbol` - produces a symbol, and enforces that the default value is either
61
+ `nil` or a Symbol.
62
+ * `boolean` - produces `nil`, `true`, or `false` (and only allows those as
63
+ defaults). Supports.. a fair variety of strings to map onto those boolean
64
+ value, though you should probably just use "true" and "false" really. If you
65
+ specify `required: true` and get a value like "maybe?", it'll raise an
66
+ `EnvironmentHelpers::InvalidBooleanText` exception.
67
+ * `integer_range` - produces an integer Range object. It accepts `N-N`, `N..N`,
68
+ or `N...N`, (the latter means 'excluding the upper bound, as in ruby).
69
+ * `integer` - produces an integer from the environment variable, by calling
70
+ `to_i` on it (if it's present). Note that this means that providing a value
71
+ like "hello" means you'll get `0`, since that's what ruby does when you call
72
+ `"hello".to_i`.
73
+ * `file_path` - produces a `Pathname` initialized with the path specified by the
74
+ environment variable.
75
+ * `date` - produces a `Date` object, using `Date.strptime`. The default format
76
+ string is `%Y-%m-%d`, which would parse a date like `2023-12-25`. It will
77
+ handle invalid values (or format strings) like the variable not being present,
78
+ though if it's specified as `required`, you will see a different exception in
79
+ each case.
80
+ * `date_time` - produces a `DateTime` object, using either `DateTime.strptime`
81
+ or `DateTime.iso8601`. The default format is `:iso8601`, and `:unix` is also
82
+ an allowed 'format'. But if it is supplied as a _string_, it will be handled
83
+ as a strptime format string (the `:unix` format is equivalent to the format
84
+ string `"%s"`). It handles invalid or unparseable values like `ENV.date` does,
85
+ in that they are treated as if not supplied.
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
13
13
  DESC
14
14
  spec.homepage = "https://github.com/nevinera/environment_helpers"
15
15
  spec.license = "MIT"
16
- spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
16
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
17
17
 
18
18
  spec.metadata["homepage_uri"] = spec.homepage
19
19
  spec.metadata["source_code_uri"] = spec.homepage
@@ -30,7 +30,10 @@ Gem::Specification.new do |spec|
30
30
 
31
31
  spec.add_development_dependency "rspec", "~> 3.10"
32
32
  spec.add_development_dependency "simplecov", "~> 0.22.0"
33
+ spec.add_development_dependency "rspec-cover_it", "~> 0.1.0"
33
34
  spec.add_development_dependency "pry", "~> 0.14"
34
35
  spec.add_development_dependency "standard", "~> 1.28"
35
36
  spec.add_development_dependency "rubocop", "~> 1.50"
37
+ spec.add_development_dependency "quiet_quality", "~> 1.3.0"
38
+ spec.add_development_dependency "mdl", "~> 0.12"
36
39
  end
@@ -12,6 +12,16 @@ module EnvironmentHelpers
12
12
  fail(InvalidDateText, "Required date environment variable #{name} had inappropriate content '#{text}'")
13
13
  end
14
14
 
15
+ def date_time(name, format: :iso8601, default: nil, required: false)
16
+ check_default_type(:date_time, default, DateTime)
17
+ text = fetch_value(name, required: required)
18
+ dt = parse_date_time_from(text, format: format)
19
+
20
+ return dt if dt
21
+ return default unless required
22
+ fail(InvalidDateTimeText, "Require date_time environment variable #{name} had inappropriate content '#{text}'")
23
+ end
24
+
15
25
  private
16
26
 
17
27
  def parse_date_from(text, format:)
@@ -20,5 +30,37 @@ module EnvironmentHelpers
20
30
  rescue ArgumentError
21
31
  nil
22
32
  end
33
+
34
+ def parse_date_time_from(text, format:)
35
+ if text.nil?
36
+ nil
37
+ elsif format == :iso8601
38
+ iso8601_date_time(text)
39
+ elsif format == :unix
40
+ unix_date_time(text)
41
+ elsif format.is_a?(String)
42
+ strptime_date_time(text, format: format)
43
+ else
44
+ fail(BadFormat, "ENV.date_time requires either a strptime format string, :unix, or :iso8601")
45
+ end
46
+ end
47
+
48
+ def iso8601_date_time(text)
49
+ DateTime.iso8601(text)
50
+ rescue
51
+ nil
52
+ end
53
+
54
+ def unix_date_time(text)
55
+ DateTime.strptime(text, "%s")
56
+ rescue
57
+ nil
58
+ end
59
+
60
+ def strptime_date_time(text, format:)
61
+ DateTime.strptime(text, format)
62
+ rescue
63
+ nil
64
+ end
23
65
  end
24
66
  end
@@ -0,0 +1,44 @@
1
+ module EnvironmentHelpers
2
+ module EnumerableHelpers
3
+ VALID_TYPES = %i[strings symbols integers]
4
+
5
+ def array(key, of: :strings, delimiter: ",", default: nil, required: false)
6
+ check_default_type(:array, default, Array)
7
+ check_valid_data_type!(of)
8
+ check_default_data_types!(default, of)
9
+
10
+ values = fetch_value(key, required: required)
11
+ return default if values.nil?
12
+
13
+ values.split(delimiter).map { |value| value.send(TYPE_HANDLERS[of]) }
14
+ end
15
+
16
+ private
17
+
18
+ def check_valid_data_type!(type)
19
+ unless VALID_TYPES.include?(type)
20
+ fail(InvalidType, "Valid types: #{VALID_TYPES.join(", ")}. Got: #{type}.")
21
+ end
22
+ end
23
+
24
+ def check_default_data_types!(default, type)
25
+ invalid = Array(default).reject { |val| val.is_a? TYPE_MAP[type] }
26
+
27
+ unless invalid.empty?
28
+ fail(BadDefault, "Default array contains values not of type `#{type}': #{invalid.join(", ")}")
29
+ end
30
+ end
31
+
32
+ TYPE_HANDLERS = {
33
+ integers: :to_i,
34
+ strings: :to_s,
35
+ symbols: :to_sym
36
+ }
37
+
38
+ TYPE_MAP = {
39
+ integers: Integer,
40
+ strings: String,
41
+ symbols: Symbol
42
+ }
43
+ end
44
+ end
@@ -1,3 +1,3 @@
1
1
  module EnvironmentHelpers
2
- VERSION = "1.2.1"
2
+ VERSION = "1.4.0"
3
3
  end
@@ -9,17 +9,21 @@ require_relative "./environment_helpers/range_helpers"
9
9
  require_relative "./environment_helpers/numeric_helpers"
10
10
  require_relative "./environment_helpers/file_helpers"
11
11
  require_relative "./environment_helpers/datetime_helpers"
12
+ require_relative "./environment_helpers/enumerable_helpers"
12
13
 
13
14
  module EnvironmentHelpers
14
15
  Error = Class.new(::StandardError)
15
16
  MissingVariableError = Class.new(Error)
16
17
  BadDefault = Class.new(Error)
18
+ BadFormat = Class.new(Error)
17
19
 
20
+ InvalidType = Class.new(Error)
18
21
  InvalidValue = Class.new(Error)
19
22
  InvalidBooleanText = Class.new(InvalidValue)
20
23
  InvalidRangeText = Class.new(InvalidValue)
21
24
  InvalidIntegerText = Class.new(InvalidValue)
22
25
  InvalidDateText = Class.new(InvalidValue)
26
+ InvalidDateTimeText = Class.new(InvalidValue)
23
27
 
24
28
  include AccessHelpers
25
29
  include StringHelpers
@@ -28,6 +32,7 @@ module EnvironmentHelpers
28
32
  include NumericHelpers
29
33
  include FileHelpers
30
34
  include DatetimeHelpers
35
+ include EnumerableHelpers
31
36
  end
32
37
 
33
38
  ENV.extend(EnvironmentHelpers)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: environment_helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Mueller
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-28 00:00:00.000000000 Z
11
+ date: 2023-06-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.22.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-cover_it
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.1.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.1.0
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: pry
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,34 @@ dependencies:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
96
  version: '1.50'
97
+ - !ruby/object:Gem::Dependency
98
+ name: quiet_quality
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 1.3.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 1.3.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: mdl
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.12'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.12'
83
125
  description: |
84
126
  Convenience helpers for more simply accessing data passed to applications through the
85
127
  environment that may have types and/or defaults
@@ -89,11 +131,16 @@ executables: []
89
131
  extensions: []
90
132
  extra_rdoc_files: []
91
133
  files:
92
- - ".github/workflows/lint.yml"
134
+ - ".github/workflows/quality.yml"
93
135
  - ".github/workflows/rspec.yml"
94
136
  - ".gitignore"
137
+ - ".mdl_rules.rb"
138
+ - ".mdlrc"
139
+ - ".quiet_quality.ci-cd.yml"
140
+ - ".quiet_quality.yml"
95
141
  - ".rspec"
96
142
  - ".rubocop.yml"
143
+ - CHANGELOG.md
97
144
  - Gemfile
98
145
  - LICENSE
99
146
  - README.md
@@ -102,6 +149,7 @@ files:
102
149
  - lib/environment_helpers/access_helpers.rb
103
150
  - lib/environment_helpers/boolean_helpers.rb
104
151
  - lib/environment_helpers/datetime_helpers.rb
152
+ - lib/environment_helpers/enumerable_helpers.rb
105
153
  - lib/environment_helpers/file_helpers.rb
106
154
  - lib/environment_helpers/numeric_helpers.rb
107
155
  - lib/environment_helpers/range_helpers.rb
@@ -121,14 +169,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
121
169
  requirements:
122
170
  - - ">="
123
171
  - !ruby/object:Gem::Version
124
- version: 2.6.0
172
+ version: 2.7.0
125
173
  required_rubygems_version: !ruby/object:Gem::Requirement
126
174
  requirements:
127
175
  - - ">="
128
176
  - !ruby/object:Gem::Version
129
177
  version: '0'
130
178
  requirements: []
131
- rubygems_version: 3.3.26
179
+ rubygems_version: 3.4.10
132
180
  signing_key:
133
181
  specification_version: 4
134
182
  summary: A set of convenience methods for accessing environment data
@@ -1,30 +0,0 @@
1
- name: Linters
2
-
3
- on: [push]
4
-
5
- jobs:
6
- StandardRB:
7
- runs-on: ubuntu-latest
8
- steps:
9
- - uses: actions/checkout@v2
10
-
11
- - name: Set up ruby
12
- uses: ruby/setup-ruby@v1
13
- with:
14
- ruby-version: 3.2
15
-
16
- - name: Cache gems
17
- uses: actions/cache@v1
18
- with:
19
- path: vendor/bundle
20
- key: ${{ runner.os }}-linters-${{ hashFiles('Gemfile.lock') }}
21
- restore-keys:
22
- ${{ runner.os }}-linters-
23
- - name: Install gems
24
- run: bundle install --jobs 4 --retry 3
25
-
26
- - name: Run standard
27
- run: bundle exec standardrb
28
-
29
- - name: Run rubocop (complexity checks)
30
- run: bundle exec rubocop --parallel