fig_tree 0.0.5 → 0.2.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: 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