invar 0.6.1 → 0.8.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: 1f8761298571a16c1752a4413d4288095301381a3a3ad323ea9e0cf75c48a5f7
4
- data.tar.gz: b5a573c3eb0b93e3774a504fc467f9349eb242979a900d3b6ac463d609d75257
3
+ metadata.gz: a4826c528fc5940bcc955a1fc762abc2b4800a30eb4ce5b34af0ea313dd990ab
4
+ data.tar.gz: f463ed247adc47ea89d7b6965cd427d21a98de125271b262541eb0703a792d62
5
5
  SHA512:
6
- metadata.gz: a7f52110ae1fe1580047d74b957c6da15208a82faec856d795177deb3f745778ef8f79d2a05e422e54ba06b2ea581978783e773d9eafb52e23e29ca1d2948b06
7
- data.tar.gz: 0c35ac70036bc6c28e1444d6136fd27621d281d0ec54ba6e2c3b26a93e393eb1ce711226c081d8fba0178497fc869aea81232059746ba7afd91cddb9117cd4c1
6
+ metadata.gz: 6bbc1f4df04c3f4917a2cfcce611acde0859ccd74b412c0b9faa021770c4f01d246defb0131fc8052d0e2aeb40d904d40a043ecccb7a872f966b4a9264e812a3
7
+ data.tar.gz: 32a1754130909b04d488adb88b67e5efe193c2173103d9041338652026ef45a55b3e4fbaa49bed2863f8b5d0d70a257ace52b5bbff913236f4c82b4a90af06bf
data/.rubocop.yml CHANGED
@@ -4,17 +4,6 @@ AllCops:
4
4
  Exclude:
5
5
  - 'bin/*'
6
6
 
7
- TargetRubyVersion: 2.7
8
-
9
- Layout/LineLength:
10
- Exclude:
11
- - 'spec/**/*.rb'
12
-
13
- # setting to 6 to match RubyMine autoformat
14
- Layout/FirstArrayElementIndentation:
15
- IndentationWidth: 6
16
-
17
-
18
7
  # rspec blocks are huge by design
19
8
  Metrics/BlockLength:
20
9
  Exclude:
@@ -23,4 +12,3 @@ Metrics/BlockLength:
23
12
  Metrics/ModuleLength:
24
13
  Exclude:
25
14
  - 'spec/**/*.rb'
26
-
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-2.7.1
1
+ ruby-3.1.4
data/Gemfile CHANGED
@@ -2,5 +2,19 @@
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
- # Specify your gem's dependencies in invar.gemspec
5
+ # Gem's dependencies in invar.gemspec
6
6
  gemspec
7
+
8
+ group :development do
9
+ gem 'bundler', '~> 2.3'
10
+ gem 'rake', '~> 13.0'
11
+ gem 'rubocop', '~> 1.56'
12
+ gem 'rubocop-performance', '~> 1.19'
13
+ gem 'yard', '~> 0.9'
14
+ end
15
+
16
+ group :test do
17
+ gem 'fakefs', '~> 2.5'
18
+ gem 'rspec', '~> 3.12'
19
+ gem 'simplecov', '~> 0.22'
20
+ end
data/RELEASE_NOTES.md CHANGED
@@ -19,6 +19,36 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
19
19
 
20
20
  * none
21
21
 
22
+ ## [0.8.0] - 2023-09-13
23
+
24
+ ### Major Changes
25
+
26
+ * none
27
+
28
+ ### Minor Changes
29
+
30
+ * Increased minimum Ruby to 3.1
31
+
32
+ ### Bugfixes
33
+
34
+ * none
35
+
36
+ ## [0.7.0] - 2023-08-06
37
+
38
+ ### Major Changes
39
+
40
+ * none
41
+
42
+ ### Minor Changes
43
+
44
+ * Tweaked file missing error messages
45
+ * Extracted testing helper features into a separate module
46
+ * Added support for multiple after_load hooks
47
+
48
+ ### Bugfixes
49
+
50
+ * No longer attempts to set secrets file permissions on every edit
51
+
22
52
  ## [0.6.1] - 2023-05-22
23
53
 
24
54
  ### Major Changes
@@ -31,7 +61,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
31
61
 
32
62
  ### Bugfixes
33
63
 
34
- * Fixed minor logic error in permissions checking, improved testing
64
+ * Fixed minor logic error in permissions checking, improved testing
35
65
 
36
66
  ## [0.6.0] - 2023-05-21
37
67
 
data/invar.gemspec CHANGED
@@ -27,15 +27,8 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ['lib']
29
29
 
30
- spec.required_ruby_version = '>= 2.7'
30
+ spec.required_ruby_version = '>= 3.1'
31
31
 
32
32
  spec.add_dependency 'dry-schema', '>= 1.0'
33
33
  spec.add_dependency 'lockbox', '>= 1.0'
34
-
35
- spec.add_development_dependency 'bundler', '~> 2.3'
36
- spec.add_development_dependency 'fakefs', '~> 1.9'
37
- spec.add_development_dependency 'rake', '~> 13.0'
38
- spec.add_development_dependency 'rspec', '~> 3.12'
39
- spec.add_development_dependency 'simplecov', '~> 0.21'
40
- spec.add_development_dependency 'yard', '~> 0.9'
41
34
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nodoc:
4
+ module Invar
5
+ # Raised when no config file can be found within the search paths.
6
+ class MissingConfigFileError < RuntimeError
7
+ end
8
+
9
+ # Raised when no secrets file can be found within the search paths.
10
+ class MissingSecretsFileError < RuntimeError
11
+ end
12
+
13
+ # Raised when an error is encountered during secrets file encryption
14
+ class SecretsFileEncryptionError < RuntimeError
15
+ end
16
+
17
+ # Raised when an error is encountered during secrets file decryption
18
+ class SecretsFileDecryptionError < RuntimeError
19
+ end
20
+
21
+ # Raised when a key is defined in both the environment and the configuration file.
22
+ class EnvConfigCollisionError < RuntimeError
23
+ # Message hinting at possible solution
24
+ HINT = 'Either rename your config entry or remove the environment variable.'
25
+ end
26
+
27
+ # Raised when there are config or secrets files found at multiple locations. You can resolve this by deciding on
28
+ # one correct location and removing the alternate file(s).
29
+ class AmbiguousSourceError < RuntimeError
30
+ # Message hinting at possible solution
31
+ HINT = 'Choose 1 correct one and delete the others.'
32
+ end
33
+
34
+ # Raised when #pretend is called but the testing extension has not been loaded.
35
+ #
36
+ # When raised during normal operation, it may mean the application is calling #pretend directly, which is strongly
37
+ # discouraged. The feature is meant for testing.
38
+ #
39
+ # @see Invar#pretend
40
+ class ImmutableRealityError < NoMethodError
41
+ HINT = <<~HINT
42
+ Try adding this to your test suite config file:
43
+ require 'invar/test'
44
+ HINT
45
+
46
+ PRETEND_MSG = "Method 'Invar::Scope#pretend' is defined in the testing extension. #{ HINT }".freeze
47
+ HOOK_MSG = "Methods 'Invar.after_load and clear_hooks' are defined in the testing extension. #{ HINT }".freeze
48
+ end
49
+
50
+ # Raised when schema validation fails
51
+ class SchemaValidationError < RuntimeError
52
+ end
53
+ end
@@ -7,13 +7,18 @@ require 'delegate'
7
7
 
8
8
  module Invar
9
9
  # Verifies a file is secure
10
- class PrivateFile #< SimpleDelegator
10
+ class PrivateFile
11
11
  extend Forwardable
12
12
  def_delegators :@delegate_sd_obj, :stat, :to_s, :basename, :==, :chmod
13
13
 
14
+ # Mask for limiting to the lowest three octal digits (which store permissions)
15
+ PERMISSIONS_MASK = 0o777
16
+
14
17
  ALLOWED_USER_MODES = [0o600, 0o400].freeze
15
18
  ALLOWED_GROUP_MODES = [0o060, 0o040, 0o000].freeze
16
19
 
20
+ DEFAULT_PERMISSIONS = 0o600
21
+
17
22
  # Allowed permissions modes for lockfile. Readable or read-writable by the user or group only
18
23
  ALLOWED_MODES = ALLOWED_USER_MODES.product(ALLOWED_GROUP_MODES).collect do |u, g|
19
24
  u | g # bitwise OR
@@ -45,9 +50,8 @@ module Invar
45
50
  #
46
51
  # @raise [FilePermissionsError] if the file has insecure permissions
47
52
  def verify_permissions!
48
- permissions_mask = 0o777 # only the lowest three digits are perms, so masking
49
53
  # stat = @delegate_sd_obj.stat
50
- file_mode = stat.mode & permissions_mask
54
+ file_mode = stat.mode & PERMISSIONS_MASK
51
55
  # TODO: use stat.world_readable? etc instead
52
56
  return if ALLOWED_MODES.include? file_mode
53
57
 
@@ -30,8 +30,8 @@ module Invar
30
30
  #
31
31
  # @param (see #define)
32
32
  # @see Tasks#define
33
- def self.define(**args, &block)
34
- new.define(**args, &block)
33
+ def self.define(...)
34
+ new.define(...)
35
35
  end
36
36
 
37
37
  # Defines helpful Rake tasks for the given namespace.
@@ -199,7 +199,10 @@ module Invar
199
199
 
200
200
  encryption_key = Lockbox.generate_key
201
201
 
202
- write_encrypted_file(file_path, encryption_key, SECRETS_TEMPLATE)
202
+ write_encrypted_file(file_path,
203
+ encryption_key: encryption_key,
204
+ content: SECRETS_TEMPLATE,
205
+ permissions: PrivateFile::DEFAULT_PERMISSIONS)
203
206
 
204
207
  warn "Created file: #{ file_path }"
205
208
 
@@ -232,7 +235,7 @@ module Invar
232
235
  'secrets.yml'
233
236
  end
234
237
 
235
- def write_encrypted_file(file_path, encryption_key, content)
238
+ def write_encrypted_file(file_path, encryption_key:, content:, permissions: nil)
236
239
  lockbox = Lockbox.new(key: encryption_key)
237
240
 
238
241
  encrypted_data = lockbox.encrypt(content)
@@ -240,7 +243,7 @@ module Invar
240
243
  config_dir.mkpath
241
244
  # TODO: replace File.opens with photo_path.binwrite(uri.data) once FakeFS can handle it
242
245
  File.open(file_path.to_s, 'wb') { |f| f.write encrypted_data }
243
- file_path.chmod 0o600
246
+ file_path.chmod permissions if permissions
244
247
  end
245
248
 
246
249
  def edit_encrypted_file(file_path)
@@ -257,7 +260,7 @@ module Invar
257
260
  tmp_file.read
258
261
  end
259
262
 
260
- write_encrypted_file(file_path, encryption_key, file_str)
263
+ write_encrypted_file(file_path, encryption_key: encryption_key, content: file_str)
261
264
  end
262
265
 
263
266
  def determine_key(file_path)
data/lib/invar/reality.rb CHANGED
@@ -72,27 +72,22 @@ module Invar
72
72
  @configs = Scope.new(load_configs(locator))
73
73
  rescue FileLocator::FileNotFoundError
74
74
  raise MissingConfigFileError,
75
- "No config file found. Create config.yml in one of these locations: #{ search_paths }"
75
+ "No Invar config file found. Create config.yml in one of these locations: #{ search_paths }"
76
76
  end
77
77
 
78
78
  begin
79
79
  @secrets = Scope.new(load_secrets(locator, decryption_keyfile || DEFAULT_KEY_FILE_NAME))
80
80
  rescue FileLocator::FileNotFoundError
81
+ hint = "Create encrypted secrets.yml in one of these locations: #{ search_paths }"
81
82
  raise MissingSecretsFileError,
