fig_tree 0.0.5 → 0.2.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: eeed3763d9c3d8589a8ff0426ef7bcbc6b27ead3b61a4e930fc4c043a3243ab2
4
- data.tar.gz: 99530c56bbed379a3a8ccdf8558fda0ff89d32eff73d3b33d95fa483c30945d8
3
+ metadata.gz: 434800cb06edc670398ffd76cd43a2464bbaed074fa333e0c5dbd0bad01a7301
4
+ data.tar.gz: b744f1fe4e76f2d14e7beb18b78ebe2e916dd159cd011c29bb729418c98fcca8
5
5
  SHA512:
6
- metadata.gz: 123fb1d12ecdc117a89e0f1b1c8cc8dcce7a124307d4b2ec6f1d9f89f80d0e727018f43f0b235a4919c46065b1b7396814625710302e5345871f44aa199b64df
7
- data.tar.gz: 755b79c660b3c2c72c9fd6389102164ff129f6d35cbe818f1538630d88e5cbcc57ee69b80839bd18c0e56eac0db85f89cb9cce82df743b2b64de6abb401c55b0
6
+ metadata.gz: f456847c8fada09cb5b116aae97fe28d8292b8ad0845cde50576d6604bb72fa76ed26c5812b41306319162433d64ad713151ca601c8f21ef45d8cb7263585ce6
7
+ data.tar.gz: '09b8090d10adcd029531a93be4d29067b6e9b2a99fd41a155d2acae3c4d390e04d796c59bf7a2cdfbb60cd55402c6476c576ea4585784fa8674cf14a2906957b'
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.0.0
1
+ 3.2.2
data/CHANGELOG.md CHANGED
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## UNRELEASED
9
9
 
10
+ ## [0.2.0] - 2024-05-31
11
+ - Add `removed` and `keep_removed_configs`
12
+ - Add `trap_config`
13
+
14
+ ## [0.0.6] - 2023-08-29
15
+ - Add RBI files and DSL compiler for Sorbet
16
+
10
17
  ## [0.0.5] - 2023-04-04
11
18
  - Remove Deimos-specific Rake Task skip
12
19
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FigTree
4
- VERSION = '0.0.5'
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/fig_tree.rb CHANGED
@@ -9,14 +9,19 @@ require 'active_support/callbacks'
9
9
 
10
10
  # Configuration module.
11
11
  module FigTree
12
+
13
+ class << self
14
+ attr_accessor :keep_removed_configs
15
+ end
16
+
12
17
  extend ActiveSupport::Concern
13
18
 
14
- ConfigValue = Struct.new(:value, :default_value, :default_proc, :deprecation) do
19
+ ConfigValue = Struct.new(:value, :default_value, :default_proc, :deprecation, :removed) do
15
20
 
16
21
  # Reset value back to default.
17
- def reset!
22
+ def reset_values
18
23
  if self.value.is_a?(ConfigStruct)
19
- self.value.reset!
24
+ self.value.reset_values
20
25
  else
21
26
  self.value = self.default_value
22
27
  end
@@ -24,12 +29,19 @@ module FigTree
24
29
 
25
30
  # :nodoc:
26
31
  def clone_and_reset
27
- setting = ConfigValue.new(self.value, self.default_value,
32
+ val = self.value.respond_to?(:clone_and_reset) ? self.value.clone_and_reset : self.value
33
+ setting = ConfigValue.new(val, self.default_value,
28
34
  self.default_proc, self.deprecation)
29
- setting.reset!
35
+ setting.reset_values
30
36
  setting
31
37
  end
32
38
 
39
+ # @return [Boolean]
40
+ def default_value?
41
+ val = self.default_proc ? self.default_proc.call : self.default_value
42
+ val == self.value
43
+ end
44
+
33
45
  end
34
46
 
35
47
  # Class that defines and keeps the configuration values.
@@ -46,10 +58,15 @@ module FigTree
46
58
  @setting_templates = {}
47
59
  end
48
60
 
61
+ def reset_values
62
+ @setting_objects = @setting_templates.map { |k, _| [k, []] }.to_h
63
+ @settings.values.each(&:reset_values)
64
+ end
65
+
49
66
  # Reset config back to default values.
50
67
  def reset!
51
- @setting_objects = @setting_templates.map { |k, _| [k, []] }.to_h
52
- @settings.values.each(&:reset!)
68
+ reset_values
69
+ run_callbacks(:configure)
53
70
  end
54
71
 
55
72
  # Mark a configuration as deprecated and replaced with the new config.
@@ -70,6 +87,20 @@ module FigTree
70
87
  @settings.map { |k, v| [k, v.value] }.to_h
71
88
  end
72
89
 
90
+ def clear_removed_fields!
91
+ return if FigTree.keep_removed_configs
92
+
93
+ @settings.delete_if.each do |setting|
94
+ if setting.value.is_a?(ConfigStruct)
95
+ setting.value.clear_removed_fields!
96
+ false
97
+ else
98
+ setting.removed
99
+ end
100
+ end
101
+ @setting_objects.values.flatten.each(&:clear_removed_fields!)
102
+ end
103
+
73
104
  # :nodoc:
74
105
  def clone_and_reset
75
106
  new_config = self.clone
@@ -88,16 +119,16 @@ module FigTree
88
119
  # @param name [Symbol]
89
120
  def setting_object(name, &block)
90
121
  new_config = ConfigStruct.new("#{@name}.#{name}")
91
- @setting_objects[name] = []
92
- @setting_templates[name] = new_config
93
- new_config.instance_eval(&block)
122
+ @setting_objects[name] ||= []
123
+ @setting_templates[name] ||= new_config
124
+ @setting_templates[name].instance_eval(&block)
94
125
  end
95
126
 
96
127
  # Define a setting with the given name.
97
128
  # @param name [Symbol]
98
129
  # @param default_value [Object]
99
130
  # @param default_proc [Proc]
100
- def setting(name, default_value=nil, default_proc: nil, &block)
131
+ def setting(name, default_value=nil, default_proc: nil, removed: false, &block)
101
132
  if block_given?
102
133
  # Create a nested setting
103
134
  setting_config = @settings[name]&.value || ConfigStruct.new("#{@name}.#{name}")
@@ -109,11 +140,37 @@ module FigTree
109
140
  setting = ConfigValue.new
110
141
  setting.default_proc = default_proc
111
142
  setting.default_value = default_value
112
- setting.reset!
143
+ setting.reset_values
144
+ setting.removed = removed
113
145
  @settings[name] = setting
114
146
  end
115
147
  end
116
148
 
149
+ # @param field [String]
150
+ # @return [Boolean]
151
+ def default_value?(field)
152
+ @settings[field].default_value?
153
+ end
154
+
155
+ # Cuts down the config to only values that don't match the default values.
156
+ # Used to generate a representation of current config only via the changes.
157
+ def non_default_settings!
158
+ @settings.delete_if do |key, setting|
159
+ if setting.value.is_a?(ConfigStruct)
160
+ setting.value.non_default_settings!
161
+ setting.value.settings.empty?
162
+ else
163
+ setting.default_value?
164
+ end
165
+ end
166
+ @setting_objects.each do |_, list|
167
+ list.select! do |setting|
168
+ setting.non_default_settings!
169
+ setting.settings.none?
170
+ end
171
+ end
172
+ end
173
+
117
174
  # :nodoc:
118
175
  def respond_to_missing?(method, include_all=true)
119
176
  method = method.to_s.sub(/=$/, '')
@@ -139,6 +196,10 @@ module FigTree
139
196
 
140
197
  setting = @settings[config_key]
141
198
 
199
+ if setting&.removed && !FigTree.keep_removed_configs
200
+ puts "[Config] #{config_key} has been removed: #{setting.removed}"
201
+ end
202
+
142
203
  if setting&.deprecation
143
204
  return _deprecated_config_method(method, *args)
144
205
  end
@@ -152,6 +213,14 @@ module FigTree
152
213
  _default_config_method(config_key, *args)
153
214
  end
154
215
 
216
+ def trap_config(&block)
217
+ old_settings = @settings.deep_dup
218
+ old_setting_objects = @setting_objects.deep_dup
219
+ block.call
220
+ @settings = old_settings
221
+ @setting_objects = old_setting_objects
222
+ end
223
+
155
224
  protected
156
225
 
157
226
  # Only for the clone method
@@ -234,6 +303,10 @@ module FigTree
234
303
  @config ||= ConfigStruct.new('config')
235
304
  end
236
305
 
306
+ def trap_config(&block)
307
+ config.trap_config(&block)
308
+ end
309
+
237
310
  # Evaluate a block with the given configuration values. Reset back to the original values
238
311
  # when done.
239
312
  # @param values [Hash]
@@ -267,6 +340,7 @@ module FigTree
267
340
  mod = self
268
341
  config.class.set_callback(:configure, :after,
269
342
  proc { mod.instance_eval(&block) })
343
+ config.clear_removed_fields!
270
344
  end
271
345
  end
272
346
  end
@@ -0,0 +1,75 @@
1
+ # typed: true
2
+
3
+ module Tapioca
4
+ module Compilers
5
+ class FigTree < Tapioca::Dsl::Compiler
6
+ extend T::Sig
7
+
8
+ ConstantType = type_member {{ fixed: T.all(T::Class[::FigTree], ::FigTree::ClassMethods) }}
9
+
10
+ sig { override.returns(T::Enumerable[Module]) }
11
+ def self.gather_constants
12
+ all_modules.select { |m| m < ::FigTree}
13
+ end
14
+
15
+ sig { params(path: String, struct: ::FigTree::ConfigStruct).void }
16
+ def decorate_struct(path, struct)
17
+ class_name = struct.instance_variable_get(:@name)
18
+ constant_name = "Private#{path}#{class_name.tr('.', '_').classify}"
19
+ config_class = Class.new
20
+ Object.const_set(constant_name, config_class)
21
+ root.create_path(config_class) do |klass|
22
+ settings = struct.instance_variable_get(:@settings)
23
+ if settings
24
+ settings.each do |name, value|
25
+ if value.value.is_a?(::FigTree::ConfigStruct)
26
+ decorate_struct(path, value.value)
27
+ klass.create_method(name, return_type: "#{constant_name}#{name.to_s.classify}")
28
+ else
29
+ type = value.default_value
30
+ type = if type.nil?
31
+ 'T.untyped'
32
+ elsif type == true || type == false
33
+ 'T::Boolean'
34
+ else
35
+ type.class.to_s
36
+ end
37
+ klass.create_method(name, return_type: type)
38
+ klass.create_method("#{name}=",
39
+ return_type: "void",
40
+ parameters: [create_param("value", type: type)])
41
+ end
42
+ end
43
+ end
44
+ templates = struct.instance_variable_get(:@setting_templates)
45
+ if templates
46
+ templates.each do |name, value|
47
+ klass.create_method(name,
48
+ return_type: "void",
49
+ parameters: [create_block_param("blk", type: "T.proc.bind(#{constant_name}#{name.to_s.classify}).void")])
50
+ decorate_struct(path, value)
51
+ end
52
+ end
53
+
54
+ end
55
+ end
56
+
57
+ sig { override.void }
58
+ def decorate
59
+ root.create_path(constant) do |klass|
60
+ constant_name = T.must(constant.name).gsub('::', '')
61
+ class_name = "Private#{constant_name}Config"
62
+ klass.create_include('::FigTree')
63
+ klass.create_method("config", return_type: class_name, class_method: true)
64
+ proc_type = "T.proc.bind(#{class_name}).params(config: #{class_name}).void"
65
+ klass.create_method("configure",
66
+ class_method: true,
67
+ return_type: "void",
68
+ parameters: [create_block_param("blk", type: proc_type)])
69
+ decorate_struct(constant_name, constant.config)
70
+ end
71
+ end
72
+
73
+ end
74
+ end
75
+ end
data/rbi/fig_tree.rbi ADDED
@@ -0,0 +1,91 @@
1
+ # typed: true
2
+
3
+ module FigTree
4
+ extend ::ActiveSupport::Concern
5
+
6
+ mixes_in_class_methods ::FigTree::ClassMethods
7
+ end
8
+
9
+ module FigTree::ClassMethods
10
+ sig { params(block: T.proc.bind(::FigTree::ConfigStruct).void).void }
11
+ def after_configure(&block); end
12
+
13
+ sig { returns(::FigTree::ConfigStruct) }
14
+ def config; end
15
+
16
+ sig { params(block: T.proc.bind(::FigTree::ConfigStruct).void).void }
17
+ def configure(&block); end
18
+
19
+ sig { params(block: T.proc.bind(::FigTree::ConfigStruct).void).void }
20
+ def define_settings(&block); end
21
+
22
+ sig { params(values: T.nilable(Hash), block: T.proc).void }
23
+ def with_config(values = T.unsafe(nil), &block); end
24
+ end
25
+
26
+ class FigTree::ConfigStruct
27
+ include ::ActiveSupport::Callbacks
28
+ extend ::ActiveSupport::Callbacks::ClassMethods
29
+ extend ::ActiveSupport::DescendantsTracker
30
+
31
+ sig { params(name: String) }
32
+ def initialize(name); end
33
+
34
+ # source://fig_tree//lib/fig_tree.rb#74
35
+ def clone_and_reset; end
36
+
37
+ sig { params(old_config: String, new_config: String).void }
38
+ def deprecate(old_config, new_config); end
39
+
40
+ sig { returns(String) }
41
+ def inspect; end
42
+
43
+ sig { void }
44
+ def reset!; end
45
+
46
+ sig { params(name: Symbol, default_value: T.untyped, default_proc: T.proc, block: T.proc).void }
47
+ def setting(name, default_value = T.unsafe(nil), default_proc: T.unsafe(nil), &block); end
48
+
49
+ sig {params(name: Symbol, block: T.proc.bind(::FigTree::ConfigStruct).void).void }
50
+ def setting_object(name, &block); end
51
+
52
+ sig { returns(Hash) }
53
+ def to_h; end
54
+ end
55
+
56
+ class FigTree::ConfigValue < ::Struct
57
+ sig { void }
58
+ def clone_and_reset; end
59
+
60
+ sig { returns(T.untyped) }
61
+ def default_proc; end
62
+
63
+ sig { params(_: T.untyped).void }
64
+ def default_proc=(_); end
65
+
66
+ sig { returns(T.untyped) }
67
+ def default_value; end
68
+
69
+ sig { params(_: T.untyped).void }
70
+ def default_value=(_); end
71
+
72
+ sig { void }
73
+ def reset!; end
74
+
75
+ sig { returns(T.untyped) }
76
+ def value; end
77
+
78
+ sig { params(_: T.untyped).void }
79
+ def value=(_); end
80
+
81
+ class << self
82
+ def [](*_arg0); end
83
+ def inspect; end
84
+ def keyword_init?; end
85
+ def members; end
86
+ def new(*_arg0); end
87
+ end
88
+ end
89
+
90
+ # source://fig_tree//lib/fig_tree/version.rb#4
91
+ FigTree::VERSION = T.let(T.unsafe(nil), String)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fig_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Orner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-04 00:00:00.000000000 Z
11
+ date: 2024-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -133,7 +133,6 @@ files:
133
133
  - ".gitignore"
134
134
  - ".rspec"
135
135
  - ".rubocop.yml"
136
- - ".ruby-gemset"
137
136
  - ".ruby-version"
138
137
  - CHANGELOG.md
139
138
  - CODE_OF_CONDUCT.md
@@ -144,6 +143,8 @@ files:
144
143
  - fig_tree.gemspec
145
144
  - lib/fig_tree.rb
146
145
  - lib/fig_tree/version.rb
146
+ - lib/tapioca/dsl/compilers/fig_tree.rb
147
+ - rbi/fig_tree.rbi
147
148
  - spec/fig_tree_spec.rb
148
149
  - spec/spec_helper.rb
149
150
  - support/flipp-logo.png
@@ -166,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
167
  - !ruby/object:Gem::Version
167
168
  version: '0'
168
169
  requirements: []
169
- rubygems_version: 3.3.20
170
+ rubygems_version: 3.4.10
170
171
  signing_key:
171
172
  specification_version: 4
172
173
  summary: Configuration framework for Ruby.
data/.ruby-gemset DELETED
@@ -1 +0,0 @@
1
- fig_tree