Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save echoZZJ/7fd8a5a25e8e0a8dbc1f2c0f90482cca to your computer and use it in GitHub Desktop.
Save echoZZJ/7fd8a5a25e8e0a8dbc1f2c0f90482cca to your computer and use it in GitHub Desktop.
Duplicate Xcode Project Target with Ruby
#!/usr/bin/env ruby
require 'rubygems'
require 'xcodeproj'
name = 'test_copy'
proj = Xcodeproj::Project.open('test.xcodeproj')
src_target = proj.targets.find { |item| item.to_s == 'test' }
# create target
target = proj.new_target(src_target.symbol_type, name, src_target.platform_name, src_target.deployment_target)
target.product_name = name
# create scheme
scheme = Xcodeproj::XCScheme.new
scheme.add_build_target(target)
scheme.set_launch_target(target)
scheme.save_as(proj.path, name)
# copy build_configurations
target.build_configurations.map do |item|
item.build_settings.update(src_target.build_settings(item.name))
end
# copy build_phases
# Copy the Build phases reference from source target to destination target, Remove duplicate
phases = src_target.build_phases.reject { |x| x.instance_of? Xcodeproj::Project::Object::PBXShellScriptBuildPhase }.collect(&:class)
# Copy the build phases
phases.each do |klass|
puts "Start Phase: " + klass.to_s
src = src_target.build_phases.find { |x| x.instance_of? klass }
dst = target.build_phases.find { |x| x.instance_of? klass }
unless dst
puts "Add to Target: " + klass.to_s
dst ||= proj.new(klass)
# PBXCopyFilesBuildPhase is not copied correctly - Fixing it here
if klass.to_s == 'Xcodeproj::Project::Object::PBXCopyFilesBuildPhase'
puts "--------------------Found-----------------" + src.name
dst.name = src.name
dst.dst_path = src.dst_path
dst.dst_subfolder_spec = src.dst_subfolder_spec
end
target.build_phases << dst
end
dst.files.map { |x|
puts " Remove from Project: " + x.to_s
x.remove_from_project
}
src.files.each do |f|
if f.file_ref != nil
# puts "SRC file Reference : " + f.file_ref.name.to_s
file_ref = proj.new(Xcodeproj::Project::Object::PBXFileReference)
file_ref.name = f.file_ref.name
file_ref.path = f.file_ref.path
file_ref.source_tree = f.file_ref.source_tree
# file_ref.last_known_file_type = f.file_ref.last_known_file_type
# file_ref.explicit_file_type = f.file_ref.explicit_file_type
if f.file_ref.respond_to?(:explicit_file_type)
file_ref.explicit_file_type = f.file_ref.explicit_file_type
end
if f.file_ref.respond_to?(:last_known_file_type)
file_ref.explicit_file_type = f.file_ref.last_known_file_type
end
if f.file_ref.respond_to?(:fileEncoding)
file_ref.fileEncoding = f.file_ref.fileEncoding
end
# file_ref.fileEncoding = f.file_ref.fileEncoding
begin
file_ref.move(f.file_ref.parent)
rescue
end
build_file = proj.new(Xcodeproj::Project::Object::PBXBuildFile)
build_file.file_ref = f.file_ref
dst.files << build_file
else
puts "SRC Ref Nil : " + f.to_s
end
end
puts "End Phase: " + klass.to_s
end
# Shell Script : Copy handling
# PBXShellScriptBuildPhase
src_target.build_phases.each do |phase|
if phase.class.name == 'Xcodeproj::Project::Object::PBXShellScriptBuildPhase'
puts "Start Script Phase: " + phase.to_s
# shell_script = proj.new(Xcodeproj::Project::Object::PBXShellScriptBuildPhase)
dst = proj.new(phase.class.name)
dst.name = phase.name
dst.dependency_file = phase.dependency_file
dst.input_file_list_paths = phase.input_file_list_paths
dst.input_paths = phase.input_paths
dst.output_file_list_paths = phase.output_file_list_paths
dst.output_paths = phase.output_paths
dst.shell_path = phase.shell_path
dst.shell_script = phase.shell_script
dst.show_env_vars_in_log = phase.show_env_vars_in_log
target.build_phases << dst
puts "End Script Phase: " + phase.to_s
end
end
#copy dependency here - Extensions dependency is copied
src_target.dependencies.each do |phase|
target.dependencies << phase
end
# add files
# classes = proj.main_group.groups.find { |x| x.to_s == 'Group' }.groups.find { |x| x.name == 'Classes' }
# sources = target.build_phases.find { |x| x.instance_of? Xcodeproj::Project::Object::PBXSourcesBuildPhase }
# file_ref = classes.new_file('test.m')
# build_file = proj.new(Xcodeproj::Project::Object::PBXBuildFile)
# build_file.file_ref = file_ref
# sources.files << build_file
proj.save
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment