ree 1.1.2 → 1.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: f40830100c172dbfa6b7487174a1a9b002b2ef1314fa52135d3d482b58ae99c0
4
- data.tar.gz: 39c36079525c39ccfb2b33759d255e4a0a90f70384a986026af51ba3a4a153ac
3
+ metadata.gz: 4706c35aa267df5bf2216c2eb9473f82dc5adab6caaa85d05d811d724768ba00
4
+ data.tar.gz: '05389e5c0e3aa6e313c5c78494664a8c9f309c0db991b045df6fa1671464c2fa'
5
5
  SHA512:
6
- metadata.gz: 44758b1448ea2eb4a94496aca8942e7464dcfaa863e11a202cc0b8a17373b1245580ac4bde240e0b52118e7d80ae160de621ca9d627dcd690e0e1fdf7c57d992
7
- data.tar.gz: b542d6ee0ac12408eede6aa67cc250cfe8bd95870ac16e978f8ac5051d36a804405e91a3596eb9a294c39fe12959ded9f4d77fa63e695de20fe40d2b4a93a791
6
+ metadata.gz: f730da40f895bce754a410aaf054da34d0835cb7b63afe6b26582509a40dcf17d394188d355bcc9171b034618748d3d93c50c697cc5526288d07db8453ef0669
7
+ data.tar.gz: b33741238e6dac7275c9a1098c8b806c14f0081673b5555c7d12d89f8fcb2becf2e866bf4ce6149a0d737f649c2ebc28bf1b9cedc00e6c86b0049a9390c27c8a
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ree (1.1.2)
4
+ ree (1.2.0)
5
5
  commander (~> 5.0.0)
6
6
  logger (~> 1.6.5)
7
7
 
@@ -27,7 +27,7 @@ class Ree::ImportDsl
27
27
  rescue NameError => e
28
28
  proc
29
29
  .binding
30
- .eval("#{e.name} = Ree::ImportDsl::ClassConstant.new('#{e.name}')")
30
+ .eval("#{e.name} = Ree::ImportDsl::ConstantContextBuilder.get_context('#{e.name}')")
31
31
 
32
32
  retry
33
33
  ensure
@@ -74,50 +74,76 @@ class Ree::ImportDsl
74
74
  end
75
75
  end
76
76
 
77
- class ClassConstant
78
- attr_reader :name, :constants
79
-
80
- def initialize(name)
81
- @name = name
82
- @as = nil
83
- @constants = []
77
+ class ConstantContextBuilder
78
+ def self.get_context(name, module_name = nil)
79
+ context = Class.new(ConstantContext)
80
+ context.instance_variable_set(:@name, name)
81
+ context.instance_variable_set(:@module_name, module_name)
82
+ context.instance_variable_set(:@as, nil)
83
+ context.instance_variable_set(:@constants, [])
84
+ context
84
85
  end
86
+ end
85
87
 
86
- def &(obj)
87
- if !obj.is_a?(ClassConstant)
88
- raise Ree::ImportDsl::UnlinkConstError.new(obj)
88
+ class ConstantContext
89
+ class << self
90
+ def const_missing(const_name)
91
+ ConstantContextBuilder.get_context(const_name, name)
89
92
  end
90
93
 
91
- new_obj = if obj.is_a?(Class)
92
- ClassConstant.new(obj.to_s.split("::").last)
93
- else
94
- obj
94
+ def name
95
+ @name
95
96
  end
96
97
 
97
- return self if @constants.detect { |_| _.name == new_obj.name }
98
- @constants.push(new_obj)
98
+ def module_name
99
+ @module_name
100
+ end
99
101
 
100
- self
101
- end
102
+ def get_as
103
+ @as
104
+ end
102
105
 
103
- def get_as
104
- @as
105
- end
106
+ def constants
107
+ @constants
108
+ end
109
+
110
+ def as(obj)
111
+ if !obj.is_a?(Class)
112
+ raise Ree::ImportDsl::UnlinkConstError.new(obj)
113
+ end
106
114
 
107
- def as(obj)
108
- if !obj.is_a?(ClassConstant)
109
- raise Ree::ImportDsl::UnlinkConstError.new(obj)
115
+ @as = if has_context_ancestor?(obj)
116
+ obj
117
+ else
118
+ ConstantContextBuilder.get_context(obj.to_s.split("::").last)
119
+ end
120
+
121
+ self
110
122
  end
111
123
 
112
- @as = if obj.is_a?(Class)
113
- ClassConstant.new(obj.to_s.split("::").last)
114
- else
115
- obj
124
+ def &(obj)
125
+ if !obj.is_a?(Class)
126
+ raise Ree::ImportDsl::UnlinkConstError.new(obj)
127
+ end
128
+
129
+ new_obj = if has_context_ancestor?(obj)
130
+ obj
131
+ else
132
+ ConstantContextBuilder.get_context(obj.to_s.split("::").last)
133
+ end
134
+
135
+ return self if @constants.detect { |_| _.name == new_obj.name }
136
+ @constants.push(new_obj)
137
+
138
+ self
116
139
  end
117
140
 
118
- self
141
+ def has_context_ancestor?(obj)
142
+ return false unless obj.is_a?(Class)
143
+ obj.ancestors.include?(ConstantContext)
144
+ end
119
145
  end
120
- end
146
+ end
121
147
 
122
148
  private
123
149
 
@@ -126,7 +152,7 @@ class Ree::ImportDsl
126
152
 
127
153
  klass.constants.each do |const_sym|
128
154
  const = klass.const_get(const_sym)
129
- next if const.is_a?(ClassConstant)
155
+ next if ConstantContext.has_context_ancestor?(const)
130
156
 
131
157
  if constant.is_a?(Class) || constant.is_a?(Module)
132
158
  if (const.is_a?(Class) || const.is_a?(Module)) && const.name == constant.name
@@ -156,7 +182,7 @@ class Ree::ImportDsl
156
182
  end
157
183
 
158
184
  if parent_constant?(klass, const_name)
159
- klass.const_set(const_name, ClassConstant.new(const_name.to_s))
185
+ klass.const_set(const_name, ConstantContextBuilder.get_context(const_name.to_s))
160
186
  retry_after = true
161
187
  end
162
188
 
@@ -166,7 +192,7 @@ class Ree::ImportDsl
166
192
  private
167
193
 
168
194
  def store_removed_constant(name, constant)
169
- return if constant.is_a?(ClassConstant)
195
+ return if ConstantContext.has_context_ancestor?(constant)
170
196
  get_removed_constants << RemovedConstant.new(name, constant.dup)
171
197
  end
172
198
 
@@ -55,6 +55,46 @@ class Ree::LinkImportBuilder
55
55
  nil
56
56
  end
57
57
 
58
+ # @param [Class] klass Object class
59
+ # @param [Symbol] package_name
60
+ # @param [Proc] proc
61
+ # @return [ArrayOf[String]] List of names of imported constants
62
+ def build_for_objects(klass, package_name, proc)
63
+ const_list, removed_constants = Ree::ImportDsl.new.execute(klass, proc)
64
+ package = @packages_facade.get_package(package_name)
65
+
66
+ const_list.each do |const_obj|
67
+ if const_obj.module_name
68
+ object_name = Ree::StringUtils.underscore(const_obj.module_name).to_sym
69
+ else
70
+ object_name = Ree::StringUtils.underscore(const_obj.name).to_sym
71
+ end
72
+
73
+ object = package.get_object(object_name)
74
+ @packages_facade.load_package_object(package_name, object_name) if object
75
+
76
+ if object && object.klass && object.klass.const_defined?(const_obj.name)
77
+ set_const(klass, object.klass.const_get(const_obj.name), const_obj)
78
+ next
79
+ end
80
+
81
+ load_const_file(const_obj.name, package)
82
+ long_const_name = const_obj.module_name ? "#{const_obj.module_name}::#{const_obj.name}" : const_obj.name
83
+
84
+ if package.module.const_defined?(const_obj.name)
85
+ set_const(klass, package.module.const_get(const_obj.name), const_obj)
86
+ elsif package.module.const_defined?(long_const_name)
87
+ set_const(klass, package.module.const_get(long_const_name), const_obj)
88
+ else
89
+ raise Ree::Error.new("'#{const_obj.name}' is not found in :#{object&.name}")
90
+ end
91
+ end
92
+
93
+ assign_removed_constants(klass, removed_constants)
94
+
95
+ const_list.map(&:name)
96
+ end
97
+
58
98
  private
59
99
 
60
100
  def assign_removed_constants(klass, removed_constants)
@@ -69,7 +109,7 @@ class Ree::LinkImportBuilder
69
109
  target_klass.send(:remove_const, const_obj.get_as.name) rescue nil
70
110
  target_klass.const_set(const_obj.get_as.name, ref_class)
71
111
 
72
- if target_klass.const_get(const_obj.name).is_a?(Ree::ImportDsl::ClassConstant)
112
+ if target_klass.const_defined?(const_obj.name) && Ree::ImportDsl::ConstantContext.has_context_ancestor?(target_klass.const_get(const_obj.name))
73
113
  target_klass.send(:remove_const, const_obj.name)
74
114
  end
75
115
  else
@@ -77,4 +117,11 @@ class Ree::LinkImportBuilder
77
117
  target_klass.const_set(const_obj.name, ref_class)
78
118
  end
79
119
  end
120
+
121
+ def load_const_file(const_name, package)
122
+ return unless package.dir
123
+ path = Dir[File.join(Ree::PathHelper.abs_package_dir(package), Ree::PACKAGE, '**', "#{Ree::StringUtils.underscore(const_name)}.rb")].first
124
+ return unless path
125
+ Ree.container.packages_facade.load_file(path, package.name)
126
+ end
80
127
  end
@@ -27,9 +27,14 @@ class Ree::ObjectDsl
27
27
  end
28
28
 
29
29
  # Proxy method for link_object & link_file
30
+ #
30
31
  def link(*args, **kwargs)
31
32
  if args.first.is_a?(Symbol)
32
- link_object(*args, **kwargs)
33
+ if args.size > 1
34
+ link_multiple_objects(args, **kwargs)
35
+ else
36
+ link_object(*args, **kwargs)
37
+ end
33
38
  elsif args.first.is_a?(String)
34
39
  link_file(args[0], args[1])
35
40
  else
@@ -41,6 +46,14 @@ class Ree::ObjectDsl
41
46
  @object.add_tags(list)
42
47
  end
43
48
 
49
+ def import(*args, **kwargs)
50
+ if args.first.is_a?(Symbol) # import from ree object
51
+ _import_from_object(*args, **kwargs)
52
+ else
53
+ _import_object_consts(*args, **kwargs)
54
+ end
55
+ end
56
+
44
57
  # @param [Symbol] object_name
45
58
  # @param [Nilor[Symbol]] as
46
59
  # @param [Nilor[Symbol]] from
@@ -85,6 +98,20 @@ class Ree::ObjectDsl
85
98
  @packages_facade.load_package_object(link_package_name, link_object_name)
86
99
  end
87
100
 
101
+ # @param [ArrayOf[Symbol]] object_names
102
+ # @param [Hash] kwargs
103
+ def link_multiple_objects(object_names, **kwargs)
104
+ check_arg(kwargs[:from], :from, Symbol) if kwargs[:from]
105
+
106
+ if kwargs.reject{ |k, _v| k == :from }.size > 0
107
+ raise Ree::Error.new("options #{kwargs.reject{ |k, _v| k == :from }.keys} are not allowed for multi-object links", :invalid_link_option)
108
+ end
109
+
110
+ object_names.each do |object_name|
111
+ link_object(object_name, from: kwargs[:from])
112
+ end
113
+ end
114
+
88
115
  # @param [Symbol] target (:object, :class, :both, default: :object)
89
116
  def target(val)
90
117
  check_arg(val, :target, Symbol)
@@ -298,8 +325,6 @@ class Ree::ObjectDsl
298
325
  object
299
326
  end
300
327
 
301
- private
302
-
303
328
  def check_package_dependency_added(package_name)
304
329
  @packages_facade.load_package_entry(package_name)
