kintsugi 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e7dbc48bf6850280ee25c8f9d9f9af95353b2f036113234706ebc803721fafb0
4
- data.tar.gz: '085d2b5e75db3ba38c6374d21634d403b406a00e06d49e4e26fefd82a85564d1'
3
+ metadata.gz: 02b50bf2480ea4dd03996c8fe12c02f2eeae95f6e69fa782176c695637d28f9b
4
+ data.tar.gz: 5b8f806cd4a168c245f1d9e7e764d4dfe509ccd61d0ad653596ef929b98e5ac9
5
5
  SHA512:
6
- metadata.gz: b4f45ab1c32a1932e36568e1ee7826c617681d74ac7dacf363eb0926ad05b2eb51b35e83fafef6d5bedbfa43a357f640adaa833c35b33e28fd41055f12e45d9a
7
- data.tar.gz: f3fae674c676ae59d21cc948ba4474a48fe87a2ce82ac0e73e74e0e273bf7a2574bc1149b6addeb3a368a0dbb00c9b70ac6ac0d81570645e1af1af2f7f7a4718
6
+ metadata.gz: 011b04ec2f4f6f32892436c21f0b0d17c8ea9ee7ab043324febbf1f56df32e65ff8176d4b205dc9541ccb1f7953d70be3085bca8ff79e56d3d06fecdcf8ece34
7
+ data.tar.gz: 6f923e940ad52cc62b25898f387cc7dd97fd47d93c152363c86c7e5edeedcbf02a15a405d1b5caf1e4234ed54086d0c8bf890e646ef940a1205579782b94e95a
@@ -19,6 +19,14 @@ jobs:
19
19
  ruby-version: 2.5.8
20
20
  rubygems: latest
21
21
 
22
+ - name: Draft a new release
23
+ run: |
24
+ echo ${{ secrets.GITHUB_TOKEN }} | gh auth login --with-token
25
+ version="v$(grep STRING lib/kintsugi/version.rb | cut -d \" -f 2)"
26
+ git tag $version
27
+ git push --tag
28
+ gh release create $version --generate-notes
29
+
22
30
  - name: Publish to rubygems.org
23
31
  run: |
24
32
  gem build *.gemspec
@@ -19,6 +19,7 @@ jobs:
19
19
  uses: ruby/setup-ruby@v1
20
20
  with:
21
21
  ruby-version: 2.5.8
22
+ rubygems: latest
22
23
  bundler-cache: true
23
24
 
24
25
  - name: Run Rake
data/.rubocop.yml CHANGED
@@ -12,6 +12,9 @@ RSpec/MultipleExpectations:
12
12
  AllCops:
13
13
  DisplayCopNames: true
14
14
  TargetRubyVersion: 2.5
15
+ Exclude:
16
+ - 'lib/**/xcodeproj_extensions.rb'
17
+ - 'vendor/bundle/**/*'
15
18
  NewCops: enable
16
19
 
17
20
  Metrics/BlockLength:
data/bin/kintsugi CHANGED
@@ -5,37 +5,9 @@
5
5
  # Created by Ben Yohay.
6
6
 
7
7
  require "kintsugi"
8
- require_relative "../lib/kintsugi/cli"
9
- require_relative "../lib/kintsugi/error"
10
-
11
- def parse_options!(command, argv)
12
- options = {}
13
- command.option_parser.parse!(argv, into: options)
14
- options
15
- end
16
-
17
- def name_of_subcommand?(subcommands, argument)
18
- subcommands.include?(argument)
19
- end
20
-
21
- first_argument = ARGV[0]
22
- cli = Kintsugi::CLI.new
23
- command =
24
- if name_of_subcommand?(cli.subcommands, first_argument)
25
- ARGV.shift
26
- cli.subcommands[first_argument]
27
- else
28
- cli.root_command
29
- end
30
-
31
- options = parse_options!(command, ARGV)
32
8
 
33
9
  begin
34
- command.action.call(options, ARGV)
35
- rescue ArgumentError => e
36
- puts "#{e.class}: #{e}"
37
- exit(1)
38
- rescue Kintsugi::MergeError => e
39
- puts e
10
+ Kintsugi.run(ARGV)
11
+ rescue ArgumentError, Kintsugi::MergeError
40
12
  exit(1)
41
13
  end
data/kintsugi.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_dependency "xcodeproj", ">= 1.19.0", "<= 1.21.0"
26
26
 
27
+ spec.add_development_dependency "git", "~> 1.11"
27
28
  spec.add_development_dependency "rake", "~> 13.0"
28
29
  spec.add_development_dependency "rspec", "~> 3.9"
29
30
  spec.add_development_dependency "rubocop", "1.12.0"
@@ -29,26 +29,28 @@ module Kintsugi
29
29
  puts "Warning: Main group doesn't exist, ignoring changes to it."
30
30
  else
31
31
  apply_change_to_component(project.root_object, "mainGroup",
32
- change["rootObject"]["mainGroup"])
32
+ change["rootObject"]["mainGroup"], "rootObject")
33
33
  end
34
34
  end
35
35
 
36
36
  unless change["rootObject"]["projectReferences"].nil?
37
37
  apply_change_to_component(project.root_object, "projectReferences",
38
- change["rootObject"]["projectReferences"])
38
+ change["rootObject"]["projectReferences"], "rootObject")
39
39
  end
40
40
 
41
41
  apply_change_to_component(project, "rootObject",
42
42
  change["rootObject"].reject { |key|
43
43
  %w[mainGroup projectReferences].include?(key)
44
- })
44
+ }, "")
45
45
  end
46
46
 
47
47
  private
48
48
 
49
- def apply_change_to_component(parent_component, change_name, change)
49
+ def apply_change_to_component(parent_component, change_name, change, parent_change_path)
50
50
  return if change_name == "displayName"
51
51
 
52
+ change_path = parent_change_path.empty? ? change_name : "#{parent_change_path}/#{change_name}"
53
+
52
54
  attribute_name = attribute_name_from_change_name(change_name)
53
55
  if simple_attribute?(parent_component, attribute_name)
54
56
  apply_change_to_simple_attribute(parent_component, attribute_name, change)
@@ -62,7 +64,7 @@ module Kintsugi
62
64
  component = child_component(parent_component, change_name)
63
65
 
64
66
  if component.nil?
65
- add_missing_component_if_valid(parent_component, change_name, change)
67
+ add_missing_component_if_valid(parent_component, change_name, change, change_path)
66
68
  return
67
69
  end
68
70
  end
@@ -76,11 +78,12 @@ module Kintsugi
76
78
 
77
79
  (change[:added] || []).each do |added_change|
78
80
  is_object_list = component.is_a?(Xcodeproj::Project::ObjectList)
79
- add_child_to_component(is_object_list ? parent_component : component, added_change)
81
+ add_child_to_component(is_object_list ? parent_component : component, added_change,
82
+ change_path)
80
83
  end
81
84
 
82
85
  subchanges_of_change(change).each do |subchange_name, subchange|
83
- apply_change_to_component(component, subchange_name, subchange)
86
+ apply_change_to_component(component, subchange_name, subchange, change_path)
84
87
  end
85
88
  end
86
89
 
@@ -100,9 +103,9 @@ module Kintsugi
100
103
  end
101
104
  end
102
105
 
103
- def add_missing_component_if_valid(parent_component, change_name, change)
106
+ def add_missing_component_if_valid(parent_component, change_name, change, change_path)
104
107
  if change[:added] && change.compact.count == 1
105
- add_child_to_component(parent_component, change[:added])
108
+ add_child_to_component(parent_component, change[:added], change_path)
106
109
  return
107
110
  end
108
111
 
@@ -112,10 +115,7 @@ module Kintsugi
112
115
 
113
116
  def replace_component_with_new_type(parent_component, name_in_parent_component, change)
114
117
  old_component = parent_component.send(name_in_parent_component)
115
-
116
- new_component = parent_component.project.new(
117
- Module.const_get("Xcodeproj::Project::#{change["isa"][:added]}")
118
- )
118
+ new_component = component_of_new_type(parent_component, change, old_component)
119
119
 
120
120
  copy_attributes_to_new_component(old_component, new_component)
121
121
 
@@ -123,6 +123,27 @@ module Kintsugi
123
123
  new_component
124
124
  end
125
125
 
