kintsugi 0.6.3 → 0.7.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.
@@ -6,9 +6,11 @@ require "json"
6
6
  require "rspec"
7
7
  require "tempfile"
8
8
  require "tmpdir"
9
+ require "tty-prompt"
9
10
 
10
11
  require "kintsugi/apply_change_to_project"
11
12
  require "kintsugi/error"
13
+ require "tty/prompt/test"
12
14
 
13
15
  require_relative "be_equivalent_to_project"
14
16
 
@@ -18,6 +20,7 @@ describe Kintsugi, :apply_change_to_project do
18
20
  let(:base_project) { Xcodeproj::Project.new(base_project_path) }
19
21
 
20
22
  before do
23
+ Kintsugi::Settings.interactive_resolution = false
21
24
  base_project.save
22
25
  end
23
26
 
@@ -29,8 +32,9 @@ describe Kintsugi, :apply_change_to_project do
29
32
 
30
33
  it "not raises when change is nil or doesn't have root object" do
31
34
  expect {
32
- described_class.apply_change_to_project(base_project, nil)
33
- described_class.apply_change_to_project(base_project, {})
35
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
36
+ described_class.apply_change_to_project(base_project, nil, theirs_project)
37
+ described_class.apply_change_to_project(base_project, {}, theirs_project)
34
38
  }.not_to raise_error
35
39
  end
36
40
 
@@ -40,7 +44,7 @@ describe Kintsugi, :apply_change_to_project do
40
44
 
41
45
  changes_to_apply = get_diff(theirs_project, base_project)
42
46
 
43
- described_class.apply_change_to_project(base_project, changes_to_apply)
47
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
44
48
 
45
49
  expect(base_project).to be_equivalent_to_project(theirs_project)
46
50
  end
@@ -51,7 +55,7 @@ describe Kintsugi, :apply_change_to_project do
51
55
 
52
56
  changes_to_apply = get_diff(theirs_project, base_project)
53
57
 
54
- described_class.apply_change_to_project(base_project, changes_to_apply)
58
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
55
59
 
56
60
  expect(base_project).to be_equivalent_to_project(theirs_project)
57
61
  end
@@ -64,7 +68,7 @@ describe Kintsugi, :apply_change_to_project do
64
68
 
65
69
  changes_to_apply = get_diff(theirs_project, base_project)
66
70
 
67
- described_class.apply_change_to_project(base_project, changes_to_apply)
71
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
68
72
 
69
73
  expect(base_project).to be_equivalent_to_project(theirs_project)
70
74
  end
@@ -75,7 +79,7 @@ describe Kintsugi, :apply_change_to_project do
75
79
 
76
80
  changes_to_apply = get_diff(theirs_project, base_project)
77
81
 
78
- described_class.apply_change_to_project(base_project, changes_to_apply)
82
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
79
83
 
80
84
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
81
85
  end
@@ -96,7 +100,7 @@ describe Kintsugi, :apply_change_to_project do
96
100
 
97
101
  changes_to_apply = get_diff(theirs_project, base_project)
98
102
 
99
- described_class.apply_change_to_project(base_project, changes_to_apply)
103
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
100
104
 
101
105
  expect(base_project).to be_equivalent_to_project(theirs_project)
102
106
  end
@@ -113,7 +117,7 @@ describe Kintsugi, :apply_change_to_project do
113
117
 
114
118
  changes_to_apply = get_diff(theirs_project, base_project)
115
119
 
116
- described_class.apply_change_to_project(base_project, changes_to_apply)
120
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
117
121
 
118
122
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
119
123
  end
@@ -131,10 +135,27 @@ describe Kintsugi, :apply_change_to_project do
131
135
  changes_to_apply = get_diff(theirs_project, base_project)
132
136
 
133
137
  expect {
134
- described_class.apply_change_to_project(ours_project, changes_to_apply)
138
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
135
139
  }.to raise_error(Kintsugi::MergeError)
136
140
  end
137
141
 
142
+ it "ignores removal of a product reference that was already removed" do
143
+ base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
144
+ base_project.save
145
+
146
+ ours_project = create_copy_of_project(base_project.path, "ours")
147
+ ours_project.targets[0].product_reference.remove_from_project
148
+
149
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
150
+ theirs_project.targets[0].product_reference.remove_from_project
151
+
152
+ changes_to_apply = get_diff(theirs_project, base_project)
153
+
154
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
155
+
156
+ expect(ours_project).to be_equivalent_to_project(theirs_project)
157
+ end
158
+
138
159
  describe "file related changes" do
139
160
  let(:filepath) { "foo" }
140
161
 
@@ -154,7 +175,7 @@ describe Kintsugi, :apply_change_to_project do
154
175
 
155
176
  changes_to_apply = get_diff(theirs_project, base_project)
156
177
 
157
- described_class.apply_change_to_project(base_project, changes_to_apply)
178
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
158
179
 
159
180
  expect(base_project).to be_equivalent_to_project(theirs_project)
160
181
  end
@@ -173,7 +194,7 @@ describe Kintsugi, :apply_change_to_project do
173
194
  base_project.main_group.find_subpath("new_group").remove_from_project
174
195
 
175
196
  expect {
176
- described_class.apply_change_to_project(base_project, changes_to_apply)
197
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
177
198
  }.to raise_error(Kintsugi::MergeError)
178
199
  end
179
200
 
@@ -189,7 +210,7 @@ describe Kintsugi, :apply_change_to_project do
189
210
  base_project.main_group.find_subpath("new_group").remove_from_project
190
211
 
191
212
  expect {
192
- described_class.apply_change_to_project(base_project, changes_to_apply)
213
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
193
214
  }.to raise_error(Kintsugi::MergeError)
194
215
  end
195
216
 
@@ -207,7 +228,7 @@ describe Kintsugi, :apply_change_to_project do
207
228
  base_project.save
208
229
  expected_project = create_copy_of_project(base_project.path, "expected")
209
230
 
210
- described_class.apply_change_to_project(base_project, changes_to_apply)
231
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
211
232
 
212
233
  expect(base_project).to be_equivalent_to_project(expected_project)
213
234
  end
@@ -226,7 +247,7 @@ describe Kintsugi, :apply_change_to_project do
226
247
  changes_to_apply = get_diff(theirs_project, base_project)
227
248
 
228
249
  expect {
229
- described_class.apply_change_to_project(base_project, changes_to_apply)
250
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
230
251
  }.to raise_error(Kintsugi::MergeError)
231
252
  end
232
253
 
@@ -237,7 +258,7 @@ describe Kintsugi, :apply_change_to_project do
237
258
 
238
259
  changes_to_apply = get_diff(theirs_project, base_project)
239
260
 
240
- described_class.apply_change_to_project(base_project, changes_to_apply)
261
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
241
262
 
242
263
  expect(base_project).to be_equivalent_to_project(theirs_project)
243
264
  end
@@ -251,7 +272,7 @@ describe Kintsugi, :apply_change_to_project do
251
272
 
252
273
  changes_to_apply = get_diff(theirs_project, base_project)
253
274
 
254
- described_class.apply_change_to_project(base_project, changes_to_apply)
275
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
255
276
 
256
277
  expect(base_project).to be_equivalent_to_project(theirs_project)
257
278
  end
@@ -267,7 +288,7 @@ describe Kintsugi, :apply_change_to_project do
267
288
 
268
289
  changes_to_apply = get_diff(theirs_project, base_project)
269
290
 
270
- described_class.apply_change_to_project(base_project, changes_to_apply)
291
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
271
292
 
272
293
  expect(base_project).to be_equivalent_to_project(theirs_project)
273
294
  end
@@ -284,7 +305,7 @@ describe Kintsugi, :apply_change_to_project do
284
305
  base_project.main_group.find_subpath("new_group").remove_from_project
285
306
 
286
307
  expect {
287
- described_class.apply_change_to_project(base_project, changes_to_apply)
308
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
288
309
  }.to raise_error(Kintsugi::MergeError)