305
330
  return if package_name == @package.name
@@ -328,4 +353,24 @@ class Ree::ObjectDsl
328
353
 
329
354
  raise Ree::Error.new(msg, code)
330
355
  end
356
+
357
+ def _import_object_consts(import_proc, from: nil)
358
+ check_arg(from, :from, Symbol) if from
359
+
360
+ link_package_name = from.nil? ? @object.package_name : from
361
+
362
+ Ree::LinkImportBuilder.new(@packages_facade).build_for_objects(
363
+ @object.klass, link_package_name, import_proc
364
+ )
365
+ end
366
+
367
+ def _import_from_object(object_name, import_proc, from: nil)
368
+ check_arg(from, :from, Symbol) if from
369
+
370
+ link_package_name = from.nil? ? @object.package_name : from
371
+
372
+ Ree::LinkImportBuilder.new(@packages_facade).build(
373
+ @object.klass, link_package_name, object_name, import_proc
374
+ )
375
+ end
331
376
  end
data/lib/ree/link_dsl.rb CHANGED
@@ -26,7 +26,11 @@ module Ree::LinkDSL
26
26
 
27
27
  def link(*args, **kwargs)
28
28
  if args.first.is_a?(Symbol)
29
- _link_object(*args, **kwargs)
29
+ if args.size > 1
30
+ _link_multiple_objects(args, **kwargs)
31
+ else
32
+ _link_object(*args, **kwargs)
33
+ end
30
34
  elsif args.first.is_a?(String)
31
35
  _link_file(args[0], args[1])
32
36
  else
@@ -34,8 +38,57 @@ module Ree::LinkDSL
34
38
  end
35
39
  end
36
40
 
41
+ def import(*args, **kwargs)
42
+ if args.first.is_a?(Symbol) # import from ree object
43
+ _import_from_object(*args, **kwargs)
44
+ else
45
+ _import_object_consts(*args, **kwargs)
46
+ end
47
+ end
48
+
37
49
  private
38
50
 
51
+ # @param [Proc] import_proc
52
+ # @param [Nilor[Symbol]] from
53
+ def _import_object_consts(import_proc, from: nil)
54
+ check_arg(from, :from, Symbol) if from
55
+
56
+ packages = Ree.container.packages_facade
57
+ link_package_name = get_link_package_name(from, '')
58
+
59
+ Ree::LinkImportBuilder.new(packages).build_for_objects(
60
+ self, link_package_name, import_proc
61
+ )
62
+ end
63
+
64
+ # @param [Symbol] object_name
65
+ # @param [Proc] import_proc
66
+ # @param [Nilor[Symbol]] from
67
+ def _import_from_object(object_name, import_proc, from: nil)
68
+ check_arg(from, :from, Symbol) if from
69
+
70
+ packages = Ree.container.packages_facade
71
+ link_package_name = get_link_package_name(from, object_name)
72
+
73
+ Ree::LinkImportBuilder.new(packages).build(
74
+ self, link_package_name, object_name, import_proc
75
+ )
76
+ end
77
+
78
+ # @param [ArrayOf[Symbol]] object_names
79
+ # @param [Hash] kwargs
80
+ def _link_multiple_objects(object_names, **kwargs)
81
+ check_arg(kwargs[:from], :from, Symbol) if kwargs[:from]
82
+
83
+ if kwargs.reject{ |k, _v| k == :from }.size > 0
84
+ raise Ree::Error.new("options #{kwargs.reject{ |k, _v| k == :from }.keys} are not allowed for multi-object links", :invalid_link_option)
85
+ end
86
+
87
+ object_names.each do |object_name|
88
+ _link_object(object_name, from: kwargs[:from])
89
+ end
90
+ end
91
+
39
92
  # @param [Symbol] object_name
40
93
  # @param [Nilor[Symbol]] as
41
94
  # @param [Nilor[Symbol]] from
data/lib/ree/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ree
4
- VERSION = "1.1.2"
4
+ VERSION = "1.2.0"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ree
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruslan Gatiyatov
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-05-14 00:00:00.000000000 Z
10
+ date: 2025-06-16 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: commander