126
+ def component_of_new_type(parent_component, change, old_component)
127
+ if change["isa"][:added] == "PBXFileReference"
128
+ path = (change["path"] && change["path"][:added]) || old_component.path
129
+ case parent_component
130
+ when Xcodeproj::Project::XCBuildConfiguration
131
+ parent_component.base_configuration_reference = find_file(parent_component.project, path)
132
+ return parent_component.base_configuration_reference
133
+ when Xcodeproj::Project::PBXNativeTarget
134
+ parent_component.product_reference = find_file(parent_component.project, path)
135
+ return parent_component.product_reference
136
+ when Xcodeproj::Project::PBXBuildFile
137
+ parent_component.file_ref = find_file(parent_component.project, path)
138
+ return parent_component.file_ref
139
+ end
140
+ end
141
+
142
+ parent_component.project.new(
143
+ Module.const_get("Xcodeproj::Project::#{change["isa"][:added]}")
144
+ )
145
+ end
146
+
126
147
  def copy_attributes_to_new_component(old_component, new_component)
127
148
  # The change won't describe the attributes that haven't changed, therefore the attributes
128
149
  # are copied to the new component.
@@ -298,63 +319,65 @@ module Kintsugi
298
319
  end
299
320
  end
300
321
 
301
- def add_child_to_component(component, change)
322
+ def add_child_to_component(component, change, component_change_path)
323
+ change_path = "#{component_change_path}/#{change["displayName"]}"
324
+
302
325
  if change["ProjectRef"] && change["ProductGroup"]
303
- add_subproject_reference(component, change)
326
+ add_subproject_reference(component, change, change_path)
304
327
  return
305
328
  end
306
329
 
307
330
  case change["isa"]
308
331
  when "PBXNativeTarget"
309
- add_target(component, change)
332
+ add_target(component, change, change_path)
310
333
  when "PBXAggregateTarget"
311
- add_aggregate_target(component, change)
334
+ add_aggregate_target(component, change, change_path)
312
335
  when "PBXFileReference"
313
- add_file_reference(component, change)
336
+ add_file_reference(component, change, change_path)
314
337
  when "PBXGroup"
315
- add_group(component, change)
338
+ add_group(component, change, change_path)
316
339
  when "PBXContainerItemProxy"
317
- add_container_item_proxy(component, change)
340
+ add_container_item_proxy(component, change, change_path)
318
341
  when "PBXTargetDependency"
319
- add_target_dependency(component, change)
342
+ add_target_dependency(component, change, change_path)
320
343
  when "PBXBuildFile"
321
- add_build_file(component, change)
344
+ add_build_file(component, change, change_path)
322
345
  when "XCConfigurationList"
323
- add_build_configuration_list(component, change)
346
+ add_build_configuration_list(component, change, change_path)
324
347
  when "XCBuildConfiguration"
325
- add_build_configuration(component, change)
348
+ add_build_configuration(component, change, change_path)
326
349
  when "PBXHeadersBuildPhase"
327
- add_headers_build_phase(component, change)
350
+ add_headers_build_phase(component, change, change_path)
328
351
  when "PBXSourcesBuildPhase"
329
- add_sources_build_phase(component, change)
352
+ add_sources_build_phase(component, change, change_path)
330
353
  when "PBXCopyFilesBuildPhase"
331
- add_copy_files_build_phase(component, change)
354
+ add_copy_files_build_phase(component, change, change_path)
332
355
  when "PBXShellScriptBuildPhase"
333
- add_shell_script_build_phase(component, change)
356
+ add_shell_script_build_phase(component, change, change_path)
334
357
  when "PBXFrameworksBuildPhase"
335
- add_frameworks_build_phase(component, change)
358
+ add_frameworks_build_phase(component, change, change_path)
336
359
  when "PBXResourcesBuildPhase"
337
- add_resources_build_phase(component, change)
360
+ add_resources_build_phase(component, change, change_path)
338
361
  when "PBXBuildRule"
339
- add_build_rule(component, change)
362
+ add_build_rule(component, change, change_path)
340
363
  when "PBXVariantGroup"
341
- add_variant_group(component, change)
364
+ add_variant_group(component, change, change_path)
342
365
  when "PBXReferenceProxy"
343
- add_reference_proxy(component, change)
366
+ add_reference_proxy(component, change, change_path)
344
367
  when "XCSwiftPackageProductDependency"
345
- add_swift_package_product_dependency(component, change)
368
+ add_swift_package_product_dependency(component, change, change_path)
346
369
  when "XCRemoteSwiftPackageReference"