289
310
  end
290
311
 
@@ -301,7 +322,7 @@ describe Kintsugi, :apply_change_to_project do
301
322
  base_project.main_group.find_subpath("new_group").remove_from_project
302
323
 
303
324
  expect {
304
- described_class.apply_change_to_project(base_project, changes_to_apply)
325
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
305
326
  }.to raise_error(Kintsugi::MergeError)
306
327
  end
307
328
 
@@ -316,7 +337,7 @@ describe Kintsugi, :apply_change_to_project do
316
337
 
317
338
  changes_to_apply = get_diff(theirs_project, base_project)
318
339
 
319
- described_class.apply_change_to_project(base_project, changes_to_apply)
340
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
320
341
 
321
342
  expect(base_project).to be_equivalent_to_project(theirs_project)
322
343
  end
@@ -333,7 +354,7 @@ describe Kintsugi, :apply_change_to_project do
333
354
 
334
355
  changes_to_apply = get_diff(theirs_project, base_project)
335
356
 
336
- described_class.apply_change_to_project(base_project, changes_to_apply)
357
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
337
358
 
338
359
  expect(base_project).to be_equivalent_to_project(theirs_project)
339
360
  end
@@ -346,7 +367,7 @@ describe Kintsugi, :apply_change_to_project do
346
367
 
347
368
  changes_to_apply = get_diff(theirs_project, base_project)
348
369
 
349
- described_class.apply_change_to_project(base_project, changes_to_apply)
370
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
350
371
 
351
372
  expect(base_project).to be_equivalent_to_project(theirs_project)
352
373
  end
@@ -358,7 +379,7 @@ describe Kintsugi, :apply_change_to_project do
358
379
 
359
380
  changes_to_apply = get_diff(theirs_project, base_project)
360
381
 
361
- described_class.apply_change_to_project(base_project, changes_to_apply)
382
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
362
383
 
363
384
  expect(base_project).to be_equivalent_to_project(theirs_project)
364
385
  end
@@ -369,7 +390,7 @@ describe Kintsugi, :apply_change_to_project do
369
390
 
370
391
  changes_to_apply = get_diff(theirs_project, base_project)
371
392
 
372
- described_class.apply_change_to_project(base_project, changes_to_apply)
393
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
373
394
 
374
395
  expect(base_project).to be_equivalent_to_project(theirs_project)
375
396
  end
@@ -386,7 +407,7 @@ describe Kintsugi, :apply_change_to_project do
386
407
 
387
408
  changes_to_apply = get_diff(theirs_project, base_project)
388
409
 
389
- described_class.apply_change_to_project(base_project, changes_to_apply)
410
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
390
411
 
391
412
  expect(base_project).to be_equivalent_to_project(theirs_project)
392
413
  end
@@ -402,7 +423,7 @@ describe Kintsugi, :apply_change_to_project do
402
423
 
403
424
  base_project.main_group.children.delete_at(-1)
404
425
 
405
- described_class.apply_change_to_project(base_project, changes_to_apply)
426
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
406
427
 
407
428
  expect(base_project).to be_equivalent_to_project(theirs_project)
408
429
  end
@@ -425,7 +446,7 @@ describe Kintsugi, :apply_change_to_project do
425
446
 
426
447
  changes_to_apply = get_diff(theirs_project, base_project)
427
448
 
428
- described_class.apply_change_to_project(base_project, changes_to_apply)
449
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
429
450
 
430
451
  expect(base_project).to be_equivalent_to_project(theirs_project)
431
452
  end
@@ -440,7 +461,7 @@ describe Kintsugi, :apply_change_to_project do
440
461
 
441
462
  changes_to_apply = get_diff(theirs_project, base_project)
442
463
 
443
- described_class.apply_change_to_project(base_project, changes_to_apply)
464
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
444
465
 
445
466
  expect(base_project).to be_equivalent_to_project(theirs_project)
446
467
  end
@@ -454,7 +475,7 @@ describe Kintsugi, :apply_change_to_project do
454
475
 
455
476
  changes_to_apply = get_diff(theirs_project, base_project)
456
477
 
457
- described_class.apply_change_to_project(base_project, changes_to_apply)
478
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
458
479
 
459
480
  expect(base_project).to be_equivalent_to_project(theirs_project)
460
481
  end
@@ -469,30 +490,31 @@ describe Kintsugi, :apply_change_to_project do
469
490
 
470
491
  changes_to_apply = get_diff(theirs_project, base_project)
471
492
 
472
- described_class.apply_change_to_project(base_project, changes_to_apply)
493
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
473
494
 
474
495
  expect(base_project).to be_equivalent_to_project(theirs_project)
475
496
  end
476
497
 
477
498
  describe "dealing with unexpected change" do
478
- it "ignores change to a file whose containing group doesn't exist" do
499
+ it "raises if applying change to a file whose containing group doesn't exist" do
479
500
  ours_project = create_copy_of_project(base_project.path, "ours")
480
- ours_project.main_group.remove_from_project
501
+ new_group = ours_project.main_group.find_subpath("new_group", true)
502
+ ours_project.main_group.find_file_by_path(filepath).move(new_group)
481
503
  ours_project.save
482
504
 
483
505
  theirs_project = create_copy_of_project(base_project.path, "theirs")
484
506
  theirs_project.main_group.find_file_by_path(filepath).explicit_file_type = "bar"
485
507
 
486
- changes_to_apply = get_diff(theirs_project, base_project)
508
+ ours_project.main_group.find_subpath("new_group").remove_from_project
487
509
 
488
- ours_project_before_applying_changes = create_copy_of_project(ours_project.path, "ours")
489
-
490
- described_class.apply_change_to_project(ours_project, changes_to_apply)
510
+ changes_to_apply = get_diff(theirs_project, base_project)
491
511
 
492
- expect(ours_project).to be_equivalent_to_project(ours_project_before_applying_changes)
512
+ expect {
513
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
514
+ }.to raise_error(Kintsugi::MergeError)
493
515
  end
494
516
 
495
- it "ignores change to a file that doesn't exist" do
517
+ it "raises if applying change to a file that doesn't exist" do
496
518
  ours_project = create_copy_of_project(base_project.path, "ours")
497
519
  ours_project.main_group.find_file_by_path(filepath).remove_from_project
498
520
  ours_project.save
@@ -502,11 +524,9 @@ describe Kintsugi, :apply_change_to_project do
502
524
 
503
525
  changes_to_apply = get_diff(theirs_project, base_project)
504
526
 
505
- ours_project_before_applying_changes = create_copy_of_project(ours_project.path, "ours")
506
-
507
- described_class.apply_change_to_project(ours_project, changes_to_apply)
508
-
509
- expect(ours_project).to be_equivalent_to_project(ours_project_before_applying_changes)
527
+ expect {
528
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
529
+ }.to raise_error(Kintsugi::MergeError)
510
530
  end
511
531
 
512
532
  it "ignores removal of a file whose group doesn't exist" do
@@ -521,7 +541,7 @@ describe Kintsugi, :apply_change_to_project do
521
541
 
522
542
  ours_project_before_applying_changes = create_copy_of_project(ours_project.path, "ours")
523
543
 
524
- described_class.apply_change_to_project(ours_project, changes_to_apply)
544
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
525
545
 
526
546
  expect(ours_project).to be_equivalent_to_project(ours_project_before_applying_changes)
527
547
  end
@@ -535,7 +555,7 @@ describe Kintsugi, :apply_change_to_project do
535
555
 
536
556
  changes_to_apply = get_diff(theirs_project, base_project)
537
557
 
538
- described_class.apply_change_to_project(ours_project, changes_to_apply)
558
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
539
559
 
540
560
  expect(ours_project).to be_equivalent_to_project(theirs_project)
541
561
  end
@@ -560,7 +580,7 @@ describe Kintsugi, :apply_change_to_project do
560
580
  file_reference.move(new_group)
561
581
  changes_to_apply = get_diff(theirs_project, base_project)
562
582
 
563
- described_class.apply_change_to_project(base_project, changes_to_apply)
583
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
564
584
 
565
585
  expect(base_project).to be_equivalent_to_project(theirs_project)
566
586
  end
@@ -575,7 +595,7 @@ describe Kintsugi, :apply_change_to_project do
575
595
  file_reference.move(theirs_project.main_group)
576
596
  changes_to_apply = get_diff(theirs_project, base_project)
577
597
 
578
- described_class.apply_change_to_project(base_project, changes_to_apply)
598
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
579
599
 
580
600
  expect(base_project).to be_equivalent_to_project(theirs_project)
581
601
  end
@@ -592,7 +612,7 @@ describe Kintsugi, :apply_change_to_project do
592
612
 
593
613
  changes_to_apply = get_diff(theirs_project, base_project)
594
614
 
595
- described_class.apply_change_to_project(base_project, changes_to_apply)
615
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
596
616
 
597
617
  expect(base_project).to be_equivalent_to_project(theirs_project)
598
618
  end
@@ -604,6 +624,10 @@ describe Kintsugi, :apply_change_to_project do
604
624
  base_project.targets[0].frameworks_build_phase.add_file_reference(file_reference)
605
625
 
606
626
  add_new_subproject_to_project(base_project, "subproj", framework_filename)
627
+
628
+ # Removes the container item proxy to make sure the display name of the reference proxy is the
629
+ # same as the file reference.
630
+ base_project.root_object.project_references[-1][:product_group].children[0].remote_ref.remove_from_project
607
631
  base_project.save
608
632
 
609
633
  theirs_project = create_copy_of_project(base_project.path, "theirs")
@@ -616,7 +640,7 @@ describe Kintsugi, :apply_change_to_project do
616
640
 
617
641
  changes_to_apply = get_diff(theirs_project, base_project)
618
642
 
619
- described_class.apply_change_to_project(base_project, changes_to_apply)
643
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
620
644
 
621
645
  expect(base_project).to be_equivalent_to_project(theirs_project)
622
646
  end
@@ -628,7 +652,7 @@ describe Kintsugi, :apply_change_to_project do
628
652
 
629
653
  changes_to_apply = get_diff(theirs_project, base_project)
630
654
 
631
- described_class.apply_change_to_project(base_project, changes_to_apply)
655
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
632
656
 
633
657
  expect(base_project).to be_equivalent_to_project(theirs_project)
634
658
  end
@@ -637,9 +661,12 @@ describe Kintsugi, :apply_change_to_project do
637
661
  framework_filename = "baz"
638
662
 
639
663
  add_new_subproject_to_project(base_project, "subproj", framework_filename)
640
- base_project.targets[0].frameworks_build_phase.add_file_reference(
664
+ subproject_reference_proxy =
641
665
  base_project.root_object.project_references[0][:product_group].children[0]
642
- )
666
+ # Removes the container item proxy to make sure the display name of the reference proxy is the
667
+ # same as the file reference.
668
+ subproject_reference_proxy.remote_ref.remove_from_project
669
+ base_project.targets[0].frameworks_build_phase.add_file_reference(subproject_reference_proxy)
643
670
 
644
671
  base_project.save
645
672
 
@@ -653,7 +680,7 @@ describe Kintsugi, :apply_change_to_project do
653
680
 
654
681
  changes_to_apply = get_diff(theirs_project, base_project)
655
682
 
656
- described_class.apply_change_to_project(base_project, changes_to_apply)
683
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
657
684
  # This verifies we haven't created a new file reference instead of reusing the one in the
658
685
  # hierarchy.
659
686
  base_project.files[-1].name = "foo"
@@ -681,9 +708,7 @@ describe Kintsugi, :apply_change_to_project do
681
708
 
682
709
  changes_to_apply = get_diff(theirs_project, base_project)
683
710
 
684
- changes_to_apply["rootObject"].delete("projectReferences")
685
-
686
- described_class.apply_change_to_project(base_project, changes_to_apply)
711
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
687
712
 
688
713
  expect(base_project).to be_equivalent_to_project(theirs_project)
689
714
  end
@@ -709,7 +734,7 @@ describe Kintsugi, :apply_change_to_project do
709
734
 
710
735
  changes_to_apply = get_diff(theirs_project, base_project)
711
736
 
712
- described_class.apply_change_to_project(base_project, changes_to_apply)
737
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
713
738
 
714
739
  expect(base_project).to be_equivalent_to_project(theirs_project)
715
740
  end
@@ -725,7 +750,7 @@ describe Kintsugi, :apply_change_to_project do
725
750
 
726
751
  changes_to_apply = get_diff(theirs_project, base_project)
727
752
 
728
- described_class.apply_change_to_project(base_project, changes_to_apply)
753
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
729
754
 
730
755
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
731
756
  end
@@ -741,7 +766,7 @@ describe Kintsugi, :apply_change_to_project do
741
766
 
742
767
  changes_to_apply = get_diff(theirs_project, base_project)
743
768
  other_project = create_copy_of_project(base_project.path, "theirs")
744
- described_class.apply_change_to_project(other_project, changes_to_apply)
769
+ described_class.apply_change_to_project(other_project, changes_to_apply, theirs_project)
745
770
 
746
771
  expect(other_project).to be_equivalent_to_project(theirs_project)
747
772
  end
@@ -760,7 +785,7 @@ describe Kintsugi, :apply_change_to_project do
760
785
 
761
786
  changes_to_apply = get_diff(theirs_project, base_project)
762
787
 
763
- described_class.apply_change_to_project(base_project, changes_to_apply)
788
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
764
789
 
765
790
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
766
791
  end
@@ -780,7 +805,7 @@ describe Kintsugi, :apply_change_to_project do
780
805
 
781
806
  changes_to_apply = get_diff(theirs_project, base_project)
782
807
 
783
- described_class.apply_change_to_project(base_project, changes_to_apply)
808
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
784
809
 
785
810
  expect(base_project).to be_equivalent_to_project(theirs_project)
786
811
  end
@@ -798,7 +823,7 @@ describe Kintsugi, :apply_change_to_project do
798
823
 
799
824
  changes_to_apply = get_diff(theirs_project, base_project)
800
825
 
801
- described_class.apply_change_to_project(base_project, changes_to_apply)
826
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
802
827
 
803
828
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
804
829
  end
@@ -816,7 +841,7 @@ describe Kintsugi, :apply_change_to_project do
816
841
  changes_to_apply = get_diff(theirs_project, base_project)
817
842
 
818
843
  other_project = create_copy_of_project(base_project.path, "other")
819
- described_class.apply_change_to_project(other_project, changes_to_apply)
844
+ described_class.apply_change_to_project(other_project, changes_to_apply, theirs_project)
820
845
 
821
846
  expect(other_project).to be_equivalent_to_project(base_project)
822
847
  end
@@ -841,7 +866,7 @@ describe Kintsugi, :apply_change_to_project do
841
866
 
842
867
  changes_to_apply = get_diff(theirs_project, base_project)
843
868
 
844
- described_class.apply_change_to_project(base_project, changes_to_apply)
869
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
845
870
 
846
871
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
847
872
  end
@@ -856,7 +881,7 @@ describe Kintsugi, :apply_change_to_project do
856
881
 
857
882
  changes_to_apply = get_diff(theirs_project, base_project)
858
883
 
859
- described_class.apply_change_to_project(base_project, changes_to_apply)
884
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
860
885
 
861
886
  expect(base_project).to be_equivalent_to_project(theirs_project)
862
887
  end
@@ -876,7 +901,7 @@ describe Kintsugi, :apply_change_to_project do
876
901
 
877
902
  changes_to_apply = get_diff(theirs_project, base_project)
878
903
 
879
- described_class.apply_change_to_project(base_project, changes_to_apply)
904
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
880
905
 
881
906
  expect(base_project).to be_equivalent_to_project(theirs_project)
882
907
  end
@@ -893,7 +918,7 @@ describe Kintsugi, :apply_change_to_project do
893
918
 
894
919
  changes_to_apply = get_diff(theirs_project, base_project)
895
920
 
896
- described_class.apply_change_to_project(base_project, changes_to_apply)
921
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
897
922
 
898
923
  expect(base_project).to be_equivalent_to_project(theirs_project)
899
924
  end
@@ -916,7 +941,7 @@ describe Kintsugi, :apply_change_to_project do
916
941
 
917
942
  changes_to_apply = get_diff(theirs_project, base_project)
918
943
 
919
- described_class.apply_change_to_project(base_project, changes_to_apply)
944
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
920
945
 
921
946
  expect(base_project).to be_equivalent_to_project(theirs_project)
922
947
  end
@@ -934,7 +959,7 @@ describe Kintsugi, :apply_change_to_project do
934
959
  configuration.build_settings["HEADER_SEARCH_PATHS"] = "baz"
935
960
  end
936
961
 
937
- described_class.apply_change_to_project(ours_project, changes_to_apply)
962
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
938
963
 
939
964
  expected_project = create_copy_of_project(base_project.path, "expected")
940
965
  expected_project.targets[0].build_configurations.each do |configuration|
@@ -956,7 +981,7 @@ describe Kintsugi, :apply_change_to_project do
956
981
  configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[bar foo]
957
982
  end
958
983
 
959
- described_class.apply_change_to_project(ours_project, changes_to_apply)
984
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
960
985
 
961
986
  expected_project = create_copy_of_project(base_project.path, "expected")
962
987
  expected_project.targets[0].build_configurations.each do |configuration|
@@ -981,7 +1006,7 @@ describe Kintsugi, :apply_change_to_project do
981
1006
 
982
1007
  changes_to_apply = get_diff(theirs_project, base_project)
983
1008
 
984
- described_class.apply_change_to_project(base_project, changes_to_apply)
1009
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
985
1010
 
986
1011
  expect(base_project).to be_equivalent_to_project(theirs_project)
987
1012
  end
@@ -1000,7 +1025,7 @@ describe Kintsugi, :apply_change_to_project do
1000
1025
 
1001
1026
  changes_to_apply = get_diff(theirs_project, base_project)
1002
1027
 
1003
- described_class.apply_change_to_project(base_project, changes_to_apply)
1028
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1004
1029
 
1005
1030
  expect(base_project).to be_equivalent_to_project(theirs_project)
1006
1031
  end
@@ -1018,7 +1043,7 @@ describe Kintsugi, :apply_change_to_project do
1018
1043
 
1019
1044
  changes_to_apply = get_diff(theirs_project, base_project)
1020
1045
 
1021
- described_class.apply_change_to_project(base_project, changes_to_apply)
1046
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1022
1047
 
1023
1048
  expect(base_project).to be_equivalent_to_project(theirs_project)
1024
1049
  end
@@ -1042,7 +1067,7 @@ describe Kintsugi, :apply_change_to_project do
1042
1067
 
1043
1068
  changes_to_apply = get_diff(theirs_project, base_project)
1044
1069
 
1045
- described_class.apply_change_to_project(base_project, changes_to_apply)
1070
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1046
1071
 
1047
1072
  expect(base_project).to be_equivalent_to_project(theirs_project)
1048
1073
  end
@@ -1062,7 +1087,7 @@ describe Kintsugi, :apply_change_to_project do
1062
1087
 
1063
1088
  changes_to_apply = get_diff(theirs_project, before_theirs_project)
1064
1089
 
1065
- described_class.apply_change_to_project(base_project, changes_to_apply)
1090
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1066
1091
 
1067
1092
  expect(base_project).to be_equivalent_to_project(theirs_project)
1068
1093
  end
@@ -1082,7 +1107,7 @@ describe Kintsugi, :apply_change_to_project do
1082
1107
 
1083
1108
  changes_to_apply = get_diff(theirs_project, before_theirs_project)
1084
1109
 
1085
- described_class.apply_change_to_project(base_project, changes_to_apply)
1110
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1086
1111
 
1087
1112
  expect(base_project).to be_equivalent_to_project(theirs_project)
1088
1113
  end
@@ -1103,7 +1128,7 @@ describe Kintsugi, :apply_change_to_project do
1103
1128
 
1104
1129
  changes_to_apply = get_diff(theirs_project, before_theirs_project)
1105
1130
 
1106
- described_class.apply_change_to_project(base_project, changes_to_apply)
1131
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1107
1132
  base_project.save
1108
1133
 
1109
1134
  expected_project = create_copy_of_project(base_project.path, "expected")
@@ -1129,7 +1154,7 @@ describe Kintsugi, :apply_change_to_project do
1129
1154
 
1130
1155
  changes_to_apply = get_diff(theirs_project, before_theirs_project)
1131
1156
 
1132
- described_class.apply_change_to_project(base_project, changes_to_apply)
1157
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1133
1158
  base_project.save
1134
1159
 
1135
1160
  expected_project = create_copy_of_project(base_project.path, "expected")
@@ -1152,7 +1177,7 @@ describe Kintsugi, :apply_change_to_project do
1152
1177
 
1153
1178
  changes_to_apply = get_diff(theirs_project, base_project)
1154
1179
 
1155
- described_class.apply_change_to_project(base_project, changes_to_apply)
1180
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1156
1181
 
1157
1182
  expect(base_project).to be_equivalent_to_project(theirs_project)
1158
1183
  end
@@ -1170,7 +1195,7 @@ describe Kintsugi, :apply_change_to_project do
1170
1195
 
1171
1196
  changes_to_apply = get_diff(theirs_project, base_project)
1172
1197
 
1173
- described_class.apply_change_to_project(base_project, changes_to_apply)
1198
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1174
1199
 
1175
1200
  expect(base_project).to be_equivalent_to_project(theirs_project)
1176
1201
  end
@@ -1196,7 +1221,7 @@ describe Kintsugi, :apply_change_to_project do
1196
1221
 
1197
1222
  changes_to_apply = get_diff(theirs_project, before_theirs_project)
1198
1223
 
1199
- described_class.apply_change_to_project(base_project, changes_to_apply)
1224
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1200
1225
 
1201
1226
  expect(base_project).to be_equivalent_to_project(expected_project)
1202
1227
  end
@@ -1218,7 +1243,7 @@ describe Kintsugi, :apply_change_to_project do
1218
1243
  changes_to_apply = get_diff(theirs_project, before_theirs_project)
1219
1244
 
1220
1245
  expect {
1221
- described_class.apply_change_to_project(base_project, changes_to_apply)
1246
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1222
1247
  }.to raise_error(Kintsugi::MergeError)
1223
1248
  end
1224
1249
 
@@ -1242,7 +1267,7 @@ describe Kintsugi, :apply_change_to_project do
1242
1267
  changes_to_apply = get_diff(theirs_project, before_theirs_project)
1243
1268
 
1244
1269
  expect {
1245
- described_class.apply_change_to_project(base_project, changes_to_apply)
1270
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1246
1271
  }.to raise_error(Kintsugi::MergeError)
1247
1272
  end
1248
1273
  end
@@ -1259,7 +1284,7 @@ describe Kintsugi, :apply_change_to_project do
1259
1284
 
1260
1285
  changes_to_apply = get_diff(theirs_project, base_project)
1261
1286
 
1262
- described_class.apply_change_to_project(base_project, changes_to_apply)
1287
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1263
1288
 
1264
1289
  expect(base_project).to be_equivalent_to_project(theirs_project)
1265
1290
  end
@@ -1271,7 +1296,7 @@ describe Kintsugi, :apply_change_to_project do
1271
1296
 
1272
1297
  changes_to_apply = get_diff(theirs_project, base_project)
1273
1298
 
