Class: Rucola::Xcode
Overview
:nodoc:
Constant Summary collapse
- NEW_COPY_FRAMEWORKS_BUILD_PHASE =
{ 'name' => 'Copy Frameworks', 'isa' => 'PBXCopyFilesBuildPhase', 'buildActionMask' => '2147483647', 'dstPath' => '', 'dstSubfolderSpec' => 10, # TODO: is 10 the number for the location popup choice: Frameworks 'runOnlyForDeploymentPostprocessing' => 0, 'files' => [].to_ns }
Instance Attribute Summary collapse
-
#project ⇒ Object
readonly
Returns the value of attribute project.
-
#project_data ⇒ Object
readonly
Returns the value of attribute project_data.
-
#project_path ⇒ Object
readonly
Returns the value of attribute project_path.
Instance Method Summary collapse
-
#add_build_phase_to_project_target(object_id) ⇒ Object
Adds a build phase specified by
object_id
to the build phases of the project target. -
#add_framework(name, path) ⇒ Object
Adds a framework to a project.
-
#add_object(object_id, object_values) ⇒ Object
Adds an object to the objects.
- #add_object_to_build_phase(object_id, build_phase_id) ⇒ Object
-
#bundle_framework(framework_name) ⇒ Object
Bundles the given framework in the application.
-
#bundle_rubycocoa_framework ⇒ Object
Bundles the RubyCocoa framework in the application.
-
#change_framework_location(framework_name, new_path_to_framework) ⇒ Object
Changes the path of the framework
framework_name
to the pathnew_path_to_framework
. -
#change_rubycocoa_framework_location(new_path_to_framework) ⇒ Object
Changes the path of the RubyCocoa framework to
new_path_to_framework
. -
#frameworks ⇒ Object
Returns an array of framework objects that are in the project.
-
#generate_object_id ⇒ Object
Makes sure that an unique object UUID is returned.
- #generate_uuid ⇒ Object
-
#initialize(project_path) ⇒ Xcode
constructor
A new instance of Xcode.
-
#new_framework_copy_build_phase ⇒ Object
Creates a new framework copy build phase.
-
#object_for_id(object_id) ⇒ Object
Returns the object for a given name.
-
#object_for_name(name) ⇒ Object
Get’s the id & values for a object which name is the one passed to this method.
-
#object_for_project_target ⇒ Object
Returns the object that represents this projects target.
-
#object_for_type_and_name(type, name) ⇒ Object
Get’s the id & values for a object which type and name is the one passed to this method.
- #objects ⇒ Object
-
#save ⇒ Object
Saves the project data atomically.
Constructor Details
#initialize(project_path) ⇒ Xcode
Returns a new instance of Xcode.
10 11 12 13 14 15 |
# File 'lib/rucola/xcode.rb', line 10 def initialize(project_path) @project_path = Pathname.new(project_path) @project = @project_path.basename.to_s.sub(/\.xcodeproj$/, '') @project_path_data = @project_path + 'project.pbxproj' @project_data = OSX::NSMutableDictionary.dictionaryWithContentsOfFile(@project_path_data.to_s) end |
Instance Attribute Details
#project ⇒ Object (readonly)
Returns the value of attribute project.
6 7 8 |
# File 'lib/rucola/xcode.rb', line 6 def project @project end |
#project_data ⇒ Object (readonly)
Returns the value of attribute project_data.
8 9 10 |
# File 'lib/rucola/xcode.rb', line 8 def project_data @project_data end |
#project_path ⇒ Object (readonly)
Returns the value of attribute project_path.
7 8 9 |
# File 'lib/rucola/xcode.rb', line 7 def project_path @project_path end |
Instance Method Details
#add_build_phase_to_project_target(object_id) ⇒ Object
Adds a build phase specified by object_id
to the build phases of the project target.
76 77 78 79 80 |
# File 'lib/rucola/xcode.rb', line 76 def add_build_phase_to_project_target(object_id) # Add the new build phase to the main project target if it doesn't already exist build_target_id, build_target_values = object_for_project_target build_target_values['buildPhases'].push(object_id) unless build_target_values['buildPhases'].include?(object_id) end |
#add_framework(name, path) ⇒ Object
Adds a framework to a project. Returns [framework_obj, fileref_obj].
94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/rucola/xcode.rb', line 94 def add_framework(name, path) source_tree = path[0, 1] == '/' ? '<absolute>' : '<group>' framework_obj = [generate_object_id, { 'isa' => 'PBXFileReference', 'lastKnownFileType' => 'wrapper.framework', 'name' => name, 'path' => path, 'sourceTree' => source_tree }.to_ns] add_object(*framework_obj) fileref_obj = [generate_object_id, { 'fileRef' => framework_obj.first, 'isa' => 'PBXBuildFile'}.to_ns] add_object(*fileref_obj) linked_frameworks_group = object_for_name('Linked Frameworks') linked_frameworks_group.last['children'].push(framework_obj.first) [framework_obj, fileref_obj] end |
#add_object(object_id, object_values) ⇒ Object
Adds an object to the objects.
71 72 73 |
# File 'lib/rucola/xcode.rb', line 71 def add_object(object_id, object_values) objects[object_id] = object_values end |
#add_object_to_build_phase(object_id, build_phase_id) ⇒ Object
82 83 84 85 |
# File 'lib/rucola/xcode.rb', line 82 def add_object_to_build_phase(object_id, build_phase_id) build_phase = object_for_id(build_phase_id).last build_phase['files'].push(object_id) unless build_phase['files'].include?(object_id) end |
#bundle_framework(framework_name) ⇒ Object
Bundles the given framework in the application.
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/rucola/xcode.rb', line 150 def bundle_framework(framework_name) framework_id, framework_values = object_for_name(framework_name) # create a new file wrapper for in the copy build phase framework_in_build_phase_id = generate_object_id framework_in_build_phase_values = { 'isa' => 'PBXBuildFile', 'fileRef' => framework_id } add_object(framework_in_build_phase_id, framework_in_build_phase_values) # get or define the Copy Frameworks build phase build_phase = object_for_name('Copy Frameworks') if build_phase.nil? build_phase_id, build_phase_values = new_framework_copy_build_phase # add the new build phase to the objects add_object(build_phase_id, build_phase_values) # add the new build phase to the project target add_build_phase_to_project_target(build_phase_id) else build_phase_id, build_phase_values = build_phase end # add the framework to the build phase add_object_to_build_phase(framework_in_build_phase_id, build_phase_id) end |
#bundle_rubycocoa_framework ⇒ Object
Bundles the RubyCocoa framework in the application.
178 179 180 |
# File 'lib/rucola/xcode.rb', line 178 def bundle_rubycocoa_framework bundle_framework 'RubyCocoa.framework' end |
#change_framework_location(framework_name, new_path_to_framework) ⇒ Object
Changes the path of the framework framework_name
to the path new_path_to_framework
.
138 139 140 141 142 |
# File 'lib/rucola/xcode.rb', line 138 def change_framework_location(framework_name, new_path_to_framework) framework_id, framework_values = object_for_name(framework_name) framework_values['path'] = new_path_to_framework framework_values['sourceTree'] = '<group>' end |
#change_rubycocoa_framework_location(new_path_to_framework) ⇒ Object
Changes the path of the RubyCocoa framework to new_path_to_framework
.
145 146 147 |
# File 'lib/rucola/xcode.rb', line 145 def change_rubycocoa_framework_location(new_path_to_framework) change_framework_location 'RubyCocoa.framework', new_path_to_framework end |
#frameworks ⇒ Object
Returns an array of framework objects that are in the project.
88 89 90 |
# File 'lib/rucola/xcode.rb', line 88 def frameworks objects.select {|obj| obj.last['name'].include?('framework') unless obj.last['name'].nil? } end |
#generate_object_id ⇒ Object
Makes sure that an unique object UUID is returned
113 114 115 116 117 118 119 |
# File 'lib/rucola/xcode.rb', line 113 def generate_object_id uuids = objects.keys begin uuid = generate_uuid end while uuids.include?(uuid) uuid end |
#generate_uuid ⇒ Object
108 109 110 |
# File 'lib/rucola/xcode.rb', line 108 def generate_uuid ("%04x%04x%04x%04x%04x%04x" % [rand(0x0010000),rand(0x0010000),rand(0x0010000),rand(0x0010000),rand(0x0010000),rand(0x0010000)]).upcase end |
#new_framework_copy_build_phase ⇒ Object
Creates a new framework copy build phase. It does not add it to the objects nor the build phases, do this with add_object
and add_build_phase_to_project_target
.
133 134 135 |
# File 'lib/rucola/xcode.rb', line 133 def new_framework_copy_build_phase [generate_object_id, NEW_COPY_FRAMEWORKS_BUILD_PHASE] end |
#object_for_id(object_id) ⇒ Object
Returns the object for a given name. Returns an array: [id, values]
66 67 68 |
# File 'lib/rucola/xcode.rb', line 66 def object_for_id(object_id) objects[object_id].nil? ? nil : [object_id, objects[object_id]] end |
#object_for_name(name) ⇒ Object
Get’s the id & values for a object which name is the one passed to this method. Returns an array: [id, values]
48 49 50 |
# File 'lib/rucola/xcode.rb', line 48 def object_for_name(name) nil_if_empty objects.select { |object| object.last['name'] == name }.flatten end |
#object_for_project_target ⇒ Object
Returns the object that represents this projects target. Returns an array: [id, values]
60 61 62 |
# File 'lib/rucola/xcode.rb', line 60 def object_for_project_target nil_if_empty object_for_type_and_name('PBXNativeTarget', @project) end |
#object_for_type_and_name(type, name) ⇒ Object
Get’s the id & values for a object which type and name is the one passed to this method. Returns an array: [id, values]
54 55 56 |
# File 'lib/rucola/xcode.rb', line 54 def object_for_type_and_name(type, name) nil_if_empty objects.select { |object| object.last['isa'] == type and object.last['name'] == name }.flatten end |
#objects ⇒ Object
42 43 44 |
# File 'lib/rucola/xcode.rb', line 42 def objects @project_data['objects'] = @project_data['objects'] end |
#save ⇒ Object
Saves the project data atomically. Returns false
if it failed.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/rucola/xcode.rb', line 19 def save # FIXME: Because we use non generated id's atm (which is bad!) # we should first make a bakup of the project. unless $TESTING puts "\n=========================================================================" puts "Backing up project #{@project}.xcodeproj to /tmp/#{@project}.xcodeproj.bak" puts "Please retrieve that one if for some reason the project was damaged!\n" end backup = "/tmp/#{@project}.xcodeproj.bak" Kernel.system("rm -rf #{backup}") if File.exists?(backup) Kernel.system("cp -R #{project_path} #{backup}") # this writes the plist as a new xml style plist, # but luckily xcode recognizes it as well and # writes it back out as an old style plist. @project_data.writeToFile_atomically(@project_path_data.to_s, true) end |