347
- add_remote_swift_package_reference(component, change)
370
+ add_remote_swift_package_reference(component, change, change_path)
348
371
  else
349
372
  raise MergeError, "Trying to add unsupported component type #{change["isa"]}. Full " \
350
373
  "component change is: #{change}"
351
374
  end
352
375
  end
353
376
 
354
- def add_remote_swift_package_reference(containing_component, change)
377
+ def add_remote_swift_package_reference(containing_component, change, change_path)
355
378
  remote_swift_package_reference =
356
379
  containing_component.project.new(Xcodeproj::Project::XCRemoteSwiftPackageReference)
357
- add_attributes_to_component(remote_swift_package_reference, change)
380
+ add_attributes_to_component(remote_swift_package_reference, change, change_path)
358
381
 
359
382
  case containing_component
360
383
  when Xcodeproj::Project::XCSwiftPackageProductDependency
@@ -367,10 +390,10 @@ module Kintsugi
367
390
  end
368
391
  end
369
392
 
370
- def add_swift_package_product_dependency(containing_component, change)
393
+ def add_swift_package_product_dependency(containing_component, change, change_path)
371
394
  swift_package_product_dependency =
372
395
  containing_component.project.new(Xcodeproj::Project::XCSwiftPackageProductDependency)
373
- add_attributes_to_component(swift_package_product_dependency, change)
396
+ add_attributes_to_component(swift_package_product_dependency, change, change_path)
374
397
 
375
398
  case containing_component
376
399
  when Xcodeproj::Project::PBXBuildFile
@@ -383,7 +406,7 @@ module Kintsugi
383
406
  end
384
407
  end
385
408
 
386
- def add_reference_proxy(containing_component, change)
409
+ def add_reference_proxy(containing_component, change, change_path)
387
410
  case containing_component
388
411
  when Xcodeproj::Project::PBXBuildFile
389
412
  # If there are two file references that refer to the same file, one with a build file and
@@ -405,74 +428,78 @@ module Kintsugi
405
428
  when Xcodeproj::Project::PBXGroup
406
429
  reference_proxy = containing_component.project.new(Xcodeproj::Project::PBXReferenceProxy)
407
430
  containing_component << reference_proxy
408
- add_attributes_to_component(reference_proxy, change)
431
+ add_attributes_to_component(reference_proxy, change, change_path)
409
432
  else
410
433
  raise MergeError, "Trying to add reference proxy to an unsupported component type " \
411
434
  "#{containing_component.isa}. Change is: #{change}"
412
435
  end
413
436
  end
414
437
 
415
- def add_variant_group(containing_component, change)
438
+ def add_variant_group(containing_component, change, change_path)
416
439
  case containing_component
417
440
  when Xcodeproj::Project::PBXBuildFile
418
441
  containing_component.file_ref =
419
442
  find_variant_group(containing_component.project, change["displayName"])
420
443
  when Xcodeproj::Project::PBXGroup, Xcodeproj::Project::PBXVariantGroup
444
+ unless adding_files_and_groups_allowed?(change_path)
445
+ return
446
+ end
447
+
421
448
  variant_group = containing_component.project.new(Xcodeproj::Project::PBXVariantGroup)
422
449
  containing_component.children << variant_group
423
- add_attributes_to_component(variant_group, change)
450
+ add_attributes_to_component(variant_group, change, change_path)
424
451
  else
425
452
  raise MergeError, "Trying to add variant group to an unsupported component type " \
426
453
  "#{containing_component.isa}. Change is: #{change}"
427
454
  end
428
455
  end
429
456
 
430
- def add_build_rule(target, change)
457
+ def add_build_rule(target, change, change_path)
431
458
  build_rule = target.project.new(Xcodeproj::Project::PBXBuildRule)
432
459
  target.build_rules << build_rule
433
- add_attributes_to_component(build_rule, change)
460
+ add_attributes_to_component(build_rule, change, change_path)
434
461
  end
435
462
 
436
- def add_shell_script_build_phase(target, change)
463
+ def add_shell_script_build_phase(target, change, change_path)
437
464
  build_phase = target.new_shell_script_build_phase(change["displayName"])
438
- add_attributes_to_component(build_phase, change)
465
+ add_attributes_to_component(build_phase, change, change_path)
439
466
  end