82
- "No secrets file found. Create encrypted secrets.yml in one of these locations: #{ search_paths }"
83
+ "No Invar secrets file found. #{ hint }"
83
84
  end
84
85
 
85
86
  freeze
86
- # instance_eval(&self.class.__override_block__)
87
- self.class.__override_block__&.call(self)
88
87
 
89
88
  RealityValidator.new(configs_schema, secrets_schema).validate(@configs, @secrets)
90
89
  end
91
90
 
92
- class << self
93
- attr_accessor :__override_block__
94
- end
95
-
96
91
  # Fetch from one of the two base scopes: :config or :secret.
97
92
  # Plural names are also accepted (ie. :configs and :secrets).
98
93
  #
@@ -224,51 +219,4 @@ module Invar
224
219
  end
225
220
  end
226
221
  end
227
-
228
- # Raised when no config file can be found within the search paths.
229
- class MissingConfigFileError < RuntimeError
230
- end
231
-
232
- # Raised when no secrets file can be found within the search paths.
233
- class MissingSecretsFileError < RuntimeError
234
- end
235
-
236
- # Raised when an error is encountered during secrets file encryption
237
- class SecretsFileEncryptionError < RuntimeError
238
- end
239
-
240
- # Raised when an error is encountered during secrets file decryption
241
- class SecretsFileDecryptionError < RuntimeError
242
- end
243
-
244
- # Raised when a key is defined in both the environment and the configuration file.
245
- class EnvConfigCollisionError < RuntimeError
246
- # Message hinting at possible solution
247
- HINT = 'Either rename your config entry or remove the environment variable.'
248
- end
249
-
250
- # Raised when there are config or secrets files found at multiple locations. You can resolve this by deciding on
251
- # one correct location and removing the alternate file(s).
252
- class AmbiguousSourceError < RuntimeError
253
- # Message hinting at possible solution
254
- HINT = 'Choose 1 correct one and delete the others.'
255
- end
256
-
257
- # Raised when #pretend is called but the testing extension has not been loaded.
258
- #
259
- # When raised during normal operation, it may mean the application is calling #pretend directly, which is strongly
260
- # discouraged. The feature is meant for testing.
261
- #
262
- # @see Invar#pretend
263
- class ImmutableRealityError < NoMethodError
264
- # Message and hint for a possible solution
265
- MSG = <<~MSG
266
- Method 'pretend' is defined in the testing extension. Try adding this to your test suite config file:
267
- require 'invar/test'
268
- MSG
269
- end
270
-
271
- # Raised when schema validation fails
272
- class SchemaValidationError < RuntimeError
273
- end
274
222
  end
data/lib/invar/scope.rb CHANGED
@@ -7,7 +7,6 @@ module Invar
7
7
  @data = convert(data)
8
8
 
9
9
  @data.freeze
10
- @data_override = {}
11
10
  freeze
12
11
  end
13
12
 
@@ -18,23 +17,25 @@ module Invar
18
17
  # @see #override
19
18
  def fetch(key)
20
19
  key = key.downcase.to_sym
21
- @data_override.fetch(key, @data.fetch(key))
20
+ @data.fetch key
22
21
  rescue KeyError => e
23
- raise KeyError, "#{ e.message }. Known keys are #{ @data.keys.sort.collect { |k| ":#{ k }" }.join(', ') }"
22
+ raise KeyError, "#{ e.message }. Known keys are #{ known_keys }"
24
23
  end
25
24
 
26
25
  alias / fetch
27
26
  alias [] fetch
28
27
 
29
- def pretend(**)
30
- raise ::Invar::ImmutableRealityError, ::Invar::ImmutableRealityError::MSG
28
+ def method_missing(symbol, *args)
29
+ raise ::Invar::ImmutableRealityError, ::Invar::ImmutableRealityError::PRETEND_MSG if symbol == :pretend
30
+
31
+ super
31
32
  end
32
33
 
33
34
  # Returns a hash representation of this scope and subscopes.
34
35
  #
35
36
  # @return [Hash] a hash representation of this scope
36
37
  def to_h
