diver_down 0.0.1.alpha13 → 0.0.1.alpha14

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.
@@ -12,8 +12,8 @@ module DiverDown
12
12
  # Between modules is prominently distanced
13
13
  MODULE_MINLEN = 3
14
14
 
15
- class MetadataStore
16
- Metadata = Data.define(:id, :type, :data, :module_store) do
15
+ class DotMetadataStore
16
+ DotMetadata = Data.define(:id, :type, :data, :metadata) do
17
17
  # @return [Hash]
18
18
  def to_h
19
19
  case type
@@ -31,7 +31,7 @@ module DiverDown
31
31
  private
32
32
 
33
33
  def source_to_h
34
- modules = module_store.get_modules(data.source_name).map do
34
+ modules = metadata.source(data.source_name).modules.map do
35
35
  {
36
36
  module_name: _1,
37
37
  }
@@ -41,7 +41,7 @@ module DiverDown
41
41
  id:,
42
42
  type: 'source',
43
43
  source_name: data.source_name,
44
- memo: module_store.get_memo(data.source_name),
44
+ memo: metadata.source(data.source_name).memo,
45
45
  modules:,
46
46
  }
47
47
  end
@@ -77,11 +77,11 @@ module DiverDown
77
77
  end
78
78
  end
79
79
 
80
- def initialize(module_store)
80
+ def initialize(metadata)
81
81
  @prefix = 'graph_'
82
- @module_store = module_store
82
+ @metadata = metadata
83
83
 
84
- # Hash{ id => Metadata }
84
+ # Hash{ id => DotMetadata }
85
85
  @to_h = {}
86
86
  end
87
87
 
@@ -89,13 +89,13 @@ module DiverDown
89
89
  # @param record [DiverDown::Definition::Source]
90
90
  # @return [String]
91
91
  def issue_source_id(source)
92
- build_metadata_and_return_id(:source, source)
92
+ build_dot_metadata_and_return_id(:source, source)
93
93
  end
94
94
 
95
95
  # @param dependency [DiverDown::Definition::Dependency]
96
96
  # @return [String]
97
97
  def issue_dependency_id(dependency)
98
- build_metadata_and_return_id(:dependency, [dependency])
98
+ build_dot_metadata_and_return_id(:dependency, [dependency])
99
99
  end
100
100
 
101
101
  # @param module_names [Array<String>]
@@ -106,17 +106,17 @@ module DiverDown
106
106
  if issued_metadata
107
107
  issued_metadata.id
108
108
  else
109
- build_metadata_and_return_id(:module, module_names)
109
+ build_dot_metadata_and_return_id(:module, module_names)
110
110
  end
111
111
  end
112
112
 
113
113
  # @param id [String]
114
114
  # @param dependency [DiverDown::Definition::Dependency]
115
115
  def append_dependency(id, dependency)
116
- metadata = @to_h.fetch(id)
117
- dependencies = metadata.data
116
+ dot_metadata = @to_h.fetch(id)
117
+ dependencies = dot_metadata.data
118
118
  combined_dependencies = DiverDown::Definition::Dependency.combine(*dependencies, dependency)
119
- metadata.data.replace(combined_dependencies)
119
+ dot_metadata.data.replace(combined_dependencies)
120
120
  end
121
121
 
122
122
  # @return [Array<Hash>]
@@ -126,10 +126,10 @@ module DiverDown
126
126
 
127
127
  private
128
128
 
129
- def build_metadata_and_return_id(type, data)
129
+ def build_dot_metadata_and_return_id(type, data)
130
130
  id = "#{@prefix}#{length + 1}"
131
- metadata = Metadata.new(id:, type:, data:, module_store: @module_store)
132
- @to_h[id] = metadata
131
+ dot_metadata = DotMetadata.new(id:, type:, data:, metadata: @metadata)
132
+ @to_h[id] = dot_metadata
133
133
 
134
134
  id
135
135
  end
@@ -140,24 +140,24 @@ module DiverDown
140
140
  end
141
141
 
142
142
  # @param definition [DiverDown::Definition]
143
- # @param module_store [DiverDown::ModuleStore]
143
+ # @param metadata [DiverDown::Web::Metadata]
144
144
  # @param compound [Boolean]