440
467
 
441
- def add_headers_build_phase(target, change)
442
- add_attributes_to_component(target.headers_build_phase, change)
468
+ def add_headers_build_phase(target, change, change_path)
469
+ add_attributes_to_component(target.headers_build_phase, change, change_path)
443
470
  end
444
471
 
445
- def add_sources_build_phase(target, change)
446
- add_attributes_to_component(target.source_build_phase, change)
472
+ def add_sources_build_phase(target, change, change_path)
473
+ add_attributes_to_component(target.source_build_phase, change, change_path)
447
474
  end
448
475
 
449
- def add_frameworks_build_phase(target, change)
450
- add_attributes_to_component(target.frameworks_build_phase, change)
476
+ def add_frameworks_build_phase(target, change, change_path)
477
+ add_attributes_to_component(target.frameworks_build_phase, change, change_path)
451
478
  end
452
479
 
453
- def add_resources_build_phase(target, change)
454
- add_attributes_to_component(target.resources_build_phase, change)
480
+ def add_resources_build_phase(target, change, change_path)
481
+ add_attributes_to_component(target.resources_build_phase, change, change_path)
455
482
  end
456
483
 
457
- def add_copy_files_build_phase(target, change)
484
+ def add_copy_files_build_phase(target, change, change_path)
458
485
  copy_files_phase_name = change["displayName"] == "CopyFiles" ? nil : change["displayName"]
459
486
  copy_files_phase = target.new_copy_files_build_phase(copy_files_phase_name)
460
487
 
461
- add_attributes_to_component(copy_files_phase, change)
488
+ add_attributes_to_component(copy_files_phase, change, change_path)
462
489
  end
463
490
 
464
- def add_build_configuration_list(target, change)
491
+ def add_build_configuration_list(target, change, change_path)
465
492
  target.build_configuration_list = target.project.new(Xcodeproj::Project::XCConfigurationList)
466
- add_attributes_to_component(target.build_configuration_list, change)
493
+ add_attributes_to_component(target.build_configuration_list, change, change_path)
467
494
  end
468
495
 
469
- def add_build_configuration(configuration_list, change)
496
+ def add_build_configuration(configuration_list, change, change_path)
470
497
  build_configuration = configuration_list.project.new(Xcodeproj::Project::XCBuildConfiguration)
471
498
  configuration_list.build_configurations << build_configuration
472
- add_attributes_to_component(build_configuration, change)
499
+ add_attributes_to_component(build_configuration, change, change_path)
473
500
  end
474
501
 
475
- def add_build_file(build_phase, change)
502
+ def add_build_file(build_phase, change, change_path)
476
503
  if change["fileRef"].nil?
477
504
  puts "Warning: Trying to add a build file without any file reference to build phase " \
478
505
  "'#{build_phase}'"
@@ -481,7 +508,7 @@ module Kintsugi
481
508
 
482
509
  build_file = build_phase.project.new(Xcodeproj::Project::PBXBuildFile)
483
510
  build_phase.files << build_file
484
- add_attributes_to_component(build_file, change)
511
+ add_attributes_to_component(build_file, change, change_path)
485
512
  end
486
513
 
487
514
  def find_variant_group(project, display_name)
@@ -490,7 +517,7 @@ module Kintsugi
490
517
  end
491
518
  end
492
519
 
493
- def add_target_dependency(target, change)
520
+ def add_target_dependency(target, change, change_path)
494
521
  target_dependency = find_target(target.project, change["displayName"])
495
522
 
496
523
  if target_dependency
@@ -501,14 +528,14 @@ module Kintsugi
501
528
  target_dependency = target.project.new(Xcodeproj::Project::PBXTargetDependency)
502
529
 
503
530
  target.dependencies << target_dependency
504
- add_attributes_to_component(target_dependency, change)
531
+ add_attributes_to_component(target_dependency, change, change_path)
505
532
  end
506
533
 
507
534
  def find_target(project, display_name)
508
535
  project.targets.find { |target| target.display_name == display_name }
509
536
  end
510
537
 
511
- def add_container_item_proxy(component, change)
538
+ def add_container_item_proxy(component, change, change_path)
512
539
  container_proxy = component.project.new(Xcodeproj::Project::PBXContainerItemProxy)