37
- @data.merge(@data_override).to_h.transform_values do |value|
38
+ @data.to_h.transform_values do |value|
38
39
  case value
39
40
  when Scope
40
41
  value.to_h
@@ -50,11 +51,15 @@ module Invar
50
51
 
51
52
  private
52
53
 
54
+ def known_keys
55
+ @data.keys.sort.collect { |k| ":#{ k }" }.join(', ')
56
+ end
57
+
53
58
  def convert(data)
54
59
  (data || {}).dup.each_with_object({}) do |pair, agg|
55
60
  key, value = pair
56
61
 
57
- agg[key] = value.is_a?(Hash) ? Scope.new(value) : value
62
+ agg[key.to_s.downcase.to_sym] = value.is_a?(Hash) ? Scope.new(value) : value
58
63
  end
59
64
  end
60
65
  end
data/lib/invar/test.rb CHANGED
@@ -1,16 +1,104 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'invar'
3
+ # Specifically not calling require 'invar' in this file to force applications to need to include it themselves,
4
+ # avoiding the situation where test suites include application dependencies for them and breaking when
5
+ # the app is run without the test suite
4
6
 
7
+ # :nodoc:
5
8
  module Invar
6
- # Extension to the standard class
7
- class Scope
8
- # Overrides the given set of key-value pairs. This is intended to only be used in testing environments,
9
- # where you may need contextual adjustments to suit the test situation.
10
- #
11
- # @param [Hash] pairs the hash of pairs to override.
12
- def pretend(pairs)
13
- @data_override.merge!(pairs.transform_keys(&:to_sym))
9
+ # Namespace module containing mixins for parts of the main gem to enable modifications and data control
10
+ # in automated testing, while remaining immutable in the main gem and real runtime usage.
11
+ module TestExtension
12
+ # Methods to extend the Reality class
13
+ module RealityMethods
14
+ class << self
15
+ attr_accessor :__after_load_hooks__
16
+
17
+ RealityMethods.__after_load_hooks__ = []
18
+ end
19
+
20
+ def initialize(**)
21
+ super
22
+
23
+ # instance_eval(&self.class.__override_block__)
24
+ RealityMethods.__after_load_hooks__.each { |hook| hook.call(self) }
25
+ end
26
+ end
27
+
28
+ # Adds methods to the main Invar module itself for a global-access hook to be used in application init phase.
29
+ module LoadHook
30
+ def clear_hooks
31
+ RealityMethods.__after_load_hooks__.clear
32
+ end
33
+
34
+ # Block that will be run after loading from config files.
35
+ #
36
+ # It is intended to allow test suites to tweak configurations without having to duplicate the entire config file.
37
+ #
38
+ # @yieldparam the configs from the Invar
39
+ # @return [void]
40
+ def after_load(&block)
41
+ RealityMethods.__after_load_hooks__.push(block)
42
+ end
43
+ end
44
+
45
+ # Methods mixin for the Invar::Scope class
46
+ module ScopeMethods
47
+ def initialize(data)
48
+ @pretend_data = {}
49
+ super
50
+ end
51
+
52
+ # Overrides the given set of key-value pairs. This is intended to only be used in testing environments,
53
+ # where you may need contextual adjustments to suit the test situation.
54
+ #
55
+ # @param [Hash] pairs the hash of pairs to override.
56
+ def pretend(pairs)
57
+ @pretend_data.merge! convert(pairs)
58
+ end
59
+
60
+ def fetch(key)
61
+ @pretend_data.fetch(key.downcase.to_sym) do
62
+ super
63
+ end
64
+ rescue KeyError => e
65
+ raise KeyError, "#{ e.message }. Pretend keys are: #{ pretend_keys }."
66
+ end
67
+
68
+ # Duplicated to refer to the override version
69
+ alias / fetch
70
+ alias [] fetch
71
+
72
+ # Returns a hash representation of this scope and subscopes.
73
+ #
74
+ # @return [Hash] a hash representation of this scope
75
+ def to_h
76
+ super.merge(@pretend_data).to_h
77
+ end
78
+
79
+ private
80
+
81
+ def pretend_keys
82
+ keys = @pretend_data.keys
83
+
84
+ if keys.empty?
85
+ '(none)'
86
+ else
87
+ keys.sort.collect { |k| ":#{ k }" }.join(', ')
88
+ end
89
+ end
14
90
  end
15
91
  end
92
+
93
+ # Extension to the base library class that provides additional methods relevant only to automated testing
94
+ extend TestExtension::LoadHook
95
+
96
+ # Extension to the base library class that provides additional methods relevant only to automated testing
97
+ class Scope
98
+ prepend TestExtension::ScopeMethods
99
+ end
100
+
101
+ class Reality
102
+ prepend TestExtension::RealityMethods
103
+ end
16
104
  end
data/lib/invar/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Invar
4
4
  # Current version of the gem
5
- VERSION = '0.6.1'
5
+ VERSION = '0.8.0'
6
6
  end
data/lib/invar.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'invar/version'
4
- require 'invar/reality'
3
+ require_relative 'invar/version'
4
+ require_relative 'invar/errors'
5
+ require_relative 'invar/reality'
5
6
 
6
7
  # Invar is a Ruby Gem that provides a single source of truth for application configuration, secrets, and environment
7
8
  # variables.
@@ -14,13 +15,12 @@ module Invar
14
15
  end
15
16
 
16
17
  class << self
17
- # Block that will be run after loading from config files and prior to freezing. It is intended to allow
18
- # for test suites to tweak configurations without having to duplicate the entire config file.
19
- #
20
- # @yieldparam the configs from the Invar
21
- # @return [void]
22
- def after_load(&block)
23
- ::Invar::Reality.__override_block__ = block
18
+ def method_missing(meth)
19
+ if [:after_load, :clear_hooks].include? meth
20
+ raise ::Invar::ImmutableRealityError, ::Invar::ImmutableRealityError::HOOK_MSG
21
+ end
22
+
23
+ super
24
24
  end
25
25
  end
26
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: invar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robin Miller
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-22 00:00:00.000000000 Z
11
+ date: 2023-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-schema
@@ -38,90 +38,6 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.0'
41
- - !ruby/object:Gem::Dependency
42
- name: bundler
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '2.3'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '2.3'
55
- - !ruby/object:Gem::Dependency
56
- name: fakefs
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '1.9'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '1.9'
69
- - !ruby/object:Gem::Dependency
70
- name: rake
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '13.0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '13.0'
83
- - !ruby/object:Gem::Dependency
84
- name: rspec
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '3.12'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '3.12'
97
- - !ruby/object:Gem::Dependency
98
- name: simplecov
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '0.21'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '0.21'
111
- - !ruby/object:Gem::Dependency
112
- name: yard
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: '0.9'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: '0.9'
125
41
  description: |
126
42
  Locates and loads config YAML files based on XDG standard with the encrypted secrets file kept separately.
127
43
  Includes useful rake tasks to make management easier. No code execution in config. Rails-independent. Gluten free.
@@ -143,6 +59,7 @@ files:
143
59
  - Rakefile
144
60
  - invar.gemspec
145
61
  - lib/invar.rb
62
+ - lib/invar/errors.rb
146
63
  - lib/invar/file_locator.rb
147
64
  - lib/invar/private_file.rb
148
65
  - lib/invar/rake/tasks.rb
@@ -163,14 +80,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
163
80
  requirements:
164
81
  - - ">="
165
82
  - !ruby/object:Gem::Version
166
- version: '2.7'
83
+ version: '3.1'
167
84
  required_rubygems_version: !ruby/object:Gem::Requirement
168
85
  requirements:
169
86
  - - ">="
170
87
  - !ruby/object:Gem::Version
171
88
  version: '0'
172
89
  requirements: []
173
- rubygems_version: 3.1.2
90
+ rubygems_version: 3.4.18
174
91
  signing_key:
175
92
  specification_version: 4
176
93
  summary: Single source of truth for environmental configuration.