Skip to content

Instantly share code, notes, and snippets.

@rafinhaa
Created June 8, 2023 16:41
Show Gist options
  • Save rafinhaa/326c9857c4516ace50c8312e5186b7ae to your computer and use it in GitHub Desktop.
Save rafinhaa/326c9857c4516ace50c8312e5186b7ae to your computer and use it in GitHub Desktop.
Duplicate xcode target with info.plist
require 'rubygems'
require 'xcodeproj'
require 'fileutils'
project_path = ARGV[0]
base_target_name = ARGV[1]
name = ARGV[2]
if project_path.nil? || base_target_name.nil? || name.nil?
puts "Usage: ruby duplicate-ios-target.rb <project_path> <base_target_name> <duplicate_target_name>"
exit(1)
end
proj = Xcodeproj::Project.open(project_path)
src_target = proj.targets.find { |item| item.to_s == base_target_name }
# 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
phases = src_target.build_phases.reject { |x| x.instance_of? Xcodeproj::Project::Object::PBXShellScriptBuildPhase }.collect(&:class)
phases.each do |klass|
src = src_target.build_phases.find { |x| x.instance_of? klass }
dst = target.build_phases.find { |x| x.instance_of? klass }
unless dst
dst ||= proj.new(klass)
target.build_phases << dst
end
dst.files.map { |x| x.remove_from_project }
src.files.each do |f|
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.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
end
end
# Copy and associate .plist file
plist_file_path = File.join(File.dirname(project_path), "#{base_target_name}.plist")
new_plist_file_path = File.join(File.dirname(project_path), "#{name}.plist")
if File.exist?(plist_file_path)
FileUtils.copy_file(plist_file_path, new_plist_file_path)
new_plist_file_ref = proj.new(Xcodeproj::Project::Object::PBXFileReference)
new_plist_file_ref.path = "#{name}.plist"
new_plist_file_ref.source_tree = 'SOURCE_ROOT'
new_plist_file_ref.last_known_file_type = 'text.plist.xml'
new_plist_file_ref.fileEncoding = '4'
proj.main_group << new_plist_file_ref
target.build_configurations.each do |build_configuration|
build_settings = build_configuration.build_settings
build_settings['INFOPLIST_FILE'] = new_plist_file_ref.path
end
end
proj.save
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment