anyway_config 2.5.4 → 2.6.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anyway
4
+ # Contains a mapping between type IDs/names and deserializers
5
+ class TypeRegistry
6
+ class << self
7
+ def default
8
+ @default ||= TypeRegistry.new
9
+ end
10
+ end
11
+
12
+ def initialize
13
+ @registry = {}
14
+ end
15
+
16
+ def accept(name_or_object, &block)
17
+ if !block && !name_or_object.respond_to?(:call)
18
+ raise ArgumentError, "Please, provide a type casting block or an object implementing #call(val) method"
19
+ end
20
+
21
+ registry[name_or_object] = block || name_or_object
22
+ end
23
+
24
+ def deserialize(raw, type_id, array: false)
25
+ return if raw.nil?
26
+
27
+ caster =
28
+ if type_id.is_a?(Symbol) || type_id.nil?
29
+ registry.fetch(type_id) { raise ArgumentError, "Unknown type: #{type_id}" }
30
+ else
31
+ raise ArgumentError, "Type must implement #call(val): #{type_id}" unless type_id.respond_to?(:call)
32
+ type_id
33
+ end
34
+
35
+ if array
36
+ raw_arr = raw.is_a?(String) ? raw.split(/\s*,\s*/) : Array(raw)
37
+ raw_arr.map { it = _1;caster.call(it) }
38
+ else
39
+ caster.call(raw)
40
+ end
41
+ end
42
+
43
+ def dup
44
+ new_obj = self.class.allocate
45
+ new_obj.instance_variable_set(:@registry, registry.dup)
46
+ new_obj
47
+ end
48
+
49
+ private
50
+
51
+ attr_reader :registry
52
+ end
53
+
54
+ TypeRegistry.default.tap do |obj|
55
+ obj.accept(nil, &:itself)
56
+ obj.accept(:string, &:to_s)
57
+ obj.accept(:integer, &:to_i)
58
+ obj.accept(:float, &:to_f)
59
+
60
+ obj.accept(:date) do
61
+ require "date" unless defined?(::Date)
62
+
63
+ next _1 if _1.is_a?(::Date)
64
+
65
+ next _1.to_date if _1.respond_to?(:to_date)
66
+
67
+ ::Date.parse(_1)
68
+ end
69
+
70
+ obj.accept(:datetime) do
71
+ require "date" unless defined?(::Date)
72
+
73
+ next _1 if _1.is_a?(::DateTime)
74
+
75
+ next _1.to_datetime if _1.respond_to?(:to_datetime)
76
+
77
+ ::DateTime.parse(_1)
78
+ end
79
+
80
+ obj.accept(:uri) do
81
+ require "uri" unless defined?(::URI)
82
+
83
+ next _1 if _1.is_a?(::URI)
84
+
85
+ ::URI.parse(_1)
86
+ end
87
+
88
+ obj.accept(:boolean) do
89
+ _1.to_s.match?(/\A(true|t|yes|y|1)\z/i)
90
+ end
91
+ end
92
+
93
+ unless "".respond_to?(:safe_constantize)
94
+ require "anyway/ext/string_constantize"
95
+ using Anyway::Ext::StringConstantize
96
+ end
97
+
98
+ # TypeCaster is an object responsible for type-casting.
99
+ # It uses a provided types registry and mapping, and also
100
+ # accepts a fallback typecaster.
101
+ class TypeCaster
102
+ using Ext::DeepDup
103
+ using Ext::Hash
104
+
105
+ def initialize(mapping, registry: TypeRegistry.default, fallback: ::Anyway::AutoCast)
106
+ @mapping = mapping.deep_dup
107
+ @registry = registry
108
+ @fallback = fallback
109
+ end
110
+
111
+ def coerce(key, val, config: mapping)
112
+ caster_config = config[key.to_sym]
113
+
114
+ return fallback.coerce(key, val) unless caster_config
115
+
116
+ case caster_config
117
+ in Hash[array:, type:, **nil]
118
+ registry.deserialize(val, type, array: array)
119
+ in Hash[config: subconfig]
120
+ subconfig = subconfig.safe_constantize if subconfig.is_a?(::String)
121
+ raise ArgumentError, "Config is not found: #{subconfig}" unless subconfig
122
+
123
+ subconfig.new(val)
124
+ in Hash
125
+ return val unless val.is_a?(Hash)
126
+
127
+ caster_config.each do |k, v|
128
+ ks = k.to_s
129
+ next unless val.key?(ks)
130
+
131
+ val[ks] = coerce(k, val[ks], config: caster_config)
132
+ end
133
+
134
+ val
135
+ else
136
+ registry.deserialize(val, caster_config)
137
+ end
138
+ end
139
+
140
+ private
141
+
142
+ attr_reader :mapping, :registry, :fallback
143
+ end
144
+ end
@@ -13,9 +13,9 @@ module Anyway
13
13
 
14
14
  case val
15
15
  when Hash
16
- val.transform_values { call(_1) }
16
+ val.transform_values { call(it) }
17
17
  when ARRAY_RXP
18
- val.split(/\s*,\s*/).map { call(_1) }
18
+ val.split(/\s*,\s*/).map { call(it) }
19
19
  when /\A(true|t|yes|y)\z/i
20
20
  true
21
21
  when /\A(false|f|no|n)\z/i
data/lib/anyway/config.rb CHANGED
@@ -154,7 +154,7 @@ module Anyway # :nodoc:
154
154
  if block
155
155
  load_callbacks << BlockCallback.new(block)
156
156
  else
157
- load_callbacks.push(*names.map { NamedCallback.new(_1) })
157
+ load_callbacks.push(*names.map { NamedCallback.new(it) })
158
158
  end
159
159
  end
160
160
 
@@ -380,7 +380,7 @@ module Anyway # :nodoc:
380
380
  trace&.keep_if { |key| self.class.config_attributes.include?(key.to_sym) }
381
381
 
382
382
  # Run on_load callbacks
383
- self.class.load_callbacks.each { _1.apply_to(self) }
383
+ self.class.load_callbacks.each { it.apply_to(self) }
384
384
 
385
385
  # Set trace after we write all the values to
386
386
  # avoid changing the source to accessor
@@ -389,14 +389,14 @@ module Anyway # :nodoc:
389
389
  self
390
390
  end
391
391
 
392
- def load_from_sources(base_config, **options)
392
+ def load_from_sources(base_config, **)
393
393
  Anyway.loaders.each do |(_id, loader)|
394
- Utils.deep_merge!(base_config, loader.call(**options))
394
+ Utils.deep_merge!(base_config, loader.call(**))
395
395
  end
396
396
  base_config
397
397
  end
398
398
 
399
- def dig(*keys) = values.dig(*keys)
399
+ def dig(*) = values.dig(*)
400
400
 
401
401
  def to_h() = values.deep_dup.deep_freeze
402
402
 
@@ -6,8 +6,8 @@ module Anyway
6
6
  include Tracing
7
7
 
8
8
  class << self
9
- def call(local: Anyway::Settings.use_local_files, **opts)
10
- new(local:).call(**opts)
9
+ def call(local: Anyway::Settings.use_local_files, **)
10
+ new(local:).call(**)
11
11
  end
12
12
  end
13
13
 
@@ -26,12 +26,12 @@ module Anyway
26
26
  value.dig(...)
27
27
  end
28
28
 
29
- def record_value(val, *path, **opts)
29
+ def record_value(val, *path, **)
30
30
  key = path.pop
31
31
  trace = if val.is_a?(Hash)
32
- Trace.new.tap { _1.merge_values(val, **opts) }
32
+ Trace.new.tap { it.merge_values(val, **) }
33
33
  else
34
- Trace.new(:value, val, **opts)
34
+ Trace.new(:value, val, **)
35
35
  end
36
36
 
37
37
  target_trace = path.empty? ? self : value.dig(*path)
@@ -40,14 +40,14 @@ module Anyway
40
40
  val
41
41
  end
42
42
 
43
- def merge_values(hash, **opts)
43
+ def merge_values(hash, **)
44
44
  return hash unless hash
45
45
 
46
46
  hash.each do |key, val|
47
47
  if val.is_a?(Hash)
48
- value[key.to_s].merge_values(val, **opts)
48
+ value[key.to_s].merge_values(val, **)
49
49
  else
50
- value[key.to_s] = Trace.new(:value, val, **opts)
50
+ value[key.to_s] = Trace.new(:value, val, **)
51
51
  end
52
52
  end
53
53
 
@@ -84,7 +84,7 @@ module Anyway
84
84
 
85
85
  def to_h
86
86
  if trace?
87
- value.transform_values(&:to_h).tap { _1.default_proc = nil }
87
+ value.transform_values(&:to_h).tap { it.default_proc = nil }
88
88
  else
89
89
  {value:, source:}
90
90
  end
@@ -174,13 +174,13 @@ module Anyway
174
174
 
175
175
  module_function
176
176
 
177
- def trace!(type, *path, **opts)
177
+ def trace!(type, *path, **)
178
178
  return yield unless Tracing.tracing?
179
179
  val = yield
180
180
  if val.is_a?(Hash)
181
- Tracing.current_trace.merge_values(val, type:, **opts)
181
+ Tracing.current_trace.merge_values(val, type:, **)
182
182
  elsif !path.empty?
183
- Tracing.current_trace.record_value(val, *path, type:, **opts)
183
+ Tracing.current_trace.record_value(val, *path, type:, **)
184
184
  end
185
185
  val
186
186
  end
@@ -34,7 +34,7 @@ module Anyway
34
34
 
35
35
  if array
36
36
  raw_arr = raw.is_a?(String) ? raw.split(/\s*,\s*/) : Array(raw)
37
- raw_arr.map { caster.call(_1) }
37
+ raw_arr.map { caster.call(it) }
38
38
  else
39
39
  caster.call(raw)
40
40
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Anyway # :nodoc:
4
- VERSION = "2.5.4"
4
+ VERSION = "2.6.1"
5
5
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/commands/credentials/credentials_command"
4
+
5
+ module Rails
6
+ module Command
7
+ class LocalCredentialsCommand < CredentialsCommand
8
+ desc "edit", "Open the decrypted local credentials in `$VISUAL` or `$EDITOR` for editing"
9
+ def edit
10
+ load_environment_config!
11
+ load_generators
12
+
13
+ @content_path = "config/credentials/local.yml.enc"
14
+ @key_path = "config/credentials/local.key"
15
+
16
+ ensure_encryption_key_has_been_added
17
+ ensure_credentials_have_been_added
18
+ ensure_diffing_driver_is_configured
19
+
20
+ change_credentials_in_system_editor
21
+ end
22
+ end
23
+ end
24
+ end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anyway_config
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.4
4
+ version: 2.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-16 00:00:00.000000000 Z
11
+ date: 2023-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-next-core
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.14.0
19
+ version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.14.0
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: ammeter
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -70,16 +70,16 @@ dependencies:
70
70
  name: ruby-next
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.14.0
75
+ version: '1.0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.14.0
82
+ version: '1.0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: webmock
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -138,6 +138,13 @@ files:
138
138
  - lib/.rbnext/3.1/anyway/env.rb
139
139
  - lib/.rbnext/3.1/anyway/loaders/base.rb
140
140
  - lib/.rbnext/3.1/anyway/tracing.rb
141
+ - lib/.rbnext/3.2/anyway/config.rb
142
+ - lib/.rbnext/3.2/anyway/loaders/base.rb
143
+ - lib/.rbnext/3.2/anyway/tracing.rb
144
+ - lib/.rbnext/3.4/anyway/auto_cast.rb
145
+ - lib/.rbnext/3.4/anyway/config.rb
146
+ - lib/.rbnext/3.4/anyway/tracing.rb
147
+ - lib/.rbnext/3.4/anyway/type_casting.rb
141
148
  - lib/anyway.rb
142
149
  - lib/anyway/auto_cast.rb
143
150
  - lib/anyway/config.rb
@@ -185,6 +192,7 @@ files:
185
192
  - lib/generators/anyway/install/USAGE
186
193
  - lib/generators/anyway/install/install_generator.rb
187
194
  - lib/generators/anyway/install/templates/application_config.rb.tt
195
+ - lib/rails/commands/local_credentials/local_credentials_command.rb
188
196
  - sig/anyway_config.rbs
189
197
  - sig/manifest.yml
190
198
  homepage: http://github.com/palkan/anyway_config
@@ -212,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
220
  - !ruby/object:Gem::Version
213
221
  version: '0'
214
222
  requirements: []
215
- rubygems_version: 3.4.8
223
+ rubygems_version: 3.4.20
216
224
  signing_key:
217
225
  specification_version: 4
218
226
  summary: Configuration DSL for Ruby libraries and applications