kintsugi 0.5.4 → 0.6.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 +4 -4
- data/lib/kintsugi/apply_change_to_project.rb +262 -65
- data/lib/kintsugi/cli.rb +7 -0
- data/lib/kintsugi/settings.rb +18 -0
- data/lib/kintsugi/version.rb +1 -1
- data/spec/kintsugi_apply_change_to_project_spec.rb +292 -111
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c3458553d6a093c7ecdb473c8005cfbac4426709759b42adcf8a2ca2194a996
|
4
|
+
data.tar.gz: e6d67a33e803fddc41400e8c6df5670461ac33e7f524f6cf989a6f1730bde4f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a223924c1211a436829f79138f2e125d1acb231c53d98b029fcb5a7fff2120be64c28562cba0844d0ccb65e73f3bc85e559d7c927b4721881bbd751cb94f83a6
|
7
|
+
data.tar.gz: a904e53a5439af6df1257d0c17684a14015f75bed0fb5d9673308a1642cf86c836066b784ad743e609b7b9e976db4eaee9aa577eb89e0f5bbcd48b39724bb176
|
@@ -6,8 +6,21 @@ require "xcodeproj"
|
|
6
6
|
|
7
7
|
require_relative "utils"
|
8
8
|
require_relative "error"
|
9
|
+
require_relative "settings"
|
9
10
|
require_relative "xcodeproj_extensions"
|
10
11
|
|
12
|
+
class Array
|
13
|
+
# Converts an array of arrays of size 2 into a multimap, mapping the first element of each
|
14
|
+
# subarray to an array of the last elements it appears with in the same subarray.
|
15
|
+
def to_multi_h
|
16
|
+
raise ArgumentError, "Not all elements are arrays of size 2" unless all? do |arr|
|
17
|
+
arr.is_a?(Array) && arr.count == 2
|
18
|
+
end
|
19
|
+
|
20
|
+
group_by(&:first).transform_values { |group| group.map(&:last) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
11
24
|
module Kintsugi
|
12
25
|
class << self
|
13
26
|
# Applies the change specified by `change` to `project`.
|
@@ -28,8 +41,7 @@ module Kintsugi
|
|
28
41
|
if project.root_object.main_group.nil?
|
29
42
|
puts "Warning: Main group doesn't exist, ignoring changes to it."
|
30
43
|
else
|
31
|
-
|
32
|
-
change["rootObject"]["mainGroup"], "rootObject")
|
44
|
+
apply_main_group_change(project, change["rootObject"]["mainGroup"])
|
33
45
|
end
|
34
46
|
end
|
35
47
|
|
@@ -46,10 +58,154 @@ module Kintsugi
|
|
46
58
|
|
47
59
|
private
|
48
60
|
|
61
|
+
def apply_main_group_change(project, main_group_change)
|
62
|
+
additions, removals, diffs = classify_group_and_file_changes(main_group_change, "")
|
63
|
+
apply_group_additions(project, additions)
|
64
|
+
apply_file_changes(project, additions, removals)
|
65
|
+
apply_group_and_file_diffs(project, diffs)
|
66
|
+
apply_group_removals(project, removals)
|
67
|
+
end
|
68
|
+
|
69
|
+
def classify_group_and_file_changes(change, path)
|
70
|
+
children_changes = change["children"] || {}
|
71
|
+
removals = flatten_change(children_changes[:removed], path)
|
72
|
+
additions = flatten_change(children_changes[:added], path)
|
73
|
+
diffs = [[change, path]]
|
74
|
+
subchanges_of_change(children_changes).each do |key, subchange|
|
75
|
+
sub_additions, sub_removals, sub_diffs =
|
76
|
+
classify_group_and_file_changes(subchange, join_path(path, key))
|
77
|
+
removals += sub_removals
|
78
|
+
additions += sub_additions
|
79
|
+
diffs += sub_diffs
|
80
|
+
end
|
81
|
+
|
82
|
+
[additions, removals, diffs]
|
83
|
+
end
|
84
|
+
|
85
|
+
def flatten_change(change, path)
|
86
|
+
entries = (change || []).map do |child|
|
87
|
+
[child, path]
|
88
|
+
end
|
89
|
+
group_entries = entries.map do |group, _|
|
90
|
+
next if group["children"].nil?
|
91
|
+
|
92
|
+
flatten_change(group["children"], join_path(path, group["displayName"]))
|
93
|
+
end.compact.flatten(1)
|
94
|
+
entries + group_entries
|
95
|
+
end
|
96
|
+
|
97
|
+
def apply_group_additions(project, additions)
|
98
|
+
additions.each do |change, path|
|
99
|
+
next unless %w[PBXGroup PBXVariantGroup].include?(change["isa"])
|
100
|
+
|
101
|
+
group_type = Module.const_get("Xcodeproj::Project::#{change["isa"]}")
|
102
|
+
containing_group = path.empty? ? project.main_group : project[path]
|
103
|
+
|
104
|
+
next if !Settings.allow_duplicates &&
|
105
|
+
!find_group_in_group(containing_group, group_type, change).nil?
|
106
|
+
|
107
|
+
new_group = project.new(group_type)
|
108
|
+
containing_group.children << new_group
|
109
|
+
add_attributes_to_component(new_group, change, path, ignore_keys: ["children"])
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def find_group_in_group(group, instance_type, change)
|
114
|
+
group
|
115
|
+
.children
|
116
|
+
.select { |child| child.instance_of?(instance_type) }
|
117
|
+
.find do |child_group|
|
118
|
+
child_group.display_name == change["displayName"] && child_group.path == change["path"]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def apply_file_changes(project, additions, removals)
|
123
|
+
def file_reference_key(change)
|
124
|
+
[change["name"], change["path"], change["sourceTree"]]
|
125
|
+
end
|
126
|
+
|
127
|
+
file_additions = additions.select { |change, _| change["isa"] == "PBXFileReference" }
|
128
|
+
file_removals = removals.select { |change, _| change["isa"] == "PBXFileReference" }
|
129
|
+
|
130
|
+
addition_keys_to_paths = file_additions
|
131
|
+
.map { |change, path| [file_reference_key(change), path] }
|
132
|
+
.to_multi_h
|
133
|
+
removal_keys_to_references = file_removals.to_multi_h.map do |change, paths|
|
134
|
+
references = paths.map do |containing_path|
|
135
|
+
project[join_path(containing_path, change["displayName"])]
|
136
|
+
end
|
137
|
+
|
138
|
+
[file_reference_key(change), references]
|
139
|
+
end.to_h
|
140
|
+
|
141
|
+
file_additions.each do |change, path|
|
142
|
+
containing_group = path.empty? ? project.main_group : project[path]
|
143
|
+
change_key = file_reference_key(change)
|
144
|
+
|
145
|
+
if (removal_keys_to_references[change_key] || []).empty?
|
146
|
+
apply_file_addition(containing_group, change, "rootObject/mainGroup/#{path}")
|
147
|
+
elsif addition_keys_to_paths[change_key].length == 1 &&
|
148
|
+
removal_keys_to_references[change_key].length == 1 &&
|
149
|
+
!removal_keys_to_references[change_key].first.nil?
|
150
|
+
removal_keys_to_references[change_key].first.move(containing_group)
|
151
|
+
else
|
152
|
+
file_path = join_path(path, change["displayName"])
|
153
|
+
raise MergeError,
|
154
|
+
"Cannot deduce whether the file #{file_path} is new, or was moved to its new place"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
file_removals.each do |change, path|
|
159
|
+
next unless addition_keys_to_paths[file_reference_key(change)].nil?
|
160
|
+
|
161
|
+
file_reference = project[join_path(path, change["displayName"])]
|
162
|
+
remove_component(file_reference, change)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def apply_file_addition(containing_group, change, path)
|
167
|
+
return if !Settings.allow_duplicates &&
|
168
|
+
!find_file_in_group(containing_group, Xcodeproj::Project::PBXFileReference,
|
169
|
+
change["path"]).nil?
|
170
|
+
|
171
|
+
file_reference = containing_group.project.new(Xcodeproj::Project::PBXFileReference)
|
172
|
+
containing_group.children << file_reference
|
173
|
+
|
174
|
+
# For some reason, `include_in_index` is set to `1` and `source_tree` to `SDKROOT` by
|
175
|
+
# default.
|
176
|
+
file_reference.include_in_index = nil
|
177
|
+
file_reference.source_tree = nil
|
178
|
+
add_attributes_to_component(file_reference, change, path)
|
179
|
+
end
|
180
|
+
|
181
|
+
def apply_group_and_file_diffs(project, diffs)
|
182
|
+
diffs.each do |change, path|
|
183
|
+
component = project[path]
|
184
|
+
|
185
|
+
next if component.nil?
|
186
|
+
|
187
|
+
change.each do |subchange_name, subchange|
|
188
|
+
next if subchange_name == "children"
|
189
|
+
|
190
|
+
apply_change_to_component(component, subchange_name, subchange, path)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def apply_group_removals(project, removals)
|
196
|
+
removals.each do |change, path|
|
197
|
+
next unless %w[PBXGroup PBXVariantGroup].include?(change["isa"])
|
198
|
+
|
199
|
+
group_path = join_path(path, change["displayName"])
|
200
|
+
|
201
|
+
remove_component(project[group_path], change)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
49
205
|
def apply_change_to_component(parent_component, change_name, change, parent_change_path)
|
50
206
|
return if change_name == "displayName"
|
51
207
|
|
52
|
-
change_path = parent_change_path
|
208
|
+
change_path = join_path(parent_change_path, change_name)
|
53
209
|
|
54
210
|
attribute_name = attribute_name_from_change_name(change_name)
|
55
211
|
if simple_attribute?(parent_component, attribute_name)
|
@@ -61,28 +217,40 @@ module Kintsugi
|
|
61
217
|
component = replace_component_with_new_type(parent_component, attribute_name, change)
|
62
218
|
change = change_for_component_of_new_type(component, change)
|
63
219
|
else
|
64
|
-
component = child_component(parent_component, change_name)
|
65
|
-
|
66
|
-
if component.nil?
|
67
|
-
add_missing_component_if_valid(parent_component, change_name, change, change_path)
|
68
|
-
return
|
69
|
-
end
|
220
|
+
component = child_component(parent_component, change, change_name)
|
70
221
|
end
|
71
222
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
223
|
+
if change[:removed].is_a?(Hash)
|
224
|
+
remove_component(component, change[:removed])
|
225
|
+
elsif change[:removed].is_a?(Array)
|
226
|
+
unless component.nil?
|
227
|
+
(change[:removed]).each do |removed_change|
|
228
|
+
child = child_component_of_object_list(component, removed_change,
|
229
|
+
removed_change["displayName"])
|
230
|
+
remove_component(child, removed_change)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
elsif !change[:removed].nil?
|
234
|
+
raise MergeError, "Unsupported removed change type for #{change[:removed]}"
|
77
235
|
end
|
78
236
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
237
|
+
if change[:added].is_a?(Hash)
|
238
|
+
add_child_to_component(parent_component, change[:added], change_path)
|
239
|
+
elsif change[:added].is_a?(Array)
|
240
|
+
(change[:added]).each do |added_change|
|
241
|
+
add_child_to_component(parent_component, added_change, change_path)
|
242
|
+
end
|
243
|
+
elsif !change[:added].nil?
|
244
|
+
raise MergeError, "Unsupported added change type for #{change[:added]}"
|
83
245
|
end
|
84
246
|
|
85
247
|
subchanges_of_change(change).each do |subchange_name, subchange|
|
248
|
+
if component.nil?
|
249
|
+
raise MergeError, "Trying to apply changes to a component that doesn't exist at path " \
|
250
|
+
"#{change_path}. It was probably removed in a previous commit. This is considered a " \
|
251
|
+
"conflict that should be resolved manually."
|
252
|
+
end
|
253
|
+
|
86
254
|
apply_change_to_component(component, subchange_name, subchange, change_path)
|
87
255
|
end
|
88
256
|
end
|
@@ -103,16 +271,6 @@ module Kintsugi
|
|
103
271
|
end
|
104
272
|
end
|
105
273
|
|
106
|
-
def add_missing_component_if_valid(parent_component, change_name, change, change_path)
|
107
|
-
if change[:added] && change.compact.count == 1
|
108
|
-
add_child_to_component(parent_component, change[:added], change_path)
|
109
|
-
return
|
110
|
-
end
|
111
|
-
|
112
|
-
puts "Warning: Detected change of an object named '#{change_name}' contained in " \
|
113
|
-
"'#{parent_component}' but the object doesn't exist. Ignoring this change."
|
114
|
-
end
|
115
|
-
|
116
274
|
def replace_component_with_new_type(parent_component, name_in_parent_component, change)
|
117
275
|
old_component = parent_component.send(name_in_parent_component)
|
118
276
|
new_component = component_of_new_type(parent_component, change, old_component)
|
@@ -164,15 +322,23 @@ module Kintsugi
|
|
164
322
|
end
|
165
323
|
end
|
166
324
|
|
167
|
-
def child_component(component, change_name)
|
325
|
+
def child_component(component, change, change_name)
|
168
326
|
if component.is_a?(Xcodeproj::Project::ObjectList)
|
169
|
-
component
|
327
|
+
child_component_of_object_list(component, change, change_name)
|
170
328
|
else
|
171
329
|
attribute_name = attribute_name_from_change_name(change_name)
|
172
330
|
component.send(attribute_name)
|
173
331
|
end
|
174
332
|
end
|
175
333
|
|
334
|
+
def child_component_of_object_list(component, change, change_name)
|
335
|
+
if change["isa"] == "PBXReferenceProxy"
|
336
|
+
find_reference_proxy_in_component(component, change["remoteRef"])
|
337
|
+
else
|
338
|
+
component.find { |child| child.display_name == change_name }
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
176
342
|
def simple_attribute?(component, attribute_name)
|
177
343
|
return false unless component.respond_to?("simple_attributes")
|
178
344
|
|
@@ -281,7 +447,14 @@ module Kintsugi
|
|
281
447
|
|
282
448
|
return added_change if ((old_value || []) - (removed_change || [])).empty?
|
283
449
|
|
284
|
-
|
450
|
+
new_value = (old_value || []) - (removed_change || [])
|
451
|
+
filtered_added_change = if Settings.allow_duplicates
|
452
|
+
(added_change || [])
|
453
|
+
else
|
454
|
+
(added_change || []).reject { |added| new_value.include?(added) }
|
455
|
+
end
|
456
|
+
|
457
|
+
new_value + filtered_added_change
|
285
458
|
end
|
286
459
|
|
287
460
|
def new_string_simple_attribute_value(old_value, removed_change, added_change)
|
@@ -294,10 +467,13 @@ module Kintsugi
|
|
294
467
|
end
|
295
468
|
|
296
469
|
def remove_component(component, change)
|
470
|
+
return if component.nil?
|
471
|
+
|
297
472
|
if component.to_tree_hash != change
|
298
473
|
raise MergeError, "Trying to remove an object that changed since then. This is " \
|
299
474
|
"considered a conflict that should be resolved manually. Name of the object is: " \
|
300
|
-
"'#{component.display_name}'"
|
475
|
+
"'#{component.display_name}'. Existing component: #{component.to_tree_hash}. " \
|
476
|
+
"Change: #{change}"
|
301
477
|
end
|
302
478
|
|
303
479
|
if change["isa"] == "PBXFileReference"
|
@@ -320,7 +496,7 @@ module Kintsugi
|
|
320
496
|
end
|
321
497
|
|
322
498
|
def add_child_to_component(component, change, component_change_path)
|
323
|
-
change_path =
|
499
|
+
change_path = join_path(component_change_path, change["displayName"])
|
324
500
|
|
325
501
|
if change["ProjectRef"] && change["ProductGroup"]
|
326
502
|
add_subproject_reference(component, change, change_path)
|
@@ -426,6 +602,10 @@ module Kintsugi
|
|
426
602
|
end
|
427
603
|
containing_component.file_ref = file_reference
|
428
604
|
when Xcodeproj::Project::PBXGroup
|
605
|
+
return if !Settings.allow_duplicates &&
|
606
|
+
!find_file_in_group(containing_component, Xcodeproj::Project::PBXReferenceProxy,
|
607
|
+
change["path"]).nil?
|
608
|
+
|
429
609
|
reference_proxy = containing_component.project.new(Xcodeproj::Project::PBXReferenceProxy)
|
430
610
|
containing_component << reference_proxy
|
431
611
|
add_attributes_to_component(reference_proxy, change, change_path)
|
@@ -441,13 +621,11 @@ module Kintsugi
|
|
441
621
|
containing_component.file_ref =
|
442
622
|
find_variant_group(containing_component.project, change["displayName"])
|
443
623
|
when Xcodeproj::Project::PBXGroup, Xcodeproj::Project::PBXVariantGroup
|
444
|
-
|
445
|
-
|
624
|
+
if find_group_in_group(containing_component, Xcodeproj::Project::PBXVariantGroup,
|
625
|
+
change).nil?
|
626
|
+
raise "Group should have been added already, so this is most likely a bug in Kintsugi" \
|
627
|
+
"Change is: #{change}. Change path: #{change_path}"
|
446
628
|
end
|
447
|
-
|
448
|
-
variant_group = containing_component.project.new(Xcodeproj::Project::PBXVariantGroup)
|
449
|
-
containing_component.children << variant_group
|
450
|
-
add_attributes_to_component(variant_group, change, change_path)
|
451
629
|
else
|
452
630
|
raise MergeError, "Trying to add variant group to an unsupported component type " \
|
453
631
|
"#{containing_component.isa}. Change is: #{change}"
|
@@ -506,6 +684,11 @@ module Kintsugi
|
|
506
684
|
return
|
507
685
|
end
|
508
686
|
|
687
|
+
existing_build_file = build_phase.files.find do |build_file|
|
688
|
+
build_file.file_ref.path == change["fileRef"]["path"]
|
689
|
+
end
|
690
|
+
return if !Settings.allow_duplicates && !existing_build_file.nil?
|
691
|
+
|
509
692
|
build_file = build_phase.project.new(Xcodeproj::Project::PBXBuildFile)
|
510
693
|
build_phase.files << build_file
|
511
694
|
add_attributes_to_component(build_file, change, change_path)
|
@@ -581,6 +764,12 @@ module Kintsugi
|
|
581
764
|
end
|
582
765
|
|
583
766
|
def add_subproject_reference(root_object, project_reference_change, change_path)
|
767
|
+
existing_subproject =
|
768
|
+
root_object.project_references.find do |project_reference|
|
769
|
+
project_reference.project_ref.path == project_reference_change["ProjectRef"]["path"]
|
770
|
+
end
|
771
|
+
return if !Settings.allow_duplicates && !existing_subproject.nil?
|
772
|
+
|
584
773
|
filter_subproject_without_project_references = lambda do |file_reference|
|
585
774
|
root_object.project_references.find do |project_reference|
|
586
775
|
project_reference.project_ref.uuid == file_reference.uuid
|
@@ -645,48 +834,45 @@ module Kintsugi
|
|
645
834
|
when Xcodeproj::Project::PBXBuildFile
|
646
835
|
containing_component.file_ref = find_file(containing_component.project, change["path"])
|
647
836
|
when Xcodeproj::Project::PBXGroup, Xcodeproj::Project::PBXVariantGroup
|
648
|
-
|
649
|
-
|
837
|
+
if find_file_in_group(containing_component, Xcodeproj::Project::PBXFileReference,
|
838
|
+
change["path"]).nil?
|
839
|
+
raise "File should have been added already, so this is most likely a bug in Kintsugi" \
|
840
|
+
"Change is: #{change}. Change path: #{change_path}"
|
650
841
|
end
|
651
|
-
|
652
|
-
file_reference = containing_component.project.new(Xcodeproj::Project::PBXFileReference)
|
653
|
-
containing_component.children << file_reference
|
654
|
-
|
655
|
-
# For some reason, `include_in_index` is set to `1` and `source_tree` to `SDKROOT` by
|
656
|
-
# default.
|
657
|
-
file_reference.include_in_index = nil
|
658
|
-
file_reference.source_tree = nil
|
659
|
-
add_attributes_to_component(file_reference, change, change_path)
|
660
842
|
else
|
661
843
|
raise MergeError, "Trying to add file reference to an unsupported component type " \
|
662
844
|
"#{containing_component.isa}. Change is: #{change}"
|
663
845
|
end
|
664
846
|
end
|
665
847
|
|
848
|
+
def find_file_in_group(group, instance_type, filepath)
|
849
|
+
group
|
850
|
+
.children
|
851
|
+
.select { |child| child.instance_of?(instance_type) }
|
852
|
+
.find { |file| file.path == filepath }
|
853
|
+
end
|
854
|
+
|
666
855
|
def adding_files_and_groups_allowed?(change_path)
|
667
856
|
change_path.start_with?("rootObject/mainGroup") ||
|
668
857
|
change_path.start_with?("rootObject/projectReferences")
|
669
858
|
end
|
670
859
|
|
671
860
|
def add_group(containing_component, change, change_path)
|
672
|
-
unless adding_files_and_groups_allowed?(change_path)
|
673
|
-
return
|
674
|
-
end
|
675
|
-
|
676
861
|
case containing_component
|
677
862
|
when Xcodeproj::Project::ObjectDictionary
|
678
863
|
# It is assumed that an `ObjectDictionary` always represents a project reference.
|
679
864
|
new_group = containing_component[:project_ref].project.new(Xcodeproj::Project::PBXGroup)
|
680
865
|
containing_component[:product_group] = new_group
|
866
|
+
add_attributes_to_component(new_group, change, change_path)
|
681
867
|
when Xcodeproj::Project::PBXGroup
|
682
|
-
|
683
|
-
|
868
|
+
if find_group_in_group(containing_component, Xcodeproj::Project::PBXGroup, change).nil?
|
869
|
+
raise "Group should have been added already, so this is most likely a bug in Kintsugi" \
|
870
|
+
"Change is: #{change}. Change path: #{change_path}"
|
871
|
+
end
|
684
872
|
else
|
685
873
|
raise MergeError, "Trying to add group to an unsupported component type " \
|
686
|
-
"#{containing_component.isa}. Change is: #{change}"
|
874
|
+
"#{containing_component.isa}. Change is: #{change}. Change path: #{change_path}"
|
687
875
|
end
|
688
|
-
|
689
|
-
add_attributes_to_component(new_group, change, change_path)
|
690
876
|
end
|
691
877
|
|
692
878
|
def add_attributes_to_component(component, change, change_path, ignore_keys: [])
|
@@ -739,12 +925,9 @@ module Kintsugi
|
|
739
925
|
|
740
926
|
def find_reference_proxy(project, container_item_proxy_change, reference_filter: ->(_) { true })
|
741
927
|
reference_proxies = project.root_object.project_references.map do |project_ref_and_products|
|
742
|
-
project_ref_and_products[:product_group].children
|
743
|
-
|
744
|
-
|
745
|
-
product.remote_ref.remote_info == container_item_proxy_change["remoteInfo"] &&
|
746
|
-
reference_filter.call(product)
|
747
|
-
end
|
928
|
+
find_reference_proxy_in_component(project_ref_and_products[:product_group].children,
|
929
|
+
container_item_proxy_change,
|
930
|
+
reference_filter: reference_filter)
|
748
931
|
end.compact
|
749
932
|
|
750
933
|
if reference_proxies.length > 1
|
@@ -758,5 +941,19 @@ module Kintsugi
|
|
758
941
|
|
759
942
|
reference_proxies.first
|
760
943
|
end
|
944
|
+
|
945
|
+
def find_reference_proxy_in_component(component, container_item_proxy_change,
|
946
|
+
reference_filter: ->(_) { true })
|
947
|
+
component.find do |product|
|
948
|
+
product.remote_ref.remote_global_id_string ==
|
949
|
+
container_item_proxy_change["remoteGlobalIDString"] &&
|
950
|
+
product.remote_ref.remote_info == container_item_proxy_change["remoteInfo"] &&
|
951
|
+
reference_filter.call(product)
|
952
|
+
end
|
953
|
+
end
|
954
|
+
|
955
|
+
def join_path(left, right)
|
956
|
+
left.empty? ? right : "#{left}/#{right}"
|
957
|
+
end
|
761
958
|
end
|
762
959
|
end
|
data/lib/kintsugi/cli.rb
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
require "fileutils"
|
6
6
|
require "optparse"
|
7
7
|
|
8
|
+
require_relative "settings"
|
8
9
|
require_relative "version"
|
9
10
|
|
10
11
|
module Kintsugi
|
@@ -182,6 +183,8 @@ module Kintsugi
|
|
182
183
|
exit
|
183
184
|
end
|
184
185
|
|
186
|
+
opts.on("--allow-duplicates", "Allow to add duplicates of the same entity")
|
187
|
+
|
185
188
|
opts.on_tail("\nSUBCOMMANDS\n#{subcommands_descriptions(subcommands)}")
|
186
189
|
end
|
187
190
|
|
@@ -192,6 +195,10 @@ module Kintsugi
|
|
192
195
|
exit(1)
|
193
196
|
end
|
194
197
|
|
198
|
+
if options[:"allow-duplicates"]
|
199
|
+
Settings.allow_duplicates = true
|
200
|
+
end
|
201
|
+
|
195
202
|
project_file_path = File.expand_path(arguments[0])
|
196
203
|
Kintsugi.resolve_conflicts(project_file_path, options[:"changes-output-path"])
|
197
204
|
puts "Resolved conflicts successfully"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Copyright (c) 2022 Lightricks. All rights reserved.
|
2
|
+
# Created by Ben Yohay.
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
module Kintsugi
|
6
|
+
# Kintsugi global settings.
|
7
|
+
class Settings
|
8
|
+
class << self
|
9
|
+
# `true` if Kintsugi can create entities that are identical to existing ones, `false`
|
10
|
+
# otherwise.
|
11
|
+
attr_writer :allow_duplicates
|
12
|
+
|
13
|
+
def allow_duplicates
|
14
|
+
@allow_duplicates || false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|