class Xcodeproj::Project::UUIDGenerator
Constants
- UUID_ATTRIBUTES
Public Class Methods
new(projects)
click to toggle source
# File lib/xcodeproj/project/uuid_generator.rb, line 6 def initialize(projects) @projects = Array(projects) @paths_by_object = {} end
Public Instance Methods
generate!()
click to toggle source
# File lib/xcodeproj/project/uuid_generator.rb, line 11 def generate! generate_all_paths_by_objects(@projects) new_objects_by_project = Hash[@projects.map do |project| [project, switch_uuids(project)] end] all_new_objects_by_project = new_objects_by_project.values.flat_map(&:values) all_objects_by_uuid = @projects.map(&:objects_by_uuid).inject(:merge) all_objects = @projects.flat_map(&:objects) verify_no_duplicates!(all_objects, all_new_objects_by_project) @projects.each { |project| fixup_uuid_references(project, all_objects_by_uuid) } new_objects_by_project.each do |project, new_objects_by_uuid| project.instance_variable_set(:@generated_uuids, project.instance_variable_get(:@available_uuids)) project.instance_variable_set(:@objects_by_uuid, new_objects_by_uuid) end end
Private Instance Methods
fixup_uuid_references(target_project, all_objects_by_uuid)
click to toggle source
# File lib/xcodeproj/project/uuid_generator.rb, line 38 def fixup_uuid_references(target_project, all_objects_by_uuid) fixup = ->(object, attr) do if object.respond_to?(attr) && link = all_objects_by_uuid[object.send(attr)] object.send(:"#{attr}=", link.uuid) end end target_project.objects.each do |object| UUID_ATTRIBUTES.each do |attr| fixup[object, attr] end end if (project_attributes = target_project.root_object.attributes) && project_attributes['TargetAttributes'] project_attributes['TargetAttributes'] = Hash[project_attributes['TargetAttributes'].map do |target_uuid, attributes| if test_target_id = attributes['TestTargetID'] attributes = attributes.merge('TestTargetID' => all_objects_by_uuid[test_target_id].uuid) end if target_object = all_objects_by_uuid[target_uuid] target_uuid = target_object.uuid end [target_uuid, attributes] end] end end
generate_all_paths_by_objects(projects)
click to toggle source
# File lib/xcodeproj/project/uuid_generator.rb, line 63 def generate_all_paths_by_objects(projects) projects.each { |project| generate_paths(project.root_object, project.path.basename.to_s) } end
generate_paths(object, path = '')
click to toggle source
# File lib/xcodeproj/project/uuid_generator.rb, line 67 def generate_paths(object, path = '') existing = @paths_by_object[object] || path return existing if @paths_by_object.key?(object) @paths_by_object[object] = path.size > existing.size ? path : existing object.to_one_attributes.each do |attrb| obj = attrb.get_value(object) generate_paths(obj, path + '/' << attrb.plist_name) if obj end object.to_many_attributes.each do |attrb| attrb.get_value(object).each do |o| generate_paths(o, path + '/' << attrb.plist_name << "/#{path_component_for_object(o)}") end end object.references_by_keys_attributes.each do |attrb| attrb.get_value(object).each do |dictionary| dictionary.each do |key, value| generate_paths(value, path + '/' << attrb.plist_name << "/k:#{key}/#{path_component_for_object(value)}") end end end end
path_component_for_object(object)
click to toggle source
# File lib/xcodeproj/project/uuid_generator.rb, line 106 def path_component_for_object(object) @path_component_for_object ||= Hash.new do |cache, key| component = tree_hash_to_path(key.to_tree_hash) component << key.hierarchy_path.to_s if key.respond_to?(:hierarchy_path) cache[key] = component end @path_component_for_object[object] end
switch_uuids(project)
click to toggle source
# File lib/xcodeproj/project/uuid_generator.rb, line 92 def switch_uuids(project) project.mark_dirty! project.objects.each_with_object({}) do |object, hash| next unless path = @paths_by_object[object] uuid = uuid_for_path(path) object.instance_variable_set(:@uuid, uuid) hash[uuid] = object end end
tree_hash_to_path(object, depth = 4)
click to toggle source
# File lib/xcodeproj/project/uuid_generator.rb, line 115 def tree_hash_to_path(object, depth = 4) return '|' if depth.zero? case object when Hash object.sort.each_with_object('') do |(key, value), string| string << key << ':' << tree_hash_to_path(value, depth - 1) << ',' end when Array object.map do |value| tree_hash_to_path(value, depth - 1) end.join(',') else object.to_s end end
uuid_for_path(path)
click to toggle source
# File lib/xcodeproj/project/uuid_generator.rb, line 102 def uuid_for_path(path) Digest::MD5.hexdigest(path).upcase end
verify_no_duplicates!(all_objects, all_new_objects)
click to toggle source
# File lib/xcodeproj/project/uuid_generator.rb, line 32 def verify_no_duplicates!(all_objects, all_new_objects) duplicates = all_objects - all_new_objects UserInterface.warn "[Xcodeproj] Generated duplicate UUIDs:\n\n" << duplicates.map { |d| "#{d.isa} -- #{@paths_by_object[d]}" }.join("\n") unless duplicates.empty? end