145
145
  # @param concentrate [Boolean] https://graphviz.org/docs/attrs/concentrate/
146
- def initialize(definition, module_store, compound: false, concentrate: false, only_module: false)
146
+ def initialize(definition, metadata, compound: false, concentrate: false, only_module: false)
147
147
  @definition = definition
148
- @module_store = module_store
148
+ @metadata = metadata
149
149
  @io = DiverDown::Web::IndentedStringIo.new
150
150
  @indent = 0
151
151
  @compound = compound || only_module # When only-module is enabled, dependencies between modules are displayed as compound.
152
152
  @compound_map = Hash.new { |h, k| h[k] = {} } # Hash{ ltail => Hash{ lhead => issued id } }
153
153
  @concentrate = concentrate
154
154
  @only_module = only_module
155
- @metadata_store = MetadataStore.new(module_store)
155
+ @dot_metadata_store = DotMetadataStore.new(metadata)
156
156
  end
157
157
 
158
158
  # @return [Array<Hash>]
159
- def metadata
160
- @metadata_store.to_a
159
+ def dot_metadata
160
+ @dot_metadata_store.to_a
161
161
  end
162
162
 
163
163
  # @return [String]
@@ -179,18 +179,18 @@ module DiverDown
179
179
 
180
180
  private
181
181
 
182
- attr_reader :definition, :module_store, :io
182
+ attr_reader :definition, :metadata, :io
183
183
 
184
184
  def render_only_modules
185
185
  # Hash{ from_module => { to_module => Array<DiverDown::Definition::Dependency> } }
186
186
  dependency_map = Hash.new { |h, k| h[k] = Hash.new { |hi, ki| hi[ki] = [] } }
187
187
 
188
188
  definition.sources.sort_by(&:source_name).each do |source|
189
- source_modules = module_store.get_modules(source.source_name)
189
+ source_modules = metadata.source(source.source_name).modules
190
190
  next if source_modules.empty?
191
191
 
192
192
  source.dependencies.each do |dependency|
193
- dependency_modules = module_store.get_modules(dependency.source_name)
193
+ dependency_modules = metadata.source(dependency.source_name).modules
194
194
  next if dependency_modules.empty?
195
195
 
196
196
  dependency_map[source_modules][dependency_modules].push(dependency)
@@ -198,7 +198,7 @@ module DiverDown
198
198
  end
199
199
 
200
200
  # Remove duplicated prefix modules
201
- # from [["A"], ["A", "B"]] to [["A", "B"]]
201
+ # from [["A"], ["A", "B"], ["A", "C"], ["D"]] to { "A" => { "B" => {}, "C" => {} }, "D" => {} }
202
202
  uniq_modules = [*dependency_map.keys, *dependency_map.values.map(&:keys).flatten(1)].uniq
203
203
  uniq_modules.reject! do |modules|
204
204
  modules.empty? ||
@@ -215,9 +215,9 @@ module DiverDown
215
215
 
