Skip to content

Commit

Permalink
apply_change_to_project: use attribute_name for building change_path.
Browse files Browse the repository at this point in the history
When merging the tree, Kintsugi keeps track of where it is, to allow
finding the corresponding component in the source project.
Until this commit, the path was constructed in `add_child_to_component`
by appending the display name of the added component.
When adding a file reference this path was used to traverse the project
tree along each object's attributes.

This caused a bug when the display name and the attribute name
are different, e.g., a target's build configuration list has a display
name of "ConfigurationList" and an attribute name of
"build_configuration_list". The camel-case was converted correctly, but
the merge failed due to not finding the attribute "configuration_list".

The solution to this issue is to use the attribute names to create the
path, except when adding an object to a list, where there is no
attribute and then the display name is used.
  • Loading branch information
ashdnazg committed May 9, 2024
1 parent 5f9d548 commit 4c26a59
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 10 deletions.
17 changes: 8 additions & 9 deletions lib/kintsugi/apply_change_to_project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,8 @@ def apply_change_to_component(parent_component, change_name, change, parent_chan
component = child_component(parent_component, change_name)
elsif change[:added].is_a?(Array)
(change[:added]).each do |added_change|
add_child_to_component(parent_component, added_change, change_path)
add_child_to_component(parent_component, added_change,
join_path(change_path, added_change["displayName"]))
end
elsif !change[:added].nil?
raise MergeError, "Unsupported added change type for #{change[:added]}"
Expand Down Expand Up @@ -341,9 +342,8 @@ def resolve_nonexistent_component(parent_component, change_path)
else
parent_component
end
parent_change_path = change_path.split("/")[0...-1].join("/")
add_child_to_component(non_object_list_parent, source_project_component.to_tree_hash,
parent_change_path)
change_path)
component_at_path(non_object_list_parent.project, change_path)
end

Expand Down Expand Up @@ -637,9 +637,7 @@ def remove_build_files_of_file_reference(file_reference)
end
end

def add_child_to_component(component, change, component_change_path)
change_path = join_path(component_change_path, change["displayName"])

def add_child_to_component(component, change, change_path)
if change["ProjectRef"] && change["ProductGroup"]
add_subproject_reference(component, change, change_path)
return
Expand Down Expand Up @@ -1031,13 +1029,14 @@ def add_attributes_to_component(component, change, change_path, ignore_keys: [])
next
end

child_path = join_path(change_path, change_name)
case change_value
when Hash
add_child_to_component(component, change_value, change_path)
add_child_to_component(component, change_value, child_path)
when Array
change_value.each do |added_attribute_element|
add_child_to_component(component, added_attribute_element,
"#{change_path}/#{change_name}")
element_path = join_path(child_path, added_attribute_element["displayName"])
add_child_to_component(component, added_attribute_element, element_path)
end
else
raise MergeError, "Trying to add attribute of unsupported type '#{change_value.class}' " \
Expand Down
25 changes: 24 additions & 1 deletion spec/kintsugi_apply_change_to_project_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1399,8 +1399,9 @@
expect(base_project).to be_equivalent_to_project(theirs_project)
end

it "adds base configuration reference to new target" do
it "adds base configuration reference" do
base_project.main_group.new_reference("baz")
base_project.save

theirs_project = create_copy_of_project(base_project.path, "theirs")
configuration_reference = theirs_project.main_group.find_subpath("baz")
Expand All @@ -1414,6 +1415,28 @@

expect(base_project).to be_equivalent_to_project(theirs_project)
end

it "adds base configuration reference to new configuration in a new list" do
base_project.main_group.new_reference("baz")
base_project.targets[0].build_configuration_list = nil
base_project.save

theirs_project = create_copy_of_project(base_project.path, "theirs")
configuration_reference = theirs_project.main_group.find_subpath("baz")

configuration_list = theirs_project.new(Xcodeproj::Project::XCConfigurationList)
theirs_project.targets[0].build_configuration_list = configuration_list

build_configuration = theirs_project.new(Xcodeproj::Project::XCBuildConfiguration)
build_configuration.base_configuration_reference = configuration_reference
configuration_list.build_configurations << build_configuration

changes_to_apply = get_diff(theirs_project, base_project)

described_class.apply_change_to_project(base_project, changes_to_apply, theirs_project)

expect(base_project).to be_equivalent_to_project(theirs_project)
end
end

it "adds known regions" do
Expand Down

0 comments on commit 4c26a59

Please sign in to comment.