app_config_for 0.0.1 → 0.0.4.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: 16aa403545b3c7bb28165f904eb60d51138293dfbc8269c76bc2f13ec3cf44a0
4
- data.tar.gz: 707c8d7280805a21df63505882cabd48ac9e7a9536b717fb9054bd50c2b83ec9
3
+ metadata.gz: 228991a28438bec90c4aa9f06b33850a5ee4034b01a7ec87a33c90fa77ace37d
4
+ data.tar.gz: eed01754e58c59c3ea8d58c23e809f8d9c3ae1b6fe5a3b24958a1a173f01a87c
5
5
  SHA512:
6
- metadata.gz: a7996b0d285f25d1a874ed19593ed4773d20d6eeb55237bfdccf3f61c9045a49c73a703ffeeac014e3035c71f131f1f0b7f98f0a205fe7fb71250778e1985d58
7
- data.tar.gz: 372bb10b3e6f63754a65608b7d67553c6fd49ec821b8efe101f067e9060f816ab1ab023fafef38b5b37af1a0dc1495e0cc073120805fef15657452946bfa788d
6
+ metadata.gz: d05a93814a9b8162890151e89f2e83e99f29c58478e371aeef49c63c29713a01d1c86ab3b4a28ee320d2eb639dd51879d107dd820c9f173c3bae958c626396b9
7
+ data.tar.gz: b9dc3d8224b2e0c05167da273faf7df940c1397022d22768af8cce85101de32993a56cc2e13bca5b2d8cb656e7885251a962486856388ad1871be9163784816e
@@ -22,4 +22,17 @@ module AppConfigFor
22
22
  super "Could not load configuration file: #{@file}\n#{@original_exception.message}"
23
23
  end
24
24
  end
25
+
26
+ class InvalidEnvInheritanceStyle < Error
27
+
28
+ attr_reader :attempted, :valid
29
+
30
+ def initialize(attempted)
31
+ @attempted = attempted
32
+ @valid = EnvPrefixInheritanceStyles.dup
33
+ super "Invalid inheritance style #{@attempted.inspect}. Please use one of the following: #{@valid.map(&:inspect).join(', ')}"
34
+ end
35
+
36
+ end
37
+
25
38
  end
@@ -0,0 +1,16 @@
1
+ module AppConfigFor
2
+
3
+ def self.gem_version
4
+ Gem::Version.new(VERSION::STRING)
5
+ end
6
+
7
+ module VERSION
8
+ MAJOR = 0
9
+ MINOR = 0
10
+ TINY = 4
11
+ PRE = 1
12
+
13
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
14
+ end
15
+
16
+ end
@@ -0,0 +1,45 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+ name = File.basename(__dir__).classify
3
+ STDERR.puts "#{name}: Warning! Outdated version of ActiveSupport active! To avoid security issues, please upgrade your version of ActiveSupport to at least 6.1.4."
4
+ if ActiveSupport.gem_version < Gem::Version.new('6.1.0')
5
+ puts "#{name}: Loading legacy support for ActiveSupport version #{ActiveSupport.gem_version}."
6
+
7
+ # Quick and dirty backport. This won't be here long. Just enough to support AppConfigFor during some legacy upgrades.
8
+ require "active_support/string_inquirer"
9
+ require "erb"
10
+ require "yaml"
11
+
12
+ module ActiveSupport
13
+ class EnvironmentInquirer < StringInquirer
14
+
15
+ Environments = %w(development test production)
16
+
17
+ def initialize(env)
18
+ super(env)
19
+ Environments.each { |e| instance_variable_set(:"@#{e}", env == e) }
20
+ end
21
+
22
+ Environments.each { |e| define_method("#{e}?") { instance_variable_get("@#{e}") }}
23
+ end
24
+
25
+ class ConfigurationFile
26
+ def initialize(file_name)
27
+ @file_name = file_name
28
+ @config = File.read(file_name)
29
+ warn(file_name + ' contains invisible non-breaking spaces.') if @config.match?("\u00A0")
30
+ end
31
+
32
+ def self.parse(file_name)
33
+ new(file_name).parse
34
+ end
35
+
36
+ def parse
37
+ YAML.load(ERB.new(@config).result) || {}
38
+ rescue Psych::SyntaxError => e
39
+ raise "YAML syntax error occurred while parsing #{@file_name}. Error: #{e.message}"
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -1,5 +1,10 @@
1
1
  # frozen_string_literal: true
2
+ require_relative "gem_version"
2
3
 
3
4
  module AppConfigFor