216
216
  io.puts %(subgraph "#{escape_quote(module_label(module_names))}" {)
217
217
  io.indented do
218
- io.puts %(id="#{@metadata_store.issue_modules_id(module_names)}")
218
+ io.puts %(id="#{@dot_metadata_store.issue_modules_id(module_names)}")
219
219
  io.puts %(label="#{escape_quote(module_name)}")
220
- io.puts %("#{escape_quote(module_name)}" #{build_attributes(label: module_name, id: @metadata_store.issue_modules_id(module_names))})
220
+ io.puts %("#{escape_quote(module_name)}" #{build_attributes(label: module_name, id: @dot_metadata_store.issue_modules_id(module_names))})
221
221
 
222
222
  next_proc&.call
223
223
  end
@@ -245,11 +245,11 @@ module DiverDown
245
245
  # Add the dependency to the edge of the compound
246
246
  if @compound_map[ltail].include?(lhead)
247
247
  compound_id = @compound_map[ltail][lhead]
248
- @metadata_store.append_dependency(compound_id, _1)
248
+ @dot_metadata_store.append_dependency(compound_id, _1)
249
249
  next
250
250
  end
251
251
 
252
- compound_id = @metadata_store.issue_dependency_id(_1)
252
+ compound_id = @dot_metadata_store.issue_dependency_id(_1)
253
253
  @compound_map[ltail][lhead] = compound_id
254
254
 
255
255
  attributes.merge!(
@@ -268,67 +268,57 @@ module DiverDown
268
268
  end
269
269
 
270
270
  def render_sources
271
+ # Hash{ modules => sources }
272
+ # Hash{ Array<String> => Array<DiverDown::Definition::Source> }
271
273
  by_modules = definition.sources.group_by do |source|
272
- module_store.get_modules(source.source_name)
274
+ metadata.source(source.source_name).modules
273
275
  end
274
276
 
275
- # Remove duplicated prefix modules
276
- # from [["A"], ["A", "B"]] to [["A", "B"]]
277
- uniq_modules = by_modules.keys.uniq
278
- uniq_modules = uniq_modules.reject do |modules|
279
- uniq_modules.any? { _1[0..modules.size - 1] == modules && _1.length > modules.size }
277
+ # Render subgraph for each module and its sources second
278
+ nested_modules = array_to_hash(by_modules.keys.uniq.sort)
279
+ render_nested_modules_sources(by_modules, nested_modules)
280
+
281
+ # Render dependencies last
282
+ definition.sources.sort_by(&:source_name).each do |source|
283
+ insert_dependencies(source)
280
284
  end
285
+ end
281
286
 
282
- uniq_modules.each do |full_modules|
283
- # Render module and source
284
- if full_modules.empty?
285
- sources = by_modules[full_modules].sort_by(&:source_name)
287
+ def render_nested_modules_sources(by_modules, nested_modules, prefix = [])
288
+ nested_modules.each do |module_name, next_nested_modules|
289
+ module_names = prefix + [module_name].compact
290
+ sources = (by_modules[module_names] || []).sort_by(&:source_name)
286
291
 
292
+ if module_name.nil?
287
293
  sources.each do |source|
288
- insert_source(source)
294
+ io.puts build_source_node(source)
289
295
  end
290
296
  else
291
- buf = swap_io do
292
- indexes = (0..(full_modules.length - 1)).to_a
293
-
294
- chain_yield(indexes) do |index, next_proc|
295
- module_names = full_modules[0..index]
296
- module_name = module_names[-1]
297
-
298
- io.puts %(subgraph "#{escape_quote(module_label(module_names))}" {)
299
- io.indented do
300
- io.puts %(id="#{@metadata_store.issue_modules_id(module_names)}")
301
- io.puts %(label="#{escape_quote(module_name)}")
302
-
303
- sources = (by_modules[module_names] || []).sort_by(&:source_name)
304
- sources.each do |source|
305
- insert_source(source)
306
- end
307
-
308
- next_proc&.call
309
- end
310
- io.puts '}'
297
+ io.puts %(subgraph "#{escape_quote(module_label(module_names))}" {)
298
+ io.indented do
299
+ io.puts %(id="#{@dot_metadata_store.issue_modules_id(module_names)}")
300
+ io.puts %(label="#{escape_quote(module_name)}")
301
+
302
+ sources.each do |source|
303
+ io.puts build_source_node(source)
311
304
  end
312
- end
313
305
 
314
- io.write buf.string
306
+ render_nested_modules_sources(by_modules, next_nested_modules, module_names)
307
+ end
308
+ io.puts '}'
315
309
  end
316
310
  end
317
-
318
- definition.sources.sort_by(&:source_name).each do |source|
319
- insert_dependencies(source)
320
- end
321
311
  end
322
312
 
323
- def insert_source(source)
324
- io.puts %("#{escape_quote(source.source_name)}" #{build_attributes(label: source.source_name, id: @metadata_store.issue_source_id(source))})
313
+ def build_source_node(source)
314
+ %("#{escape_quote(source.source_name)}" #{build_attributes(label: source.source_name, id: @dot_metadata_store.issue_source_id(source))})
325
315
  end
326
316
 
327
317
  def insert_dependencies(source)
328
318
  source.dependencies.each do
329
319
  attributes = {}
330
- ltail = module_label(*module_store.get_modules(source.source_name))
331
- lhead = module_label(*module_store.get_modules(_1.source_name))
320
+ ltail = module_label(*metadata.source(source.source_name).modules)
321
+ lhead = module_label(*metadata.source(_1.source_name).modules)
332
322
 
333
323
  if @compound && (ltail || lhead)
334
324
  # Rendering of dependencies between modules is done only once
@@ -338,11 +328,11 @@ module DiverDown
338
328
  # Add the dependency to the edge of the compound
339
329
  if between_modules && @compound_map[ltail].include?(lhead)
340
330
  compound_id = @compound_map[ltail][lhead]
341
- @metadata_store.append_dependency(compound_id, _1)
331
+ @dot_metadata_store.append_dependency(compound_id, _1)
342
332
  next
343
333
  end
344
334
 
345
- compound_id = @metadata_store.issue_dependency_id(_1)
335
+ compound_id = @dot_metadata_store.issue_dependency_id(_1)
346
336
  @compound_map[ltail][lhead] = compound_id
347
337
 
348
338
  attributes.merge!(
@@ -353,7 +343,7 @@ module DiverDown
353
343
  )
354
344
  else
355
345
  attributes.merge!(
356
- id: @metadata_store.issue_dependency_id(_1)
346
+ id: @dot_metadata_store.issue_dependency_id(_1)
357
347
  )
358
348
  end
359
349
 
@@ -420,6 +410,28 @@ module DiverDown
420
410
  def escape_quote(string)
421
411
  string.to_s.gsub(/"/, '\"')
422
412
  end
413
+
414
+ # from [["A"], ["A", "B"], ["A", "C"], ["D"]] to { "A" => { "B" => {}, "C" => {} }, "D" => {} }
415
+ def array_to_hash(array)
416
+ hash = {}
417
+ array.each do |sub_array|
418
+ current_hash = hash
419
+
420
+ if sub_array.empty?
421
+ current_hash[nil] = {}
422
+ else
423
+ sub_array.each_with_index do |element, index|
424
+ if index == sub_array.length - 1
425
+ current_hash[element] = {}
426
+ else
427
+ current_hash[element] ||= {}
428
+ current_hash = current_hash[element]
429
+ end
430
+ end
431
+ end
432
+ end
433
+ hash
434
+ end
423
435
  end
424
436
  end
425
437
  end
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DiverDown
4
+ class Web
5
+ class Metadata
6
+ class SourceAlias
7
+ class ConflictError < StandardError
8
+ attr_reader :source_name
9
+
10
+ def initialize(message, source_name:)
11
+ @source_name = source_name
12
+
13
+ super(message)
14
+ end
15
+ end
16
+
17
+ BLANK_RE = /\A\s*\z/
18
+
19
+ def initialize
20
+ # Hash{ alias_name => Set<source_name, ...> }
21
+ @alias_to_source_names = {}
22
+ @source_name_to_alias = {}
23
+ end
24
+
25
+ # @param alias_name [String]
26
+ # @param source_names [Array<String>]
27
+ # @return [void]
28
+ def update_alias(alias_name, source_names)
29
+ source_names = source_names.reject { BLANK_RE.match?(_1) }
30
+
31
+ if source_names.empty?
32
+ prev_source_names = @alias_to_source_names.delete(alias_name)
33
+ prev_source_names&.each do |prev_source_name|
34
+ @source_name_to_alias.delete(prev_source_name)
35
+ end
36
+ else
37
+ check_conflict(alias_name, source_names)
38
+ @alias_to_source_names[alias_name] = source_names.sort
39
+
40
+ source_names.each do |source_name|
41
+ @source_name_to_alias[source_name] = alias_name
42
+ end
43
+ end
44
+ end
45
+
46
+ # @param alias_name [String]
47
+ # @return [String]
48
+ def resolve_alias(source_name)
49
+ @source_name_to_alias[source_name] if @source_name_to_alias.key?(source_name)
50
+ end
51
+
52
+ # @param alias_name [String]
53
+ # @return [Array<String>]
54
+ def aliased_source_names(alias_name)
55
+ @alias_to_source_names[alias_name] if @alias_to_source_names.key?(alias_name)
56
+ end
57
+
58
+ # Rollback the changes made in the block if an conflict error occurs.
59
+ #
60
+ # @raise [ConflictError]
61
+ def transaction
62
+ alias_to_source_names = deep_dup(@alias_to_source_names)
63
+ source_name_to_alias = deep_dup(@source_name_to_alias)
64
+
65
+ yield
66
+ rescue ConflictError
67
+ @alias_to_source_names = alias_to_source_names
68
+ @source_name_to_alias = source_name_to_alias
69
+
70
+ raise
71
+ end
72
+
73
+ # @return [Hash]
74
+ def to_h
75
+ keys = @alias_to_source_names.keys.sort
76
+ keys.to_h { [_1, aliased_source_names(_1)] }
77
+ end
78
+
79
+ private
80
+
81
+ def deep_dup(hash)
82
+ hash.transform_values do
83
+ if _1.is_a?(Hash)
84
+ deep_dup(_1)
85
+ else
86
+ _1.dup
87
+ end
88
+ end
89
+ end
90
+
91
+ def added_source_names(excluding_alias_name)
92
+ source_names = Set.new
93
+
94
+ @alias_to_source_names.each_key do |name|
95
+ next if excluding_alias_name == name
96
+
97
+ source_names.add(name)
98
+
99
+ @alias_to_source_names[name].each do |source_name|
100
+ source_names.add(source_name)
101
+ end
102
+ end
103
+
104
+ source_names
105
+ end
106
+
107
+ def check_conflict(alias_name, source_names)
108
+ if source_names.any? { _1 == alias_name }
109
+ raise(ConflictError.new("Cannot create an alias for '#{alias_name}' that refers to itself.", source_name: alias_name))
110
+ end
111
+
112
+ registered_source_names = added_source_names(alias_name)
113
+
114
+ if registered_source_names.include?(alias_name)
115
+ raise ConflictError.new("Alias '#{alias_name}' is already aliased.", source_name: alias_name)
116
+ end
117
+
118
+ conflicted_source_name = source_names.find { registered_source_names.include?(_1) }
119
+
120
+ if conflicted_source_name
121
+ resolved_source_name = resolve_alias(conflicted_source_name)
122
+ raise ConflictError.new("Source '#{conflicted_source_name}' is already aliased to '#{resolved_source_name}'.", source_name: conflicted_source_name)
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DiverDown
4
+ class Web
5
+ class Metadata
6
+ class SourceMetadata
7
+ BLANK_MEMO = ''
8
+ BLANK_RE = /\A\s*\z/
9
+ BLANK_ARRAY = [].freeze
10
+ private_constant(:BLANK_MEMO)
11
+ private_constant(:BLANK_RE)
12
+ private_constant(:BLANK_ARRAY)
13
+
14
+ attr_reader :memo, :modules
15
+
16
+ # @param source_name [String]
17
+ def initialize(memo: BLANK_MEMO, modules: BLANK_ARRAY)
18
+ @memo = memo
19
+ @modules = modules
20
+ end
21
+
22
+ # @param memo [String]
23
+ # @return [void]
24
+ def memo=(memo)
25
+ @memo = memo.strip
26
+ end
27
+
28
+ # @param module_names [Array<String>]
29
+ # @return [void]
30
+ def modules=(module_names)
31
+ @modules = module_names.reject do
32
+ BLANK_RE.match?(_1)
33
+ end.freeze
34
+ end
35
+
36
+ # @return [Boolean]
37
+ def modules?
38
+ @modules.any?
39
+ end
40
+
41
+ # @return [Hash]
42
+ def to_h
43
+ hash = {}
44
+
45
+ hash[:memo] = memo unless memo == BLANK_MEMO
46
+ hash[:modules] = modules unless modules.empty?
47
+
48
+ hash
49
+ end
50
+
51
+ private
52
+
53
+ def by_source_name(source_name)
54
+ @store[source_name] ||= {}
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DiverDown
4
+ class Web
5
+ class Metadata
6
+ require 'diver_down/web/metadata/source_metadata'
7
+ require 'diver_down/web/metadata/source_alias'
8
+
9
+ attr_reader :source_alias
10
+
11
+ # @param path [String]
12
+ def initialize(path)
13
+ @path = path
14
+ load
15
+ end
16
+
17
+ # @param source_name [String]
18
+ # @return [DiverDown::Web::Metadata::SourceMetadata]
19
+ def source(source_name)
20
+ @source_map[source_name]
21
+ end
22
+
23
+ # @return [Hash]
24
+ def to_h
25
+ source_names = @source_map.keys.sort
26
+
27
+ sources = source_names.filter_map {
28
+ h = source(_1).to_h
29
+ [_1, h] unless h.empty?
30
+ }.to_h
31
+
32
+ {
33
+ sources:,
34
+ source_alias: @source_alias.to_h,
35
+ }
36
+ end
37
+
38
+ # Write store to file
39
+ # @return [void]
40
+ def flush
41
+ File.write(@path, to_h.to_yaml)
42
+ end
43
+
44
+ private
45
+
46
+ def load
47
+ @source_map = Hash.new { |h, source_name| h[source_name] = DiverDown::Web::Metadata::SourceMetadata.new }
48
+ @source_alias = DiverDown::Web::Metadata::SourceAlias.new
49
+
50
+ loaded = YAML.load_file(@path)
51
+
52
+ return if loaded.nil?
53
+
54
+ # NOTE: This is for backward compatibility. It will be removed in the future.
55
+ (loaded[:sources] || loaded || []).each do |source_name, source_hash|
56
+ source(source_name).memo = source_hash[:memo] if source_hash[:memo]
57
+ source(source_name).modules = source_hash[:modules] if source_hash[:modules]
58
+ end
59
+
60
+ loaded[:source_alias]&.each do |alias_name, source_names|
61
+ @source_alias.update_alias(alias_name, source_names)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DiverDown
4
+ class Web
5
+ class ModuleSourcesFilter
6
+ # @param metadata_alias [DiverDown::Web::Metadata]
7
+ def initialize(metadata)
8
+ @metadata = metadata
9
+ end
10
+
11
+ # @param definition [DiverDown::Definition]
12
+ # @param modules [Array<Array<String>>]
13
+ # @return [DiverDown::Definition]
14
+ def filter(definition, modules:)
15
+ new_definition = DiverDown::Definition.new(
16
+ definition_group: definition.definition_group,
17
+ title: definition.title
18
+ )
19
+
20
+ is_match_modules = ->(source_name) do
21
+ source_modules = @metadata.source(source_name).modules
22
+ source_modules.first(modules.size) == modules
23
+ end
24
+
25
+ definition.sources.each do |source|
26
+ next unless is_match_modules.call(source.source_name)
27
+
28
+ new_source = new_definition.find_or_build_source(source.source_name)
29
+
30
+ source.dependencies.each do |dependency|
31
+ next unless is_match_modules.call(dependency.source_name)
32
+
33
+ new_dependency = new_source.find_or_build_dependency(dependency.source_name)
34
+
35
+ next unless new_dependency
36
+
37
+ dependency.method_ids.each do |method_id|
38
+ new_method_id = new_dependency.find_or_build_method_id(
39
+ context: method_id.context,
40
+ name: method_id.name
41
+ )
42
+
43
+ method_id.paths.each do |path|
44
+ new_method_id.add_path(path)
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ new_definition
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DiverDown
4
+ class Web
5
+ class SourceAliasResolver
6
+ # @param metadata_alias [DiverDown::Web::Metadata::SourceAlias]
7
+ def initialize(metadata_alias)
8
+ @metadata_alias = metadata_alias
9
+ end
10
+
11
+ # @param definition [DiverDown::Definition]
12
+ # @return [DiverDown::Definition]
13
+ def resolve(definition)
14
+ new_definition = DiverDown::Definition.new(
15
+ definition_group: definition.definition_group,
16
+ title: definition.title
17
+ )
18
+
19
+ definition.sources.each do |source|
20
+ resolved_source_name = @metadata_alias.resolve_alias(source.source_name) || source.source_name
21
+ new_source = new_definition.find_or_build_source(resolved_source_name)
22
+
23
+ source.dependencies.each do |dependency|
24
+ resolved_dependency_source_name = @metadata_alias.resolve_alias(dependency.source_name) || dependency.source_name
25
+ new_dependency = new_source.find_or_build_dependency(resolved_dependency_source_name)
26
+
27
+ next unless new_dependency
28
+
29
+ dependency.method_ids.each do |method_id|
30
+ new_method_id = new_dependency.find_or_build_method_id(
31
+ context: method_id.context,
32
+ name: method_id.name
33
+ )
34
+
35
+ method_id.paths.each do |path|
36
+ new_method_id.add_path(path)
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ new_definition
43
+ end
44
+ end
45
+ end
46
+ end