513
540
  container_proxy.container_portal = find_containing_project_uuid(component.project, change)
514
541
 
@@ -521,7 +548,8 @@ module Kintsugi
521
548
  raise MergeError, "Trying to add container item proxy to an unsupported component type " \
522
549
  "#{containing_component.isa}. Change is: #{change}"
523
550
  end
524
- add_attributes_to_component(container_proxy, change, ignore_keys: ["containerPortal"])
551
+ add_attributes_to_component(container_proxy, change, change_path,
552
+ ignore_keys: ["containerPortal"])
525
553
  end
526
554
 
527
555
  def find_containing_project_uuid(project, container_item_proxy_change)
@@ -552,14 +580,14 @@ module Kintsugi
552
580
  container_item_proxies.first.container_portal
553
581
  end
554
582
 
555
- def add_subproject_reference(root_object, project_reference_change)
583
+ def add_subproject_reference(root_object, project_reference_change, change_path)
556
584
  filter_subproject_without_project_references = lambda do |file_reference|
557
585
  root_object.project_references.find do |project_reference|
558
586
  project_reference.project_ref.uuid == file_reference.uuid
559
587
  end.nil?
560
588
  end
561
589
  subproject_reference =
562
- find_file(root_object.project, project_reference_change["ProjectRef"],
590
+ find_file(root_object.project, project_reference_change["ProjectRef"]["path"],
563
591
  file_filter: filter_subproject_without_project_references)
564
592
 
565
593
  unless subproject_reference
@@ -578,7 +606,7 @@ module Kintsugi
578
606
  updated_project_reference_change =
579
607
  change_with_updated_subproject_uuid(project_reference_change, subproject_reference.uuid)
580
608
  add_attributes_to_component(project_reference, updated_project_reference_change,
581
- ignore_keys: ["ProjectRef"])
609
+ change_path, ignore_keys: ["ProjectRef"])
582
610
  end
583
611
 
584
612
  def change_with_updated_subproject_uuid(change, subproject_reference_uuid)
@@ -590,19 +618,19 @@ module Kintsugi
590
618
  new_change
591
619
  end
592
620
 
593
- def add_target(root_object, change)
621
+ def add_target(root_object, change, change_path)
594
622
  target = root_object.project.new(Xcodeproj::Project::PBXNativeTarget)
595
623
  root_object.project.targets << target
596
- add_attributes_to_component(target, change)
624
+ add_attributes_to_component(target, change, change_path)
597
625
  end
598
626
 
599
- def add_aggregate_target(root_object, change)
627
+ def add_aggregate_target(root_object, change, change_path)
600
628
  target = root_object.project.new(Xcodeproj::Project::PBXAggregateTarget)
601
629
  root_object.project.targets << target
602
- add_attributes_to_component(target, change)
630
+ add_attributes_to_component(target, change, change_path)
603
631
  end
604
632
 
605
- def add_file_reference(containing_component, change)
633
+ def add_file_reference(containing_component, change, change_path)
606
634
  # base configuration reference and product reference always reference a file that exists
607
635
  # inside a group, therefore in these cases the file is searched for.
608
636
  # In the case of group and variant group, the file can't exist in another group, therefore a
@@ -610,12 +638,17 @@ module Kintsugi
610
638
  case containing_component
611
639
  when Xcodeproj::Project::XCBuildConfiguration
612
640
  containing_component.base_configuration_reference =
613
- find_file(containing_component.project, change)
641
+ find_file(containing_component.project, change["path"])
614
642
  when Xcodeproj::Project::PBXNativeTarget
615
- containing_component.product_reference = find_file(containing_component.project, change)
643
+ containing_component.product_reference =
644
+ find_file(containing_component.project, change["path"])
616
645
  when Xcodeproj::Project::PBXBuildFile
617
- containing_component.file_ref = find_file(containing_component.project, change)
646
+ containing_component.file_ref = find_file(containing_component.project, change["path"])
618
647
  when Xcodeproj::Project::PBXGroup, Xcodeproj::Project::PBXVariantGroup
648
+ unless adding_files_and_groups_allowed?(change_path)
649
+ return
650
+ end
651
+
619
652
  file_reference = containing_component.project.new(Xcodeproj::Project::PBXFileReference)
620
653
  containing_component.children << file_reference
621
654
 
@@ -623,14 +656,23 @@ module Kintsugi
623
656
  # default.
624
657
  file_reference.include_in_index = nil
625
658
  file_reference.source_tree = nil
626
- add_attributes_to_component(file_reference, change)
659
+ add_attributes_to_component(file_reference, change, change_path)
627
660
  else
628
661
  raise MergeError, "Trying to add file reference to an unsupported component type " \
629
662
  "#{containing_component.isa}. Change is: #{change}"
630
663
  end
631
664
  end
632
665
 
633
- def add_group(containing_component, change)
666
+ def adding_files_and_groups_allowed?(change_path)
667
+ change_path.start_with?("rootObject/mainGroup") ||
668
+ change_path.start_with?("rootObject/projectReferences")
669
+ end
670
+
671
+ def add_group(containing_component, change, change_path)
672
+ unless adding_files_and_groups_allowed?(change_path)
673
+ return
674
+ end
675
+
634
676
  case containing_component
635
677
  when Xcodeproj::Project::ObjectDictionary
636
678
  # It is assumed that an `ObjectDictionary` always represents a project reference.
@@ -644,25 +686,29 @@ module Kintsugi
644
686
  "#{containing_component.isa}. Change is: #{change}"
645
687
  end
646
688
 
647
- add_attributes_to_component(new_group, change)
689
+ add_attributes_to_component(new_group, change, change_path)
648
690
  end
649
691
 
650
- def add_attributes_to_component(component, change, ignore_keys: [])
692
+ def add_attributes_to_component(component, change, change_path, ignore_keys: [])
651
693
  change.each do |change_name, change_value|
652
694
  next if (%w[isa displayName] + ignore_keys).include?(change_name)
653
695
 
654
696
  attribute_name = attribute_name_from_change_name(change_name)
655
697
  if simple_attribute?(component, attribute_name)
656
- apply_change_to_simple_attribute(component, attribute_name, {added: change_value})
698
+ simple_attribute_change = {
699
+ added: change_value,
700
+ removed: simple_attribute_default_value(component, attribute_name)
701
+ }
702
+ apply_change_to_simple_attribute(component, attribute_name, simple_attribute_change)
657
703
  next
658
704
  end
659
705
 
660
706
  case change_value
661
707
  when Hash
662
- add_child_to_component(component, change_value)
708
+ add_child_to_component(component, change_value, change_path)
663
709
  when Array
664
710
  change_value.each do |added_attribute_element|
665
- add_child_to_component(component, added_attribute_element)
711
+ add_child_to_component(component, added_attribute_element, change_path)
666
712
  end
667
713
  else
668
714
  raise MergeError, "Trying to add attribute of unsupported type '#{change_value.class}' " \
@@ -671,16 +717,20 @@ module Kintsugi
671
717
  end
672
718
  end
673
719
 
674
- def find_file(project, file_reference_change, file_filter: ->(_) { true })
720
+ def simple_attribute_default_value(component, attribute_name)
721
+ component.simple_attributes.find do |attribute|
722
+ attribute.name == attribute_name
723
+ end.default_value
724
+ end
725
+
726
+ def find_file(project, path, file_filter: ->(_) { true })
675
727
  file_references = project.files.select do |file_reference|
676
- file_reference.path == file_reference_change["path"] && file_filter.call(file_reference)
728
+ file_reference.path == path && file_filter.call(file_reference)
677
729
  end
678
730
  if file_references.length > 1
679
- puts "Debug: Found more than one matching file with path " \
680
- "'#{file_reference_change["path"]}'. Using the first one."
731
+ puts "Debug: Found more than one matching file with path '#{path}'. Using the first one."
681
732
  elsif file_references.empty?
682
- puts "Debug: No file reference found for file with path " \
683
- "'#{file_reference_change["path"]}'."
733
+ puts "Debug: No file reference found for file with path '#{path}'."
684
734
  return
685
735
  end
686
736
 
data/lib/kintsugi/cli.rb CHANGED
@@ -50,6 +50,7 @@ module Kintsugi
50
50
  exit(1)
51
51
  end
52
52
  Kintsugi.three_way_merge(arguments[0], arguments[1], arguments[2], arguments[3])
53
+ warn "\e[32mKintsugi auto-merged #{arguments[3]}\e[0m"
53
54
  }
54
55
 
55
56
  Command.new(