4
- VERSION = "0.0.1"
5
+
6
+ def self.version
7
+ gem_version
8
+ end
9
+
5
10
  end
@@ -2,27 +2,46 @@
2
2
 
3
3
  require_relative "app_config_for/version"
4
4
  require_relative "app_config_for/errors"
5
- require 'active_support/environment_inquirer'
6
- require 'active_support/configuration_file'
5
+
6
+ require 'active_support/gem_version'
7
+ if ActiveSupport.gem_version >= Gem::Version.new('6.1.4')
8
+ require 'active_support/environment_inquirer'
9
+ require 'active_support/configuration_file'
10
+ else
11
+ require_relative 'app_config_for/legacy_support'
12
+ end
13
+
7
14
  require 'active_support/core_ext/object/blank'
8
15
  require 'active_support/core_ext/string/inflections'
9
- require "active_support/core_ext/hash/indifferent_access"
16
+ require 'active_support/core_ext/hash/indifferent_access'
10
17
  require 'active_support/ordered_options'
11
18
  require 'active_support/core_ext/object/try'
12
19
 
13
20
  module AppConfigFor
14
21
 
22
+ EnvPrefixInheritanceStyles = %i(none namespace class namespace_class class_namespace)
23
+
15
24
  def initialize(*args)
16
25
  add_env_prefix
17
26
  super
18
27
  end
19
28
 
20
- def add_env_prefix(prefix = nil, at_beginning: true)
21
- env_prefixes(all: false, dup: false).send(at_beginning ? :unshift : :push, AppConfigFor.prefix_from(prefix || self)).uniq!
29
+ def add_env_prefix(prefix = nil, at_beginning = true)
30
+ env_prefixes(false, false).send(at_beginning ? :unshift : :push, AppConfigFor.prefix_from(prefix || self)).uniq!
31
+ end
32
+
33
+ def add_config_directory(new_directory)
34
+ (additional_config_directories << Pathname.new(new_directory).expand_path).uniq!
35
+ end
36
+
37
+ def additional_config_directories
38
+ @additional_config_directories ||= []
22
39
  end
23
40
 
24
41
  def config_directories
25
- directories = ['Rails'.safe_constantize&.application&.paths, try(:paths)].compact.map { |root| Pathname.new(root["config"].existent.first) }
42
+ directories = ['Rails'.safe_constantize&.application&.paths, try(:paths)].compact.map { |root| root["config"].existent.first }.compact
43
+ directories.map! { |directory| Pathname.new(directory).expand_path }
44
+ directories.concat additional_config_directories
26
45
  directories.push(Pathname.getwd + 'config')
27
46
  directories.uniq
28
47
  end
@@ -36,7 +55,7 @@ module AppConfigFor
36
55
  end
37
56
 
38
57
  def config_files(name = nil)
39
- name = AppConfigFor.yml_name_from(name || self)
58
+ name = AppConfigFor.yml_name_from(name || config_name)
40
59
  config_directories.map { |directory| directory + name }
41
60
  end
42
61
 
@@ -44,8 +63,8 @@ module AppConfigFor
44
63
  !config_file(name).blank?
45
64
  end
46
65
 
47
- def config_for(name, environment: nil)
48
- config, shared = config_options(name).fetch_values((environment || env).to_sym, :shared) {nil}
66
+ def config_for(name, env: nil)
67
+ config, shared = config_options(name).fetch_values((env || self.env).to_sym, :shared) {nil}
49
68
  config ||= shared
50
69
 
51
70
  if config.is_a?(Hash)
@@ -56,53 +75,70 @@ module AppConfigFor
56
75
  config
57
76
  end
58
77
 
78
+ def config_name
79
+ @config_name ||= self
80
+ end
81
+
82
+ def config_name=(new_config_name)
83
+ @config_name = new_config_name
84
+ end
85
+
59
86
  def config_options(name = nil)
60
87
  file = name.is_a?(Pathname) ? name : config_file(name)
61
88
  ActiveSupport::ConfigurationFile.parse(file.to_s).deep_symbolize_keys
62
89
  rescue SystemCallError => exception
63
90
  raise ConfigNotFound.new(name.is_a?(Pathname) ? name : config_files(name), exception)
64
91
  rescue => exception
65
- raise LoadError.new(file, exception)
92
+ raise file ? LoadError.new(file, exception) : exception
66
93
  end
67
94
 
68
- def configured(environment: nil)
69
- config_for(self, environment: environment)
95
+ def configured(reload = false, env: nil)
96
+ @configured = config_for(nil, env: env) if reload || @configured.nil?
97
+ @configured
70
98
  end
71
99
 
72
- def env(reload: false)
100
+ def env(reload = false)
73
101
  @env = ActiveSupport::EnvironmentInquirer.new(AppConfigFor.env_name(env_prefixes)) if reload || @env.nil?
74
102
  @env
75
103
  end
76
104
 
77
- def env_prefixes(all: true, dup: true)
105
+ def env_prefix_inheritance
106
+ @env_prefix_inheritance ||= :namespace
107
+ end
108
+
109
+ def env_prefix_inheritance=(style)
110
+ @env_prefix_inheritance = AppConfigFor.verified_style!(style)
111
+ end
112
+
113
+ def env_prefixes(all = true, dup = true)
78
114
  @env_prefixes ||= []
79
115
  if all
80
- @env_prefixes + AppConfigFor.progenitor_of(self).env_prefixes(all: true)
116
+ @env_prefixes + AppConfigFor.progenitor_prefixes_of(self)
81
117
  else
82
118
  dup ? @env_prefixes.dup : @env_prefixes
83
119
  end
84
120
  end
85
121
 
86
- def remove_env_prefix(prefix, all: false)
122
+ def remove_env_prefix(prefix, all = false)
87
123
  if all
88
124
  remove_env_prefix(prefix)
89
- AppConfigFor.progenitor_of(self).remove_env_prefix(prefix, all: true)
125
+ AppConfigFor.progenitor_of(self)&.remove_env_prefix(prefix, all)
90
126
  else
91
- env_prefixes(all: false, dup: false).delete(AppConfigFor.prefix_from(prefix))
127
+ env_prefixes(false, false).delete(AppConfigFor.prefix_from(prefix))
92
128
  end
93
129
  end
94
130
 
95
131
  class << self
96
132
 
97
- def add_env_prefix(prefix)
98
- env_prefixes(dup: false).push(prefix_from(prefix))
133
+ def add_env_prefix(prefix, at_beginning = true)
134
+ env_prefixes(false, false).send(at_beginning ? :unshift : :push, prefix_from(prefix)).uniq!
99
135
  end
100
136
 
101
137
  def env_name(prefixes = env_prefixes)
102
138
  prefixes.inject(nil) { |current_env, name| current_env || ENV["#{name.to_s.upcase}_ENV"].presence } || 'development'
103
139
  end
104
140
 
105
- def env_prefixes(all: true, dup: true)
141
+ def env_prefixes(_all = true, dup = true)
106
142
  # all is ignored as we are at the end of the chain
107
143
  @env_prefixes ||= [:rails, :rack]
108
144
  dup ? @env_prefixes.dup : @env_prefixes
@@ -119,6 +155,27 @@ module AppConfigFor
119
155
  end.deconstantize.safe_constantize
120
156
  end
121
157
 
158
+ # Not used internally, this is a convenience method to study what progenitors are used during namespace dives
159
+ def namespaces_of(object)
160
+ (object = [namespace_of(object)]).each { |x| x && object << namespace_of(x) }[0..-2]
161
+ end
162
+
163
+ def parent_of(object)
164
+ case object
165
+ when String
166
+ object.safe_constantize
167
+ when Class
168
+ object.superclass
169
+ else
170
+ object.class
171
+ end
172
+ end
173
+
174
+ # Not used internally, this is a convenience method to study what progenitors are used during class dives
175
+ def parents_of(object)
176
+ (object = [parent_of(object)]).each { |x| x && object << parent_of(x) }[0..-2]
177
+ end
178
+
122
179
  def prefix_from(object)
123
180
  if object.is_a?(Symbol)
124
181
  object
@@ -134,19 +191,41 @@ module AppConfigFor
134
191
  object.class.name
135
192
  end.underscore.gsub('/','_').to_sym
136
193
  end
194
+ end
137
195
 
196
+ def progenitor_of(object, style = nil)
197
+ style = verified_style!(style, object)
198
+ command = {namespace: :namespace_of, class: :parent_of}[style] # Todo, deal with the other styles by doing nothing and not crashing or something.
199
+ object && command && send(command, object).yield_self { |n| n && (n.respond_to?(:env_prefixes) ? n : progenitor_of(n)) }
138
200
  end
139
201
 
140
- # First namespace of the object that supports env_prefixes or AppConfig
141
- def progenitor_of(object)
142
- (namespace_of(object) || self).yield_self do |namespace|
143
- namespace.respond_to?(:env_prefixes) ? namespace : progenitor_of(namespace)
144
- end
202
+ def progenitor_prefixes_of(object, style = nil, all = true)
203
+ Array(progenitor_of(object, style)&.env_prefixes(all))
145
204
  end
146
205
 
147
- def remove_env_prefix(prefix, all: false)
148
- # all is ignored as we are at the end of the chain
149
- env_prefixes(dup: false).delete(prefix_from(prefix))
206
+ def progenitors_of(object, style = nil, terminate = true)
207
+ style = verified_style!(style, object)
208
+ terminate = terminate && style != :none
209
+ if object && style != :none
210
+ styles = style.to_s.split('_')
211
+ if styles.size > 1
212
+ styles.flat_map{ |style| progenitors_of(object, style, false) }
213
+ else
214
+ Array(progenitor_of(object, style)).yield_self { |x| x + progenitors_of(x.last, nil, false) }
215
+ end
216
+ else
217
+ []
218
+ end.yield_self { |result| terminate ? result.reverse.uniq.reverse + [self] : result }
219
+ end
220
+
221
+ def remove_env_prefix(prefix, all = false)
222
+ env_prefixes(all, false).delete(prefix_from(prefix))
223
+ end
224
+
225
+ def verified_style!(style, object = nil)
226
+ style ||= object.respond_to?(:env_prefix_inheritance) ? object.send(:env_prefix_inheritance) : :namespace
227
+ style = style.try(:to_sym) || style.to_s.to_sym
228
+ EnvPrefixInheritanceStyles.include?(style) ? style : raise(InvalidEnvInheritanceStyle.new(style))
150
229
  end
151
230
 
152
231
  def yml_name_from(object)
@@ -166,17 +245,23 @@ module AppConfigFor
166
245
 
167
246
  private
168
247
 
248
+ def prep_base(base)
249
+ base.add_env_prefix
250
+ gem = Gem.loaded_specs[base.name.underscore]
251
+ base.add_config_directory(gem.gem_dir + '/config') if gem
252
+ end
253
+
169
254
  def extended(base)
170
255
  # Todo: Add the ability to check the default environments directly from base if the methods don't yet exist.
171
256
  # ie: base.development? is the same as base.env.development?
172
- base.add_env_prefix
257
+ prep_base(base)
173
258
  end
174
259
 
175
- # Todo: Determine progenitor_of with respect to combining inheritance with namespace scoping
176
- # def included(base)
177
- # base.add_env_prefix
178
- # end
260
+ def included(base)
261
+ prep_base(base)
262
+ end
179
263
 
180
264
  end
181
265
 
182
266
  end
267
+
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: app_config_for
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frank Hall
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-04-07 00:00:00.000000000 Z
11
+ date: 2022-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ - - "<"
18
21
  - !ruby/object:Gem::Version
19
- version: '7.0'
22
+ version: '8'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '5.0'
30
+ - - "<"
25
31
  - !ruby/object:Gem::Version
26
- version: '7.0'
32
+ version: '8'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rake
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -72,6 +78,8 @@ files:
72
78
  - Rakefile
73
79
  - lib/app_config_for.rb
74
80
  - lib/app_config_for/errors.rb
81
+ - lib/app_config_for/gem_version.rb
82
+ - lib/app_config_for/legacy_support.rb
75
83
  - lib/app_config_for/version.rb
76
84
  - sig/app_config_for.rbs
77
85
  homepage: https://github.com/ChapterHouse/app_config_for
@@ -79,8 +87,8 @@ licenses:
79
87
  - MIT
80
88
  metadata:
81
89
  homepage_uri: https://github.com/ChapterHouse/app_config_for
82
- source_code_uri: https://github.com/ChapterHouse/app_config_for/tree/v0.0.1
83
- changelog_uri: https://github.com/ChapterHouse/app_config_for/blob/v0.0.1/CHANGELOG.md
90
+ source_code_uri: https://github.com/ChapterHouse/app_config_for/tree/v0.0.4.1
91
+ changelog_uri: https://github.com/ChapterHouse/app_config_for/blob/v0.0.4.1/CHANGELOG.md
84
92
  post_install_message:
85
93
  rdoc_options: []
86
94
  require_paths:
@@ -89,7 +97,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
89
97
  requirements:
90
98
  - - ">="
91
99
  - !ruby/object:Gem::Version
92
- version: 2.6.0
100
+ version: 2.3.6
93
101
  required_rubygems_version: !ruby/object:Gem::Requirement
94
102
  requirements:
95
103
  - - ">="