1274
- described_class.apply_change_to_project(base_project, changes_to_apply)
1299
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1275
1300
 
1276
1301
  expect(base_project).to be_equivalent_to_project(theirs_project)
1277
1302
  end
@@ -1285,7 +1310,7 @@ describe Kintsugi, :apply_change_to_project do
1285
1310
 
1286
1311
  changes_to_apply = get_diff(theirs_project, base_project)
1287
1312
 
1288
- described_class.apply_change_to_project(base_project, changes_to_apply)
1313
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1289
1314
 
1290
1315
  expect(base_project).to be_equivalent_to_project(theirs_project)
1291
1316
  end
@@ -1303,7 +1328,7 @@ describe Kintsugi, :apply_change_to_project do
1303
1328
 
1304
1329
  changes_to_apply = get_diff(theirs_project, base_project)
1305
1330
 
1306
- described_class.apply_change_to_project(base_project, changes_to_apply)
1331
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1307
1332
 
1308
1333
  expect(base_project).to be_equivalent_to_project(theirs_project)
1309
1334
  end
@@ -1317,7 +1342,7 @@ describe Kintsugi, :apply_change_to_project do
1317
1342
 
1318
1343
  changes_to_apply = get_diff(theirs_project, base_project)
1319
1344
 
1320
- described_class.apply_change_to_project(base_project, changes_to_apply)
1345
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1321
1346
 
1322
1347
  expect(base_project).to be_equivalent_to_project(theirs_project)
1323
1348
  end
@@ -1335,7 +1360,7 @@ describe Kintsugi, :apply_change_to_project do
1335
1360
 
1336
1361
  changes_to_apply = get_diff(theirs_project, base_project)
1337
1362
 
1338
- described_class.apply_change_to_project(base_project, changes_to_apply)
1363
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1339
1364
 
1340
1365
  expect(base_project).to be_equivalent_to_project(theirs_project)
1341
1366
  end
@@ -1349,7 +1374,7 @@ describe Kintsugi, :apply_change_to_project do
1349
1374
 
1350
1375
  changes_to_apply = get_diff(theirs_project, base_project)
1351
1376
 
1352
- described_class.apply_change_to_project(base_project, changes_to_apply)
1377
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1353
1378
 
1354
1379
  expect(base_project).to be_equivalent_to_project(theirs_project)
1355
1380
  end
@@ -1365,7 +1390,7 @@ describe Kintsugi, :apply_change_to_project do
1365
1390
 
1366
1391
  changes_to_apply = get_diff(theirs_project, base_project)
1367
1392
 
1368
- described_class.apply_change_to_project(base_project, changes_to_apply)
1393
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1369
1394
 
1370
1395
  expect(base_project).to be_equivalent_to_project(theirs_project)
1371
1396
  end
@@ -1377,7 +1402,7 @@ describe Kintsugi, :apply_change_to_project do
1377
1402
 
1378
1403
  changes_to_apply = get_diff(theirs_project, base_project)
1379
1404
 
1380
- described_class.apply_change_to_project(base_project, changes_to_apply)
1405
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1381
1406
 
1382
1407
  expect(base_project).to be_equivalent_to_project(theirs_project)
1383
1408
  end
@@ -1388,7 +1413,7 @@ describe Kintsugi, :apply_change_to_project do
1388
1413
 
1389
1414
  changes_to_apply = get_diff(theirs_project, base_project)
1390
1415
 
1391
- described_class.apply_change_to_project(base_project, changes_to_apply)
1416
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1392
1417
 
1393
1418
  expect(base_project).to be_equivalent_to_project(theirs_project)
1394
1419
  end
@@ -1401,7 +1426,7 @@ describe Kintsugi, :apply_change_to_project do
1401
1426
 
1402
1427
  changes_to_apply = get_diff(theirs_project, base_project)
1403
1428
 
1404
- described_class.apply_change_to_project(base_project, changes_to_apply)
1429
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1405
1430
 
1406
1431
  expect(base_project).to be_equivalent_to_project(theirs_project)
1407
1432
  end
@@ -1416,7 +1441,7 @@ describe Kintsugi, :apply_change_to_project do
1416
1441
 
1417
1442
  changes_to_apply = get_diff(theirs_project, base_project)
1418
1443
 
1419
- described_class.apply_change_to_project(base_project, changes_to_apply)
1444
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1420
1445
 
1421
1446
  expect(base_project).to be_equivalent_to_project(theirs_project)
1422
1447
  end
@@ -1431,7 +1456,7 @@ describe Kintsugi, :apply_change_to_project do
1431
1456
 
1432
1457
  changes_to_apply = get_diff(theirs_project, base_project)
1433
1458
 
1434
- described_class.apply_change_to_project(base_project, changes_to_apply)
1459
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1435
1460
 
1436
1461
  expect(base_project).to be_equivalent_to_project(theirs_project)
1437
1462
  end
@@ -1446,7 +1471,7 @@ describe Kintsugi, :apply_change_to_project do
1446
1471
 
1447
1472
  changes_to_apply = get_diff(theirs_project, base_project)
1448
1473
 
1449
- described_class.apply_change_to_project(base_project, changes_to_apply)
1474
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1450
1475
 
1451
1476
  expect(base_project).to be_equivalent_to_project(theirs_project)
1452
1477
  end
@@ -1464,7 +1489,7 @@ describe Kintsugi, :apply_change_to_project do
1464
1489
 
1465
1490
  changes_to_apply = get_diff(theirs_project, base_project)
1466
1491
 
1467
- described_class.apply_change_to_project(ours_project, changes_to_apply)
1492
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
1468
1493
 
1469
1494
  expect(ours_project).to be_equivalent_to_project(theirs_project)
1470
1495
  end
@@ -1481,7 +1506,7 @@ describe Kintsugi, :apply_change_to_project do
1481
1506
 
1482
1507
  changes_to_apply = get_diff(theirs_project, base_project)
1483
1508
 
1484
- described_class.apply_change_to_project(ours_project, changes_to_apply)
1509
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
1485
1510
 
1486
1511
  expect(ours_project).to be_equivalent_to_project(theirs_project)
1487
1512
  end
@@ -1508,7 +1533,7 @@ describe Kintsugi, :apply_change_to_project do
1508
1533
 
1509
1534
  changes_to_apply = get_diff(ours_project, theirs_project)
1510
1535
 
1511
- described_class.apply_change_to_project(base_project, changes_to_apply)
1536
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1512
1537
 
1513
1538
  expect(base_project).to be_equivalent_to_project(ours_project, ignore_keys: ["containerPortal"])
1514
1539
  end
@@ -1527,7 +1552,7 @@ describe Kintsugi, :apply_change_to_project do
1527
1552
 
1528
1553
  changes_to_apply = get_diff(theirs_project, base_project)
1529
1554
 
1530
- described_class.apply_change_to_project(base_project, changes_to_apply)
1555
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1531
1556
 
1532
1557
  expect(base_project).to be_equivalent_to_project(theirs_project)
1533
1558
  end
@@ -1542,7 +1567,7 @@ describe Kintsugi, :apply_change_to_project do
1542
1567
 
1543
1568
  changes_to_apply = get_diff(theirs_project, base_project)
1544
1569
 
1545
- described_class.apply_change_to_project(base_project, changes_to_apply)
1570
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1546
1571
  expect(base_project).to be_equivalent_to_project(theirs_project)
1547
1572
  end
1548
1573
 
@@ -1552,7 +1577,7 @@ describe Kintsugi, :apply_change_to_project do
1552
1577
 
1553
1578
  changes_to_apply = get_diff(theirs_project, base_project)
1554
1579
 
1555
- described_class.apply_change_to_project(base_project, changes_to_apply)
1580
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1556
1581
  expect(base_project).to be_equivalent_to_project(theirs_project)
1557
1582
  end
1558
1583
 
@@ -1568,7 +1593,7 @@ describe Kintsugi, :apply_change_to_project do
1568
1593
 
1569
1594
  changes_to_apply = get_diff(theirs_project, base_project)
1570
1595
 
1571
- described_class.apply_change_to_project(base_project, changes_to_apply)
1596
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1572
1597
 
1573
1598
  expect(base_project).to be_equivalent_to_project(theirs_project)
1574
1599
  end
@@ -1586,7 +1611,7 @@ describe Kintsugi, :apply_change_to_project do
1586
1611
 
1587
1612
  changes_to_apply = get_diff(theirs_project, base_project)
1588
1613
 
1589
- described_class.apply_change_to_project(base_project, changes_to_apply)
1614
+ described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)
1590
1615
 
1591
1616
  expect(base_project).to be_equivalent_to_project(theirs_project)
1592
1617
  end
@@ -1601,7 +1626,7 @@ describe Kintsugi, :apply_change_to_project do
1601
1626
 
1602
1627
  changes_to_apply = get_diff(theirs_project, base_project)
1603
1628
  other_project = create_copy_of_project(base_project.path, "theirs")
1604
- described_class.apply_change_to_project(other_project, changes_to_apply)
1629
+ described_class.apply_change_to_project(other_project, changes_to_apply, theirs_project)
1605
1630
 
1606
1631
  expect(other_project).to be_equivalent_to_project(base_project)
1607
1632
  end
@@ -1615,7 +1640,7 @@ describe Kintsugi, :apply_change_to_project do
1615
1640
 
1616
1641
  changes_to_apply = get_diff(theirs_project, base_project)
1617
1642
  other_project = create_copy_of_project(base_project.path, "theirs")
1618
- described_class.apply_change_to_project(other_project, changes_to_apply)
1643
+ described_class.apply_change_to_project(other_project, changes_to_apply, theirs_project)
1619
1644
 
1620
1645
  expect(other_project).to be_equivalent_to_project(base_project)
1621
1646
  end
@@ -1629,7 +1654,7 @@ describe Kintsugi, :apply_change_to_project do
1629
1654
 
1630
1655
  changes_to_apply = get_diff(theirs_project, base_project)
1631
1656
  other_project = create_copy_of_project(base_project.path, "theirs")
1632
- described_class.apply_change_to_project(other_project, changes_to_apply)
1657
+ described_class.apply_change_to_project(other_project, changes_to_apply, theirs_project)
1633
1658
 
1634
1659
  expect(other_project).to be_equivalent_to_project(base_project)
1635
1660
  end
@@ -1644,7 +1669,7 @@ describe Kintsugi, :apply_change_to_project do
1644
1669
 
1645
1670
  changes_to_apply = get_diff(theirs_project, base_project)
1646
1671
 
1647
- described_class.apply_change_to_project(ours_project, changes_to_apply)
1672
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
1648
1673
 
1649
1674
  expect(ours_project.root_object.project_references.count).to equal(1)
1650
1675
  end
@@ -1661,7 +1686,7 @@ describe Kintsugi, :apply_change_to_project do
1661
1686
 
1662
1687
  changes_to_apply = get_diff(theirs_project, base_project)
1663
1688
  other_project = create_copy_of_project(base_project.path, "theirs")
1664
- described_class.apply_change_to_project(other_project, changes_to_apply)
1689
+ described_class.apply_change_to_project(other_project, changes_to_apply, theirs_project)
1665
1690
 
1666
1691
  expect(other_project).to be_equivalent_to_project(base_project)
1667
1692
  end
@@ -1682,7 +1707,7 @@ describe Kintsugi, :apply_change_to_project do
1682
1707
  changes_to_apply = get_diff(theirs_project, base_project)
1683
1708
 
1684
1709
  other_project = create_copy_of_project(base_project.path, "theirs")
1685
- described_class.apply_change_to_project(other_project, changes_to_apply)
1710
+ described_class.apply_change_to_project(other_project, changes_to_apply, theirs_project)
1686
1711
 
1687
1712
  expect(other_project).to be_equivalent_to_project(base_project)
1688
1713
  end
@@ -1705,7 +1730,7 @@ describe Kintsugi, :apply_change_to_project do
1705
1730
 
1706
1731
  expected_project = create_copy_of_project(ours_project.path, "expected")
1707
1732
 
1708
- described_class.apply_change_to_project(ours_project, changes_to_apply)
1733
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
1709
1734
 
1710
1735
  expect(ours_project).to be_equivalent_to_project(expected_project)
1711
1736
  end
@@ -1730,7 +1755,7 @@ describe Kintsugi, :apply_change_to_project do
1730
1755
 
1731
1756
  changes_to_apply = get_diff(theirs_project, base_project)
1732
1757
 
1733
- described_class.apply_change_to_project(ours_project, changes_to_apply)
1758
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
1734
1759
 
1735
1760
  expect(ours_project.root_object.project_references[0][:project_ref].uuid)
1736
1761
  .not_to equal(ours_project.root_object.project_references[1][:project_ref].uuid)
@@ -1739,6 +1764,456 @@ describe Kintsugi, :apply_change_to_project do
1739
1764
  end
1740
1765
  end
1741
1766
 
1767
+ describe "resovling conflicts interactively" do
1768
+ let(:test_prompt) { TTY::Prompt::Test.new }
1769
+
1770
+ before do
1771
+ Kintsugi::Settings.interactive_resolution = true
1772
+ allow(TTY::Prompt).to receive(:new).and_return(test_prompt)
1773
+ test_prompt.setup
1774
+ end
1775
+
1776
+ after do
1777
+ Kintsugi::Settings.interactive_resolution = false
1778
+ end
1779
+
1780
+ describe "adding group to a non existent group" do
1781
+ it "creates the non existent group" do
1782
+ test_prompt.choose_option(0)
1783
+
1784
+ base_project.main_group.find_subpath("new_group", true)
1785
+ base_project.save
1786
+
1787
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1788
+ theirs_project["new_group"].find_subpath("sub_group", true)
1789
+
1790
+ changes_to_apply = get_diff(theirs_project, base_project)
1791
+
1792
+ ours_project = create_copy_of_project(base_project.path, "ours")
1793
+ ours_project.main_group.find_subpath("new_group").remove_from_project
1794
+
1795
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
1796
+ expect(ours_project).to be_equivalent_to_project(theirs_project)
1797
+ end
1798
+
1799
+ it "ignores adding the group" do
1800
+ test_prompt.choose_option(1)
1801
+
1802
+ base_project.main_group.find_subpath("new_group", true)
1803
+ base_project.save
1804
+
1805
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1806
+ theirs_project["new_group"].find_subpath("sub_group", true)
1807
+
1808
+ changes_to_apply = get_diff(theirs_project, base_project)
1809
+
1810
+ ours_project = create_copy_of_project(base_project.path, "ours")
1811
+ ours_project.main_group.find_subpath("new_group").remove_from_project
1812
+ ours_project.save
1813
+ expected_project = create_copy_of_project(ours_project.path, "expected")
1814
+
1815
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
1816
+ expect(ours_project).to be_equivalent_to_project(expected_project)
1817
+ end
1818
+ end
1819
+
1820
+ describe "adding file to a non existent group" do
1821
+ it "creates the non existent group" do
1822
+ test_prompt.choose_option(0)
1823
+
1824
+ base_project.main_group.find_subpath("new_group", true)
1825
+ base_project.save
1826
+
1827
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1828
+ theirs_project["new_group"].new_reference("foo/bar")
1829
+
1830
+ changes_to_apply = get_diff(theirs_project, base_project)
1831
+
1832
+ ours_project = create_copy_of_project(base_project.path, "ours")
1833
+ ours_project.main_group.find_subpath("new_group").remove_from_project
1834
+
1835
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
1836
+ expect(ours_project).to be_equivalent_to_project(theirs_project)
1837
+ end
1838
+
1839
+ it "ignores adding the file" do
1840
+ test_prompt.choose_option(1)
1841
+
1842
+ base_project.main_group.find_subpath("new_group", true)
1843
+ base_project.save
1844
+
1845
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1846
+ theirs_project["new_group"].new_reference("foo/bar")
1847
+
1848
+ changes_to_apply = get_diff(theirs_project, base_project)
1849
+
1850
+ ours_project = create_copy_of_project(base_project.path, "ours")
1851
+ ours_project.main_group.find_subpath("new_group").remove_from_project
1852
+ ours_project.save
1853
+ expected_project = create_copy_of_project(ours_project.path, "expected")
1854
+
1855
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
1856
+ expect(ours_project).to be_equivalent_to_project(expected_project)
1857
+ end
1858
+ end
1859
+
1860
+ describe "changing a group that was already removed" do
1861
+ it "creates the group and applies changes to it" do
1862
+ test_prompt.choose_option(0)
1863
+
1864
+ base_project.main_group.find_subpath("some_group", true)
1865
+ base_project.save
1866
+
1867
+ ours_project = create_copy_of_project(base_project.path, "ours")
1868
+ ours_project.main_group.find_subpath("some_group").remove_from_project
1869
+
1870
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1871
+ theirs_project.main_group.find_subpath("some_group").source_tree = "SDKROOT"
1872
+
1873
+ changes_to_apply = get_diff(theirs_project, base_project)
1874
+
1875
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
1876
+
1877
+ expect(ours_project).to be_equivalent_to_project(theirs_project)
1878
+ end
1879
+
1880
+ it "ignores changes to group" do
1881
+ test_prompt.choose_option(1)
1882
+
1883
+ base_project.main_group.find_subpath("some_group", true)
1884
+ base_project.save
1885
+
1886
+ ours_project = create_copy_of_project(base_project.path, "ours")
1887
+ ours_project.main_group.find_subpath("some_group").remove_from_project
1888
+
1889
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1890
+ theirs_project.main_group.find_subpath("some_group").source_tree = "SDKROOT"
1891
+
1892
+ changes_to_apply = get_diff(theirs_project, base_project)
1893
+
1894
+ ours_project.save
1895
+ expected_project = create_copy_of_project(ours_project.path, "expected")
1896
+
1897
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
1898
+
1899
+ expect(ours_project).to be_equivalent_to_project(expected_project)
1900
+ end
1901
+ end
1902
+
1903
+ describe "changing a component that was already removed" do
1904
+ it "creates the component and applies changes to it" do
1905
+ test_prompt.choose_option(0)
1906
+
1907
+ base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
1908
+ base_project.save
1909
+
1910
+ ours_project = create_copy_of_project(base_project.path, "ours")
1911
+ ours_project.targets[0].product_reference.remove_from_project
1912
+
1913
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1914
+ theirs_project.targets[0].product_reference.source_tree = "SDKROOT"
1915
+
1916
+ changes_to_apply = get_diff(theirs_project, base_project)
1917
+
1918
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
1919
+
1920
+ expect(ours_project).to be_equivalent_to_project(theirs_project)
1921
+ end
1922
+
1923
+ it "ignores changes to component" do
1924
+ test_prompt.choose_option(1)
1925
+
1926
+ base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
1927
+ base_project.save
1928
+
1929
+ ours_project = create_copy_of_project(base_project.path, "ours")
1930
+ ours_project.targets[0].product_reference.remove_from_project
1931
+
1932
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1933
+ theirs_project.targets[0].product_reference.source_tree = "SDKROOT"
1934
+
1935
+ changes_to_apply = get_diff(theirs_project, base_project)
1936
+
1937
+ ours_project.save
1938
+ expected_project = create_copy_of_project(ours_project.path, "expected")
1939
+
1940
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
1941
+
1942
+ expect(ours_project).to be_equivalent_to_project(expected_project)
1943
+ end
1944
+ end
1945
+
1946
+ describe "changing a file reference that has a build file and both were already removed" do
1947
+ it "creates the component and its build file and applies changes to it" do
1948
+ test_prompt.choose_option(0)
1949
+
1950
+ file_reference_name = "bar"
1951
+
1952
+ file_reference = base_project.main_group.new_reference(file_reference_name)
1953
+ target = base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
1954
+ target.source_build_phase.add_file_reference(file_reference)
1955
+ base_project.save
1956
+
1957
+ ours_project = create_copy_of_project(base_project.path, "ours")
1958
+ build_file = ours_project.targets[0].source_build_phase.files[-1]
1959
+ # Removing the build file first is done because prior to xcodeproj 1.22, the build file was
1960
+ # not removed when its file reference was removed.
1961
+ build_file.remove_from_project
1962
+ ours_project.main_group.find_subpath(file_reference_name).remove_from_project
1963
+
1964
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1965
+ theirs_project.main_group.find_subpath(file_reference_name).source_tree = "SDKROOT"
1966
+
1967
+ changes_to_apply = get_diff(theirs_project, base_project)
1968
+
1969
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
1970
+
1971
+ expect(ours_project).to be_equivalent_to_project(theirs_project)
1972
+ end
1973
+
1974
+ it "ignores changes to component and to its build file" do
1975
+ test_prompt.choose_option(1)
1976
+
1977
+ file_reference_name = "bar"
1978
+
1979
+ file_reference = base_project.main_group.new_reference(file_reference_name)
1980
+ target = base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
1981
+ target.source_build_phase.add_file_reference(file_reference)
1982
+ base_project.save
1983
+
1984
+ ours_project = create_copy_of_project(base_project.path, "ours")
1985
+ ours_project.main_group.find_subpath(file_reference_name).remove_from_project
1986
+
1987
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1988
+ theirs_project.main_group.find_subpath(file_reference_name).source_tree = "SDKROOT"
1989
+
1990
+ changes_to_apply = get_diff(theirs_project, base_project)
1991
+
1992
+ ours_project.save
1993
+ expected_project = create_copy_of_project(ours_project.path, "expected")
1994
+
1995
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
1996
+
1997
+ expect(ours_project).to be_equivalent_to_project(expected_project)
1998
+ end
1999
+ end
2000
+
2001
+ describe "adding entry to a hash that has another value for the same key" do
2002
+ it "overrides values from new hash" do
2003
+ # There will be two conflicts, one for each configuration.
2004
+ test_prompt.choose_option(0, repeating: 2)
2005
+
2006
+ base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
2007
+ base_project.targets[0].build_configurations.each do |configuration|
2008
+ configuration.build_settings = nil
2009
+ end
2010
+ base_project.save
2011
+
2012
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
2013
+ theirs_project.targets[0].build_configurations.each do |configuration|
2014
+ configuration.build_settings = {"HEADER_SEARCH_PATHS" => "bar"}
2015
+ end
2016
+
2017
+ ours_project = create_copy_of_project(base_project.path, "ours")
2018
+ ours_project.targets[0].build_configurations.each do |configuration|
2019
+ configuration.build_settings = {"HEADER_SEARCH_PATHS" => "baz"}
2020
+ end
2021
+
2022
+ changes_to_apply = get_diff(theirs_project, base_project)
2023
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
2024
+
2025
+ expect(ours_project).to be_equivalent_to_project(theirs_project)
2026
+ end
2027
+
2028
+ it "keeps values from old hash" do
2029
+ # There will be two conflicts, one for each configuration.
2030
+ test_prompt.choose_option(1, repeating: 2)
2031
+
2032
+ base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
2033
+ base_project.targets[0].build_configurations.each do |configuration|
2034
+ configuration.build_settings = nil
2035
+ end
2036
+ base_project.save
2037
+
2038
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
2039
+ theirs_project.targets[0].build_configurations.each do |configuration|
2040
+ configuration.build_settings = {"HEADER_SEARCH_PATHS" => "bar"}
2041
+ end
2042
+
2043
+ ours_project = create_copy_of_project(base_project.path, "ours")
2044
+ ours_project.targets[0].build_configurations.each do |configuration|
2045
+ configuration.build_settings = {"HEADER_SEARCH_PATHS" => "baz"}
2046
+ end
2047
+ ours_project.save
2048
+ expected_project = create_copy_of_project(ours_project.path, "expected")
2049
+
2050
+ changes_to_apply = get_diff(theirs_project, base_project)
2051
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
2052
+
2053
+ expect(ours_project).to be_equivalent_to_project(expected_project)
2054
+ end
2055
+ end
2056
+
2057
+ describe "trying to remove entry from a hash that has another value for the same key" do
2058
+ it "removes the key" do
2059
+ # There will be two conflicts, one for each configuration.
2060
+ test_prompt.choose_option(0, repeating: 2)
2061
+
2062
+ base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
2063
+ base_project.targets[0].build_configurations.each do |configuration|
2064
+ configuration.build_settings = {"HEADER_SEARCH_PATHS" => "bar"}
2065
+ end
2066
+ base_project.save
2067
+
2068
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
2069
+ theirs_project.targets[0].build_configurations.each do |configuration|
2070
+ configuration.build_settings = nil
2071
+ end
2072
+
2073
+ ours_project = create_copy_of_project(base_project.path, "ours")
2074
+ ours_project.targets[0].build_configurations.each do |configuration|
2075
+ configuration.build_settings = {"HEADER_SEARCH_PATHS" => "baz"}
2076
+ end
2077
+
2078
+ changes_to_apply = get_diff(theirs_project, base_project)
2079
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
2080
+
2081
+ expected_project = create_copy_of_project(base_project.path, "expected")
2082
+ expected_project.targets[0].build_configurations.each do |configuration|
2083
+ configuration.build_settings = {}
2084
+ end
2085
+ expect(ours_project).to be_equivalent_to_project(expected_project)
2086
+ end
2087
+
2088
+ it "keeps the key" do
2089
+ # There will be two conflicts, one for each configuration.
2090
+ test_prompt.choose_option(1, repeating: 2)
2091
+
2092
+ base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
2093
+ base_project.targets[0].build_configurations.each do |configuration|
2094
+ configuration.build_settings = {"HEADER_SEARCH_PATHS" => "bar"}
2095
+ end
2096
+ base_project.save
2097
+
2098
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
2099
+ theirs_project.targets[0].build_configurations.each do |configuration|
2100
+ configuration.build_settings = nil
2101
+ end
2102
+
2103
+ ours_project = create_copy_of_project(base_project.path, "ours")
2104
+ ours_project.targets[0].build_configurations.each do |configuration|
2105
+ configuration.build_settings = {"HEADER_SEARCH_PATHS" => "baz"}
2106
+ end
2107
+ ours_project.save
2108
+ expected_project = create_copy_of_project(ours_project.path, "expected")
2109
+
2110
+ changes_to_apply = get_diff(theirs_project, base_project)
2111
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
2112
+
2113
+ expect(ours_project).to be_equivalent_to_project(expected_project)
2114
+ end
2115
+ end
2116
+
2117
+ describe "trying to change string value that has another existing value" do
2118
+ it "replaces the string with the new value" do
2119
+ # There will be two conflicts, one for each configuration.
2120
+ test_prompt.choose_option(0, repeating: 2)
2121
+
2122
+ base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
2123
+ base_project.targets[0].build_configurations.each do |configuration|
2124
+ configuration.build_settings["PRODUCT_NAME"] = "old"
2125
+ end
2126
+ base_project.save
2127
+
2128
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
2129
+ theirs_project.targets[0].build_configurations.each do |configuration|
2130
+ configuration.build_settings["PRODUCT_NAME"] = "new"
2131
+ end
2132
+
2133
+ ours_project = create_copy_of_project(base_project.path, "ours")
2134
+ ours_project.targets[0].build_configurations.each do |configuration|
2135
+ configuration.build_settings["PRODUCT_NAME"] = "existing"
2136
+ end
2137
+
2138
+ changes_to_apply = get_diff(theirs_project, base_project)
2139
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
2140
+
2141
+ expect(ours_project).to be_equivalent_to_project(theirs_project)
2142
+ end
2143
+
2144
+ it "keeps the existing value" do
2145
+ # There will be two conflicts, one for each configuration.
2146
+ test_prompt.choose_option(1, repeating: 2)
2147
+
2148
+ base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
2149
+ base_project.targets[0].build_configurations.each do |configuration|
2150
+ configuration.build_settings["PRODUCT_NAME"] = "old"
2151
+ end
2152
+ base_project.save
2153
+
2154
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
2155
+ theirs_project.targets[0].build_configurations.each do |configuration|
2156
+ configuration.build_settings["PRODUCT_NAME"] = "new"
2157
+ end
2158
+
2159
+ ours_project = create_copy_of_project(base_project.path, "ours")
2160
+ ours_project.targets[0].build_configurations.each do |configuration|
2161
+ configuration.build_settings["PRODUCT_NAME"] = "existing"
2162
+ end
2163
+ ours_project.save
2164
+ expected_project = create_copy_of_project(ours_project.path, "expected")
2165
+
2166
+ changes_to_apply = get_diff(theirs_project, base_project)
2167
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
2168
+
2169
+ expect(ours_project).to be_equivalent_to_project(expected_project)
2170
+ end
2171
+ end
2172
+
2173
+ describe "trying to remove a component with different attributes" do
2174
+ it "removes the component anyway" do
2175
+ test_prompt.choose_option(0)
2176
+
2177
+ base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
2178
+ base_project.targets[0].new_shell_script_build_phase("bar")
2179
+ base_project.save
2180
+
2181
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
2182
+ theirs_project.targets[0].shell_script_build_phases[0].remove_from_project
2183
+
2184
+ ours_project = create_copy_of_project(base_project.path, "ours")
2185
+ ours_project.targets[0].shell_script_build_phases[0].shell_script = "foo"
2186
+
2187
+ changes_to_apply = get_diff(theirs_project, base_project)
2188
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
2189
+
2190
+ expect(ours_project).to be_equivalent_to_project(theirs_project)
2191
+ end
2192
+
2193
+ it "keeps the component" do
2194
+ test_prompt.choose_option(1)
2195
+
2196
+ base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
2197
+ base_project.targets[0].new_shell_script_build_phase("bar")
2198
+ base_project.save
2199
+
2200
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
2201
+ theirs_project.targets[0].shell_script_build_phases[0].remove_from_project
2202
+
2203
+ ours_project = create_copy_of_project(base_project.path, "ours")
2204
+ ours_project.targets[0].shell_script_build_phases[0].shell_script = "foo"
2205
+
2206
+ ours_project.save
2207
+ expected_project = create_copy_of_project(ours_project.path, "expected")
2208
+
2209
+ changes_to_apply = get_diff(theirs_project, base_project)
2210
+ described_class.apply_change_to_project(ours_project, changes_to_apply, theirs_project)
2211
+
2212
+ expect(ours_project).to be_equivalent_to_project(expected_project)
2213
+ end
2214
+ end
2215
+ end
2216
+
1742
2217
  def create_copy_of_project(project_path, new_project_prefix)
1743
2218
  copied_project_path = make_temp_directory(new_project_prefix, ".xcodeproj")
1744
2219
  FileUtils.cp(File.join(project_path, "project.pbxproj"), copied_project_path)
@@ -1829,3 +2304,20 @@ describe Kintsugi, :apply_change_to_project do
1829
2304
  directory_path
1830
2305
  end
1831
2306
  end
2307
+
2308
+ module TTY
2309
+ class Prompt
2310
+ class Test
2311
+ def choose_option(index, repeating: 1)
2312
+ input << "#{"j" * index}\n" * repeating
2313
+ input.rewind
2314
+ end
2315
+
2316
+ def setup
2317
+ on(:keypress) do |event|
2318
+ trigger(:keydown) if event.value == "j"
2319
+ end
2320
+ end
2321
+ end
2322
+ end
2323
+ end