ssm_config 0.1.1 → 1.1.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: 62ee2af26eb305962b5a1c4f019b5a16b847de0b5b4b482bb7c077c958a8cf32
4
- data.tar.gz: c7665892a5d0900d5923549dd9c08196adeb8fb854879f13f46e44a038158b25
3
+ metadata.gz: a7509632dfae2aa08f269331ae52ec1e645da5c3777a772721866147f4e25c46
4
+ data.tar.gz: 146883e2ee8cde2946de40d3ee49ba2ab1dc0f9ad529425a2970bf6bb0baf8ec
5
5
  SHA512:
6
- metadata.gz: ba9d0c438b9147d33d95ad07eee3224f05b1a77a4e3b930e15c476b98a1a4a38dfbad6797491e648c213f0ed231e22f11c59a2b84809c6424f05f6c078e4b58f
7
- data.tar.gz: 768c01d819f2af815c1788359870a3626257a39021129bc460b50850d9161f600d0de2c92ee0f52303af54523a845a3b2097bfd52c9cb8850999a62c6ebe7137
6
+ metadata.gz: c18bf507eda6a9f668325376d7ac0a28d0ceee717ef73909019493cb8b91aac3fc0c51e4eae8b60077674565b25fbd0505bab97f32588a5a6ed456bd8da395a9
7
+ data.tar.gz: 91bd9725e9ca01cc512c434db801998887fe248ed8720eeaab7e4cafde50a1d3cb2d8873700e2f5411c2e2c1f3a76457a74db801f05f22824451bc4ec7b056ef
data/.gitignore CHANGED
@@ -10,3 +10,6 @@
10
10
 
11
11
  # rspec failure tracking
12
12
  .rspec_status
13
+ .DS_Store
14
+ ./spec/rails_app/log/**
15
+
data/.rubocop.yml ADDED
@@ -0,0 +1,13 @@
1
+ require:
2
+ - rubocop-rspec
3
+ - rubocop-rails
4
+
5
+ inherit_gem:
6
+ snap-style:
7
+ - "rubocop/rubocop.yml"
8
+
9
+ Security/YAMLLoad:
10
+ Enabled: false
11
+
12
+ Metrics/BlockLength:
13
+ Max: 100
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.6.7
data/Gemfile CHANGED
@@ -2,3 +2,17 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in ssm_config.gemspec
4
4
  gemspec
5
+
6
+ group :development, :test do
7
+ gem 'pry-byebug'
8
+ gem 'rubocop', '~> 0.92', :require => false
9
+ gem 'rubocop-rails', :require => false
10
+ gem 'rubocop-rspec', :require => false
11
+ gem 'timecop'
12
+ end
13
+
14
+ source 'https://rubygems.pkg.github.com/bodyshopbidsdotcom' do
15
+ group :development do
16
+ gem 'snap-style'
17
+ end
18
+ end
data/README.md CHANGED
@@ -1,9 +1,13 @@
1
1
  # SsmConfig
2
2
 
3
- Any config YAML in the config directory can be accessed by calling `SsmConfig.config_name`.
4
- For example, if you wish to access `config/foo.yml`, just call `SsmConfig.foo` from anywhere in the app. The YAML will be parsed
5
- into a hash.
6
-
3
+ * ActiveRecord
4
+ - Any file in ActiveRecord with model name `SsmConfigRecord` can be accessed by calling `SsmConfig.file_name`
5
+ - All rows with the corresponding file name will be parsed into a hash
6
+ * `config` directory
7
+ - If file is not found in `SsmConfigRecord` (or the ActiveRecord doesn't exist), `SsmConfig` looks in the `config` directory
8
+ - Any YAML file in the directory with the corresponding file name will be parsed into a hash
9
+
10
+ These two are exclusive, with the former prioritized: i.e., the gem will look in the ActiveRecord model first, and then in the `config` directory if no such file is found.
7
11
  ## Installation
8
12
 
9
13
  Add this line to your application's Gemfile:
@@ -20,27 +24,78 @@ Or install it yourself as:
20
24
 
21
25
  $ gem install ssm_config
22
26
 
27
+ ## Setup
28
+
29
+ To utilize ActiveRecords, create the following model:
30
+ ```
31
+ rails generate model SsmConfigRecord file:string:index accessor_keys:string value:string datatype:string
32
+ ```
33
+
34
+ The supported datatypes are `[string, integer, boolean, float]`. The field `datatype` should contain the character that corresponds to the first character of the datatype (so one of `[s, i, b, f]`). This field is not case-sensitive (the gem also only checks the first character of `datatype`). Booleans should also be one of `[t, f]`, corresponding to `true` and `false`. Similarly, this is not case-sensitive and only the first character of the value (given the datatype is a boolean) will be checked.
35
+
36
+ An invalid entry will throw an exception (as well as an invalid boolean entry).
37
+
38
+ When migrating a file to the ActiveRecord, it is important to correctly input the accessor keys. The field `accessor_keys` represents a hashkey corresponding to a value in the hash: for the sequence of keys used to access a value, the corresponding accessor key will be the keys concatentated with a comma delimiter. For example, if `hash[:key1][:key2][:key3] = value`, the corresponding accessor key would be the string `"key1,key2,key3"`. In the case that there is an array, we include the index embraced by brackets. Consider the following hash:
39
+
40
+ ```yml
41
+ any:
42
+ build:
43
+ docker:
44
+ - image: value1
45
+ steps:
46
+ - value2
47
+ - run: value3
48
+ ```
49
+ The accessor keys for `value1`, `value2`, and `value3` would be `"build,docker,[0],image"`, `"build,steps,[0]"`, and `"build,steps,[1],run"`, respectively.
50
+
51
+ ⚠️ **NOTE:** ⚠️ There should be no file name called `cache`, as this will call a method of the `SsmConfig` class. Also, all values read from the table will be strings.
23
52
  ## Usage
24
53
 
25
- Given `config/eft.yml`:
54
+
55
+ Given the following rows in `SsmConfigRecord`:
56
+
57
+ | file | accessor_keys | value |
58
+ | :---: | :------------: | :---: |
59
+ | eft | days_to_enter_bank_account,default | 3 |
60
+ | eft | days_to_enter_bank_account,company1,[0] | 2 |
61
+ | eft | days_to_enter_bank_account,company2 | 4|
62
+
63
+ ```ruby
64
+ SsmConfig.eft
65
+ => {"days_to_enter_bank_account"=>{"default"=>3, "company1"=>[2], "company2"=>4}}
66
+ ```
67
+ `SsmConfig` will always reconstruct the hash using all the rows with the corresponding file name. In the case that no such row exists, `SsmConfig` will look for `config/foo.yml`. For example, given `config/eft.yml`,
68
+
26
69
  ```yml
27
70
  any:
28
71
  days_to_enter_bank_account:
29
72
  default: 3
30
- company1: 2
73
+ company1:
74
+ - 2
31
75
  company2: 4
32
76
  ```
33
-
34
77
  ```ruby
35
78
  SsmConfig.eft
36
- => {"days_to_enter_bank_account"=>{"default"=>3, "company1"=>2, "company2"=>4}}
79
+ => {"days_to_enter_bank_account"=>{"default"=>3, "company1"=>[2], "company2"=>4}}
37
80
  ```
38
81
 
82
+ This search will be exclusive: i.e., if any row exists in the table then the gem will not look in `config`.
39
83
  ## Development
40
84
 
41
85
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
42
86
 
43
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
87
+ To install this gem onto your local machine, run `bundle exec rake install`.
88
+
89
+ To develop and test locally, include a path for your gem in the Gemfile of the desired application, i.e.,
90
+ ```
91
+ gem 'ssm_config', path: 'path'
92
+ ```
93
+
94
+ ## Release to RubyGems
95
+
96
+ To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
97
+ To do so, you need a RubyGems account and [to be listed as an owner](https://rubygems.org/gems/ssm_config/owners).
98
+ In the process, after pushing the tag, the console will hang. You will need to enter your RubyGems login and then its password.
44
99
 
45
100
  ## Contributing
46
101
 
data/Rakefile CHANGED
@@ -1,6 +1,7 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
-
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require File.expand_path('../spec/rails_app/config/application', __FILE__)
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
6
  task :default => :spec
7
+ # YouApp::Application.load_tasks
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "ssm_config"
3
+ require 'bundler/setup'
4
+ require 'ssm_config'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,6 @@ require "ssm_config"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
+ require 'byebug'
14
15
  IRB.start(__FILE__)
@@ -0,0 +1,13 @@
1
+ module SsmConfig
2
+ # Generic SsmConfig exception.
3
+ class Error < StandardError
4
+ end
5
+
6
+ # An unexpected option, perhaps a typo, was passed to the value in the case of a boolean datatype
7
+ class InvalidBoolean < Error
8
+ end
9
+
10
+ # The datatype entered is unsupported in SsmConfigRecord
11
+ class UnsupportedDatatype < Error
12
+ end
13
+ end
@@ -0,0 +1,93 @@
1
+ module SsmConfig
2
+ module SsmStorage
3
+ class Db
4
+ TABLE_NAME = 'ssm_config_records'.freeze
5
+ ACTIVE_RECORD_MODEL = 'SsmConfigRecord'.freeze
6
+ def initialize(file_name)
7
+ @file_name = file_name
8
+ end
9
+
10
+ def table_exists?
11
+ return active_record_model_exists? if active_record_exists? && constant_exists?
12
+ false
13
+ end
14
+
15
+ def hash
16
+ match_file = ACTIVE_RECORD_MODEL.constantize.where(:file => @file_name.to_s).order(:accessor_keys)
17
+ hashes = match_file.each_with_object({}) { |row, hash| hash[row.accessor_keys] = transform_class(row.value, row.datatype); }
18
+ insert_arrays(reconstruct_hash(hashes)).try(:with_indifferent_access)
19
+ end
20
+
21
+ private
22
+
23
+ def active_record_exists?
24
+ ActiveRecord::Base.connection.table_exists? TABLE_NAME
25
+ end
26
+
27
+ def active_record_model_exists?
28
+ ACTIVE_RECORD_MODEL.constantize.exists?(:file => @file_name.to_s)
29
+ end
30
+
31
+ def constant_exists?
32
+ Object.const_defined? ACTIVE_RECORD_MODEL
33
+ end
34
+
35
+ def convert_boolean(value)
36
+ value = value.to_s.downcase
37
+ return true if value[0] == 't'
38
+ return false if value[0] == 'f'
39
+ raise SsmConfig::InvalidBoolean, 'Not a valid boolean: must be one of true or false'
40
+ end
41
+
42
+ def transform_class(value, type)
43
+ possible_types = ['s', 'i', 'b', 'f']
44
+ raise SsmConfig::UnsupportedDatatype, 'Not a valid class: must be one of string, integer, boolean, or float' unless possible_types.include? type.to_s.downcase[0]
45
+ return value.send("to_#{type.to_s.downcase[0]}") unless type[0] == 'b'
46
+ convert_boolean(value)
47
+ end
48
+
49
+ def add_flag_for_array_index(key)
50
+ return "#{key}flag" if key[0] == '['
51
+ key
52
+ end
53
+
54
+ # given a hash from hashkey (sequence of keys delimited by comma) to value, reconstruct hash
55
+ # arrays will not be formed properly, see insert_arrays
56
+ def reconstruct_hash(hash)
57
+ hash.each_with_object({}) do |(key, value), final_hash| # key will represent sequence of keys needed to get down to value
58
+ curr_hash = final_hash
59
+ delimited = key.split(',')
60
+ delimited[0..-2].each do |curr_key|
61
+ curr_key = add_flag_for_array_index(curr_key) # if bracket, indicates array index, add a flag indicating this is for an array index, and not some key name that had a bracket in it
62
+ curr_hash[curr_key] = {} unless curr_hash.key?(curr_key) # if key doesn't exist, initialize it
63
+ curr_hash = curr_hash[curr_key] # move into next level of hash
64
+ end
65
+ curr_hash[add_flag_for_array_index(delimited[-1])] = value # insert value
66
+ end
67
+ end
68
+
69
+ def array_index_flagged?(hash)
70
+ hash.all? do |key, _value|
71
+ key[0] == '[' && key[-4..-1] == 'flag'
72
+ end
73
+ end
74
+
75
+ # reconstruct_hash is unable to create arrays where needed, so parse through
76
+ # result and convert to arrays where needed
77
+ def insert_arrays(hash)
78
+ return hash unless hash.class == Hash
79
+ return hash if hash.keys.size.zero? # if there are no keys, return
80
+ if array_index_flagged?(hash) # if key has bracket + flag, it is an array index
81
+ hash = hash.values # convert hash to just the array of values
82
+ hash.each_with_index do |element, index|
83
+ hash[index] = insert_arrays(element) # recurse on each value
84
+ end
85
+ else # no change needed, recurse on next level of hash
86
+ hash.each do |key, value|
87
+ hash[key] = insert_arrays(value)
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,9 @@
1
+ module SsmConfig
2
+ module SsmStorage
3
+ class Empty
4
+ def hash
5
+ {}
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,25 @@
1
+ module SsmConfig
2
+ module SsmStorage
3
+ class Yml
4
+ CONFIG_PATH = 'config'.freeze
5
+ def initialize(file_name)
6
+ @file_name = file_name
7
+ end
8
+
9
+ def file_exists?
10
+ File.exist?(file_path)
11
+ end
12
+
13
+ def hash
14
+ yaml_loaded = YAML.load(ERB.new(File.read((file_path).to_s)).result)
15
+ (yaml_loaded[Rails.env] || yaml_loaded['any']).try(:with_indifferent_access)
16
+ end
17
+
18
+ private
19
+
20
+ def file_path
21
+ Rails.root.join(CONFIG_PATH, "#{@file_name}.yml")
22
+ end
23
+ end
24
+ end
25
+ end
data/lib/ssm_config.rb CHANGED
@@ -1,37 +1,56 @@
1
- class SsmConfig
2
- VERSION = "0.1.1"
1
+ require './lib/ssm_config/ssm_storage/db.rb'
2
+ require './lib/ssm_config/ssm_storage/yml.rb'
3
+ require './lib/ssm_config/ssm_storage/empty.rb'
4
+ require 'active_support/core_ext/hash/indifferent_access'
5
+ require 'active_support/time'
6
+ require './lib/ssm_config/errors.rb'
3
7
 
4
- class << self
8
+ module SsmConfig
9
+ VERSION = '1.1.0'.freeze
10
+ REFRESH_TIME = (30.minutes).freeze
5
11
 
12
+ class << self
6
13
  def method_missing(meth, *args, &block)
7
- config_file = Rails.root.join('config', "#{meth}.yml")
14
+ result = populate(meth)
15
+ super if result == false
16
+ result
17
+ end
8
18
 
9
- if File.exists?(config_file)
10
- write_config_accessor_for(meth)
11
- self.send(meth)
12
- else
13
- super
14
- end
19
+ def respond_to_missing?(meth, *_args)
20
+ determine_query(meth).present?
21
+ end
22
+
23
+ def last_processed_time
24
+ @last_processed_time ||= ActiveSupport::HashWithIndifferentAccess.new
15
25
  end
16
26
 
17
27
  private
18
28
 
19
- def parse_config_file(filename)
20
- YAML.load(ERB.new(File.read("#{Rails.root}/config/#{filename}")).result).symbolize_keys
29
+ def determine_query(meth)
30
+ query_database = SsmConfig::SsmStorage::Db.new(meth)
31
+ query_yml = SsmConfig::SsmStorage::Yml.new(meth)
32
+ return query_database if query_database.table_exists?
33
+ return query_yml if query_yml.file_exists?
34
+ nil
21
35
  end
22
36
 
23
- def parse_config_file_with_env(filename)
24
- yaml_loaded = YAML.load(ERB.new(File.read("#{Rails.root}/config/#{filename}")).result)
25
- (yaml_loaded[Rails.env] || yaml_loaded['any']).try(:with_indifferent_access)
37
+ def populate(meth)
38
+ query = determine_query(meth)
39
+
40
+ return false if query.blank?
41
+ self.last_processed_time[meth] = Time.zone.now
42
+ write_config_accessor_for(meth) unless method_defined?(meth.to_sym)
43
+ instance_variable_set("@#{meth}".to_sym, nil)
44
+ self.send(meth, query)
26
45
  end
27
46
 
28
47
  def write_config_accessor_for(meth)
29
- self.instance_eval %Q{
30
- def #{meth}
31
- @#{meth} ||= parse_config_file_with_env('#{meth}.yml')
32
- end
33
- }
48
+ self.instance_eval %{
49
+ def #{meth}(obj = SsmConfig::SsmStorage::Empty.new)
50
+ return self.send(:populate, "#{meth}") if self.last_processed_time["#{meth}".to_sym] < Time.zone.now - REFRESH_TIME
51
+ @#{meth} ||= obj&.hash
52
+ end
53
+ }, __FILE__, __LINE__ - 5
34
54
  end
35
-
36
55
  end
37
56
  end
data/ssm_config.gemspec CHANGED
@@ -1,34 +1,36 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'ssm_config'
5
4
 
6
5
  Gem::Specification.new do |spec|
7
- spec.name = "ssm_config"
6
+ spec.name = 'ssm_config'
8
7
  spec.version = SsmConfig::VERSION
9
- spec.authors = ["Santiago Herrera"]
10
- spec.email = ["santiago@snapsheet.me"]
8
+ spec.authors = ['Santiago Herrera']
9
+ spec.email = ['santiago@snapsheet.me']
11
10
 
12
- spec.summary = %q{YML file loader and parser for Rails}
13
- spec.homepage = "https://github.com/bodyshopbidsdotcom/ssm_config"
14
- spec.license = "MIT"
11
+ spec.summary = 'YML file loader and parser for Rails'
12
+ spec.homepage = 'https://github.com/bodyshopbidsdotcom/ssm_config'
13
+ spec.license = 'MIT'
15
14
 
16
15
  if spec.respond_to?(:metadata)
17
- spec.metadata['allowed_push_host'] = "https://rubygems.org"
16
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
18
17
  else
19
- raise "RubyGems 2.0 or newer is required to protect against " \
20
- "public gem pushes."
18
+ raise 'RubyGems 2.0 or newer is required to protect against ' \
19
+ 'public gem pushes.'
21
20
  end
22
21
 
23
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
22
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
24
23
  f.match(%r{^(test|spec|features)/})
25
24
  end
26
- spec.bindir = "exe"
25
+ spec.bindir = 'exe'
27
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
- spec.require_paths = ["lib"]
27
+ spec.require_paths = ['lib']
29
28
 
30
- spec.add_development_dependency "bundler", "~> 1.14"
31
- spec.add_development_dependency "rake", "~> 10.0"
32
- spec.add_development_dependency "rspec", "~> 3.0"
33
- spec.add_dependency "rails", ">= 3", "< 7"
29
+ spec.add_development_dependency 'bundler', '~> 1.14'
30
+ spec.add_development_dependency 'rake', '~> 10.0'
31
+ spec.add_development_dependency 'rspec', '~> 3.0'
32
+ spec.add_development_dependency 'rspec-rails'
33
+ spec.add_dependency 'rails', '>= 3', '< 7'
34
+ spec.add_development_dependency 'sqlite3', '1.4'
35
+ spec.required_ruby_version = '>=2.6'
34
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ssm_config
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Santiago Herrera
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-09-15 00:00:00.000000000 Z
11
+ date: 2023-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rails
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -72,6 +86,20 @@ dependencies:
72
86
  - - "<"
73
87
  - !ruby/object:Gem::Version
74
88
  version: '7'
89
+ - !ruby/object:Gem::Dependency
90
+ name: sqlite3
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '='
94
+ - !ruby/object:Gem::Version
95
+ version: '1.4'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - '='
101
+ - !ruby/object:Gem::Version
102
+ version: '1.4'
75
103
  description:
76
104
  email:
77
105
  - santiago@snapsheet.me
@@ -81,6 +109,8 @@ extra_rdoc_files: []
81
109
  files:
82
110
  - ".gitignore"
83
111
  - ".rspec"
112
+ - ".rubocop.yml"
113
+ - ".ruby-version"
84
114
  - ".travis.yml"
85
115
  - CODE_OF_CONDUCT.md
86
116
  - Gemfile
@@ -90,6 +120,10 @@ files:
90
120
  - bin/console
91
121
  - bin/setup
92
122
  - lib/ssm_config.rb
123
+ - lib/ssm_config/errors.rb
124
+ - lib/ssm_config/ssm_storage/db.rb
125
+ - lib/ssm_config/ssm_storage/empty.rb
126
+ - lib/ssm_config/ssm_storage/yml.rb
93
127
  - ssm_config.gemspec
94
128
  homepage: https://github.com/bodyshopbidsdotcom/ssm_config
95
129
  licenses:
@@ -104,14 +138,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
104
138
  requirements:
105
139
  - - ">="
106
140
  - !ruby/object:Gem::Version
107
- version: '0'
141
+ version: '2.6'
108
142
  required_rubygems_version: !ruby/object:Gem::Requirement
109
143
  requirements:
110
144
  - - ">="
111
145
  - !ruby/object:Gem::Version
112
146
  version: '0'
113
147
  requirements: []
114
- rubygems_version: 3.2.33
148
+ rubygems_version: 3.0.9
115
149
  signing_key:
116
150
  specification_version: 4
117
151
  summary: YML file loader and parser for Rails