app_config_for 0.0.1 → 0.0.4.1

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: 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
  - - ">="