Last active
June 23, 2017 10:46
-
-
Save matnogaj/1a4c1d10bfc458a25f86e2946f7cae53 to your computer and use it in GitHub Desktop.
Adds adhoc config to projects found in node_modules
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'xcodeproj' | |
require 'find' | |
require 'yaml' | |
require 'set' | |
class XCodeProject | |
def initialize(path) | |
unless File.exists?(path) | |
raise Errno::ENOENT, "#{path} does not exist." | |
end | |
@path = path | |
@_name = File.basename(path, '.xcodeproj') | |
@proj = Xcodeproj::Project.open(path) | |
@build_config_names = @proj.build_configurations.collect(&:name).to_set | |
@debug_bc = build_config_named 'Debug' | |
@release_bc = build_config_named 'Release' | |
end | |
def project_name | |
@_name | |
end | |
def deep_dup(object) | |
case object | |
when Hash | |
new_hash = {} | |
object.each do |key, value| | |
new_hash[key] = deep_dup(value) | |
end | |
new_hash | |
when Array | |
object.map { |value| deep_dup(value) } | |
else | |
object.dup | |
end | |
end | |
def build_configurations | |
@proj.build_configurations | |
end | |
def mirror_settings(from_bc, to_bc) | |
to_bc.build_settings = deep_dup(from_bc.build_settings) | |
end | |
def duplicate_debug_as(name) | |
bc = @proj.add_build_configuration(name, :debug) | |
mirror_settings(@debug_bc, bc) | |
end | |
def duplicate_release_as(name) | |
bc = @proj.add_build_configuration(name, :release) | |
mirror_settings(@release_bc, bc) | |
end | |
def ensure_build_config(name, kind) | |
base_bc = kind == :debug ? @debug_bc : @release_bc | |
if has_config_named name | |
puts " Configuration '#{name}' already exists." | |
puts " Ensuring settings are properly mirrored." | |
mirror_settings(base_bc, build_config_named(name)) | |
else | |
puts " Not Found: '#{name}'." | |
puts " Creating new one based off of #{base_bc.name}." | |
if kind == :debug | |
duplicate_debug_as(name) | |
else | |
duplicate_release_as(name) | |
end | |
end | |
end | |
def ensure_build_config_in_targets(name, kind) | |
@proj.targets.each do |target| | |
names = target.build_configurations.collect(&:name).to_set | |
if !names.include?(name) | |
puts "Target #{target} is missing #{name}" | |
new_bc = target.add_build_configuration(name, kind) | |
config_name = (kind == :debug) ? 'Debug' : 'Release' | |
from_bc = target.build_configurations.find { |bc| bc.name == config_name } | |
mirror_settings(from_bc, new_bc) | |
# save | |
end | |
end | |
end | |
def build_config_named(name) | |
@proj.build_configurations.find { |bc| bc.name == name } | |
end | |
def all_build_phases | |
@proj.targets.map{|t|t.build_phases}.flatten | |
end | |
def has_config_named(name) | |
@build_config_names.include?(name) | |
end | |
def find_run_script_phase | |
all_build_phases.find do |bp| | |
bp.is_a?(Xcodeproj::Project::Object::PBXShellScriptBuildPhase) && yield(bp) | |
end | |
end | |
def save | |
@proj.save | |
end | |
end | |
class BuildConfigSynchronizer | |
def initialize(search_path=File.join(File.dirname(__FILE__), '../node_modules')) | |
@search_path = search_path | |
# if you need more configs then add them here | |
@mappings = {:debug => ["Debug"], :release => ["Release", "AdHoc"]} | |
find_and_fix_projects | |
end | |
def fix_project(project) | |
puts "Fixing #{project.project_name}..." | |
puts " Ensuring all build configs are properly mapped" | |
@mappings.each do |kind,names| | |
names.each do |name| | |
# first fix targets and later project | |
project.ensure_build_config_in_targets(name, kind) | |
project.ensure_build_config(name, kind) | |
end | |
end | |
puts " Making sure run scripts have correct conditionals." | |
bp = project.find_run_script_phase do |rs_phase| | |
rs_phase.shell_script.include?('"Debug"') | |
end | |
if bp | |
puts " Run script needs updating." | |
ss_text = bp.shell_script.split("\n").map{|s| " #{s}"}.join("\n") | |
puts " Found:\n#{ss_text}\n" | |
bp.shell_script = bp.shell_script.sub('"Debug"', '*Debug') | |
ss_text = bp.shell_script.split("\n").map{|s| " #{s}"}.join("\n") | |
puts " Replaced with:\n#{ss_text}\n" | |
else | |
puts " Run script seems in order." | |
end | |
puts "Finished fixing #{project.project_name}.\n\n" | |
project.save | |
end | |
def find_and_fix_projects | |
puts "Searching #{@search_path} for relevant xcodeproj's...\n\n" | |
Find.find(@search_path) do |e| | |
if e =~ /\.xcodeproj\Z/ | |
puts "Found SOME xcodeproj file. #{e}" | |
fix_project(XCodeProject.new(e)) | |
end | |
end | |
end | |
end | |
BuildConfigSynchronizer.new |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment