vendor 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/CHANGELOG.md +6 -0
  2. data/Gemfile.lock +1 -1
  3. data/LICENSE +1 -1
  4. data/Readme.markdown +2 -1
  5. data/VERSION +1 -1
  6. data/lib/vendor/cli/app.rb +13 -17
  7. data/lib/vendor/spec.rb +244 -55
  8. data/lib/vendor/vendor_file/library/base.rb +43 -63
  9. data/lib/vendor/vendor_file/loader.rb +8 -0
  10. data/lib/vendor/vendor_spec/builder.rb +19 -8
  11. data/lib/vendor/xcode.rb +0 -1
  12. data/lib/vendor/xcode/project.rb +198 -469
  13. data/spec/lib/vendor/spec_spec.rb +34 -10
  14. data/spec/lib/vendor/vendor_file/library/base_spec.rb +41 -49
  15. data/spec/lib/vendor/vendor_spec/builder_spec.rb +26 -0
  16. data/spec/support/resources/cache/base/DKBenchmark-0.1-Manifest/vendor.json +1 -1
  17. data/spec/support/resources/cache/base/DKBenchmark-0.1-Vendorspec/DKBenchmark.vendorspec +2 -0
  18. data/spec/support/resources/vendors/DKBenchmark/DKBenchmark.vendorspec +2 -0
  19. data/spec/support/resources/vendors/DKBenchmarkFramework/DKBenchmark.framework/DKBenchmark +0 -0
  20. data/spec/support/resources/vendors/DKBenchmarkFramework/DKBenchmark.framework/Versions/A/DKBenchmark +0 -0
  21. data/spec/support/resources/vendors/DKBenchmarkFramework/DKBenchmark.framework/Versions/A/Headers/DKBenchmark.h +18 -0
  22. data/spec/support/resources/vendors/DKBenchmarkFramework/DKBenchmark.vendorspec +23 -0
  23. data/vendor.gemspec +1 -0
  24. metadata +111 -63
  25. data/lib/vendor/xcode/proxy.rb +0 -31
  26. data/lib/vendor/xcode/proxy/base.rb +0 -129
  27. data/lib/vendor/xcode/proxy/pbx_aggregate_target.rb +0 -11
  28. data/lib/vendor/xcode/proxy/pbx_build_file.rb +0 -9
  29. data/lib/vendor/xcode/proxy/pbx_container_item_proxy.rb +0 -8
  30. data/lib/vendor/xcode/proxy/pbx_file_reference.rb +0 -41
  31. data/lib/vendor/xcode/proxy/pbx_frameworks_build_phase.rb +0 -15
  32. data/lib/vendor/xcode/proxy/pbx_group.rb +0 -35
  33. data/lib/vendor/xcode/proxy/pbx_native_target.rb +0 -11
  34. data/lib/vendor/xcode/proxy/pbx_project.rb +0 -12
  35. data/lib/vendor/xcode/proxy/pbx_reference_proxy.rb +0 -7
  36. data/lib/vendor/xcode/proxy/pbx_resources_build_phase.rb +0 -15
  37. data/lib/vendor/xcode/proxy/pbx_shell_script_build_phase.rb +0 -15
  38. data/lib/vendor/xcode/proxy/pbx_sources_build_phase.rb +0 -15
  39. data/lib/vendor/xcode/proxy/pbx_target_dependency.rb +0 -7
  40. data/lib/vendor/xcode/proxy/pbx_variant_group.rb +0 -7
  41. data/lib/vendor/xcode/proxy/unknown.rb +0 -8
  42. data/lib/vendor/xcode/proxy/xc_build_configuration.rb +0 -7
  43. data/lib/vendor/xcode/proxy/xc_configuration_list.rb +0 -9
  44. data/lib/vendor/xcode/proxy/xc_version_group.rb +0 -7
  45. data/spec/lib/vendor/xcode/project_spec.rb +0 -635
  46. data/spec/lib/vendor/xcode/proxy/base_spec.rb +0 -88
  47. data/spec/lib/vendor/xcode/proxy/pbx_file_reference_spec.rb +0 -26
  48. data/spec/lib/vendor/xcode/proxy/pbx_group_spec.rb +0 -27
  49. data/spec/lib/vendor/xcode/proxy/pbx_project_spec.rb +0 -29
@@ -23,6 +23,14 @@ module Vendor
23
23
  self.libraries = @dsl.libraries
24
24
  end
25
25
 
26
+ def libraries_to_install
27
+ unless @graph.version_conflicts?
28
+ @graph.libraries_to_install.each do |library,targets|
29
+ yield library, targets if block_given?
30
+ end
31
+ end
32
+ end
33
+
26
34
  def install(project)
27
35
  unless @graph.version_conflicts?
28
36
  @graph.libraries_to_install.each do |lib|
@@ -43,37 +43,48 @@ module Vendor
43
43
 
44
44
  private
45
45
 
46
+ # Find all the files within the vendor spec to install
47
+ def vendor_spec_files_to_install
48
+ Array(@vendor_spec.files) + Array(@vendor_spec.resources)
49
+ end
50
+
46
51
  def copy_files(data_dir)
47
52
  data_files = []
48
53
 
49
54
  raise NoFilesError.new("No file definition found for #{@name}") if @vendor_spec.files.nil?
50
55
 
51
- # Remove files that are within folders with a ".", such as ".bundle"
52
- # and ".frameworks"
53
- copy_files = @vendor_spec.files.reject { |file| file =~ /\/?[^\/]+\.[^\/]+\// }
56
+ copy_files = vendor_spec_files_to_install
54
57
 
55
58
  raise NoFilesError.new("No files found for packaging") if copy_files.empty?
56
59
 
57
60
  copy_files.each do |file|
58
61
  dir = File.dirname(file)
59
62
  path = File.join(@folder, file)
60
- copy_to_dir = File.expand_path(File.join(data_dir, dir))
61
- copy_to_file = File.join(copy_to_dir, File.basename(file))
63
+ if File.directory? path
64
+ copy_to_dir = File.expand_path(File.join(data_dir, dir, File.basename(file)))
65
+ copy_to_file = File.expand_path(copy_to_dir)
66
+ else
67
+ copy_to_dir = File.expand_path(File.join(data_dir, dir))
68
+ copy_to_file = File.join(copy_to_dir, File.basename(file))
69
+ end
62
70
 
63
71
  Vendor.ui.debug "Creating dir #{copy_to_dir}"
64
72
  FileUtils.mkdir_p copy_to_dir
65
73
 
66
74
  Vendor.ui.debug "Copying #{path} to #{copy_to_file}"
67
- FileUtils.cp_r path, copy_to_file
75
+ FileUtils.copy_entry path, copy_to_file
68
76
 
69
77
  data_files << copy_to_file
78
+ if File.directory?(path)
79
+ data_files.concat(Dir.glob(File.join(copy_to_file, "**", "*")))
80
+ end
70
81
  end
71
-
82
+
72
83
  data_files
73
84
  end
74
85
 
75
86
  def zip_file(filename, files, base_dir)
76
- Zip::ZipFile.open(filename, Zip::ZipFile::CREATE)do |zipfile|
87
+ Zip::ZipFile.open(filename, Zip::ZipFile::CREATE) do |zipfile|
77
88
 
78
89
  files.each do |file|
79
90
  path = file.gsub(base_dir, '').gsub(/^\//, '')
@@ -2,7 +2,6 @@ module Vendor
2
2
 
3
3
  module XCode
4
4
 
5
- autoload :Proxy, "vendor/xcode/proxy"
6
5
  autoload :Project, "vendor/xcode/project"
7
6
 
8
7
  end
@@ -1,503 +1,232 @@
1
- require 'json'
1
+ require 'xcoder'
2
2
 
3
3
  module Vendor::XCode
4
4
 
5
5
  class Project
6
6
 
7
- # Build settings and the format that they should be stored in
8
- BUILD_SETTING_TYPES = {
9
- "OTHER_LDFLAGS" => :array
10
- }
11
-
12
- require 'fileutils'
13
-
14
- attr_reader :name
15
- attr_reader :object_version
16
- attr_reader :archive_version
17
- attr_reader :objects
18
- attr_reader :root_object
19
- attr_reader :project_folder
20
-
21
- attr_accessor :dirty
7
+ attr_reader :project
22
8
 
23
9
  def initialize(project_folder)
24
- @project_folder = project_folder
25
- @pbxproject = ::File.join(project_folder, "project.pbxproj")
26
- @name = File.basename(project_folder).split(".").first
27
- @dirty = false
28
-
29
- reload
30
- end
31
-
32
- def reload
33
- # We switch between our custom PList converter and the JSON format
34
- # because the custom implementation isn't very reliable. We use it mainly
35
- # so the gem can run on systems that don't have plutil installed (like our
36
- # CI server). The plutil app is far more reliable.
37
- if RUBY_PLATFORM !~ /darwin/ || ENV['PARSER'] == 'custom'
38
- contents = File.readlines(@pbxproject).join("\n")
39
- parsed = Vendor::Plist.parse_ascii(contents)
40
- else
41
- parsed = JSON.parse(`plutil -convert json -o - "#{@pbxproject}"`)
42
- end
43
-
44
- @object_version = parsed['objectVersion'].to_i
45
- @archive_version = parsed['archiveVersion'].to_i
46
-
47
- @objects_by_id = {}
48
-
49
- @objects = parsed['objects'].map do |id, attributes|
50
- begin
51
- klass = Vendor::XCode::Proxy.const_get(attributes['isa'])
52
- rescue NameError => e
53
- klass = Vendor::XCode::Proxy::Unknown
54
- end
55
-
56
- @objects_by_id[id] = klass.new(:project => self, :id => id, :attributes => attributes)
57
- end
58
-
59
- @objects.each { |object| object.send(:after_initialize) }
60
-
61
- @root_object = @objects_by_id[parsed['rootObject']]
62
- end
63
-
64
- def find_object(id)
65
- @objects_by_id[id]
66
- end
67
-
68
- def find_target(t)
69
- # Are we already a target?
70
- if t.kind_of?(Vendor::XCode::Proxy::Base)
71
- t
10
+ @project = Xcode.project project_folder
11
+ end
12
+
13
+ #
14
+ # Install the library into the project for the selected targets.
15
+ #
16
+ # @param [Library] library the instance that conveys the requirements to
17
+ # install.
18
+ # @param [Array<Symbols>] targets to install this library; The value :all
19
+ # is a special target name that means all targets.
20
+ #
21
+ def install(library,targets)
22
+
23
+ Vendor.ui.info "## Installing __#{library.name} (#{library.version})__\n\n"
24
+
25
+ project_targets = project_targets_from_specified_targets(targets)
26
+
27
+ if project_targets.empty?
28
+ Vendor.ui.warn "* The project '#{project.name}' does not have any matching targets: #{targets.join(", ")}"
29
+ return
30
+ end
31
+
32
+ library_pathname = "Vendor/#{library.name}"
33
+
34
+ files_added = create_library_folders_and_groups library_pathname, library.files
35
+
36
+ resources_added = create_library_folders_and_groups library_pathname, library.resources, 'resource'
37
+
38
+ frameworks_added = add_required_frameworks_to_project library.frameworks
39
+
40
+
41
+ source_files = files_added.find_all {|file| File.extname(file.path.to_s) =~ /\.mm?$/ }
42
+
43
+ framework_files = frameworks_added + files_added.find_all {|file| File.extname(file.path.to_s) =~ /\.a$|\.framework$/ }
44
+
45
+
46
+ project_targets.each do |target|
47
+
48
+ Vendor.ui.info "\n### Configuring Build Target '__#{target.name}__'\n\n"
49
+
50
+ add_source_files_to_sources_build_phase source_files, target.sources_build_phase, library.per_file_flag
51
+
52
+ add_resource_files_to_resources_build_phase resources_added, target.resources_build_phase
53
+
54
+ add_frameworks_to_frameworks_build_phase framework_files, target.framework_build_phase
55
+
56
+ add_build_settings_to_target_configurations target, library.build_settings
57
+
58
+ end
59
+
60
+ project.save!
61
+
62
+ end
63
+
64
+ private
65
+
66
+
67
+ #
68
+ # Convert the target names to the actual target objects within the project
69
+ #
70
+ # @param [Array<Symbols>] targets to install this library; The value :all
71
+ # is a special target name that means all targets.
72
+ #
73
+ # @return [Array<Target>] the targets that match the specified target names.
74
+ #
75
+ def project_targets_from_specified_targets(specified_targets)
76
+
77
+ if specified_targets == [:all]
78
+
79
+ project.targets
80
+
72
81
  else
73
- root_object.targets.find { |x| x.name == t }
74
- end
75
- end
76
-
77
- def find_group(path)
78
- current = root_object.main_group
79
-
80
- path.split("/").each do |name|
81
- current = current.children.find { |x| (x.respond_to?(:name) ? x.name : x.path) == name }
82
- return nil unless current
83
- end
84
-
85
- current
86
- end
87
-
88
- def create_group(path)
89
- current = root_object.main_group
90
-
91
- path.split("/").each do |name|
92
- group = current.children.find { |x| (x.respond_to?(:name) ? x.name : x.path) == name }
93
-
94
- unless group
95
- group = Vendor::XCode::Proxy::PBXGroup.new(:project => self,
96
- :id => Vendor::XCode::Proxy::Base.generate_id,
97
- :attributes => { 'path' => name, 'sourceTree' => '<group>', 'children' => [] })
98
-
99
- # Set the parent
100
- group.parent = current
101
-
102
- @objects_by_id[group.id] = group
103
-
104
- # This is hacky
105
- current.attributes['children'] << group.id
106
- end
107
-
108
- current = group
109
- end
110
-
111
- # Mark as dirty
112
- @dirty = true
113
-
114
- current
115
- end
116
-
117
- def remove_group(path)
118
- group = find_group(path)
119
-
120
- # If we have the group
121
- if group
122
-
123
- ids_to_remove = []
124
-
125
- # Remove the children from the file system
126
- group.children.each do |child|
127
- if child.group? # Is it a group?
128
- remove_group child.full_path # Recursivley remove the child group
129
- elsif child.file? # Or a file
130
- file = File.expand_path(File.join(@project_folder, "..", child.full_path))
131
-
132
- # Remove the file from the filesystem
133
- if File.exist?(file)
134
- FileUtils.rm_rf file
135
- end
136
- else
137
- Vendor.ui.error "Couldn't remove object: #{child}"
138
- end
139
-
140
- # Remove from the targets (if we can)
141
- root_object.targets.each { |t| remove_file_from_target(child, t) }
142
-
143
- # Remove the file from the parent
144
- child.parent.attributes['children'].delete child.id
145
-
146
- # Add the id to the list of stuff to remove. If we do this
147
- # during the loop, bad things happen - not sure why.
148
- ids_to_remove << child.id
149
- end
150
-
151
- # Remove the group from the parent
152
- group.parent.attributes['children'].delete group.id
153
-
154
- # Add to the list of stuff to remove
155
- ids_to_remove << group.id
156
-
157
- ids_to_remove.each do |id|
158
- @objects_by_id.delete id
82
+
83
+ # Take each specified target names and compare those with the targets
84
+ # specified within the project. Find all that match and return them,
85
+ # ignoring aggregate targets that may match the name as they are
86
+ # not capable of love that comes with bearing files.
87
+
88
+ # @note project#target(name) seems like it would be a better choice,
89
+ # however, the Xcoder implementation raises an error when a target
90
+ # does not match the specified name.
91
+
92
+ specified_targets.uniq.map do |name|
93
+
94
+ project.targets.reject {|target| target.isa == "PBXAggregateTarget" }.find_all {|target| target.name == name }
95
+
96
+ end.flatten
97
+ end
98
+
99
+ end
100
+
101
+ #
102
+ #
103
+ # @param [String] pathname the path to create for the library
104
+ # @param [Array<String>] files to copy into the project and create in the
105
+ # project.
106
+ # @return [Array<FileReference>] an array of all the files that were added
107
+ # to the project.
108
+ #
109
+ def create_library_folders_and_groups(pathname,files,section="")
110
+
111
+ # Create the physical path for the library
112
+
113
+ FileUtils.mkdir_p pathname
114
+
115
+ # Create the project's logical group for the library
116
+
117
+ library_group = project.group pathname
118
+
119
+ Vendor.ui.info "* Installing #{files.count} #{section} file(s)\n\n"
120
+
121
+ files.map do |file|
122
+
123
+ target_filepath = "#{pathname}/#{File.basename(file)}"
124
+
125
+ Vendor.ui.debug " > from: #{file}\n\n"
126
+ Vendor.ui.debug " > to: #{target_filepath}\n\n"
127
+
128
+ # Copy the physical file to the library path
129
+
130
+ FileUtils.cp_r file, target_filepath
131
+
132
+ # Copy the project's logical files
133
+
134
+ library_group.create_file 'name' => File.basename(file), 'path' => target_filepath, 'sourceTree' => 'SOURCE_ROOT'
135
+
136
+ end.compact
137
+
138
+ end
139
+
140
+ #
141
+ # @param [Array<String>] frameworks to add to the frameworks section of the
142
+ # project.
143
+ # @return [Array<FileReference>] an array of all the frameworks and system
144
+ # libraries that were added to the project.
145
+ #
146
+ def add_required_frameworks_to_project(frameworks)
147
+ frameworks.map do |framework_name|
148
+ if File.extname(framework_name) =~ /^\.dylib$/
149
+ project.frameworks_group.create_system_library(framework_name)
150
+ else
151
+ project.frameworks_group.create_system_framework(framework_name)
159
152
  end
160
-
161
- # Mark as dirty
162
- @dirty = true
163
-
164
- else
165
- false
166
153
  end
167
154
  end
168
-
169
- def add_framework(framework, options = {})
170
- # Find targets and filter out aggregate targets (we can't add files to
171
- # those bad boys)
172
- targets = targets_from_options(options, :ignore_aggregates => true)
173
-
174
- Vendor.ui.debug %{Adding #{framework} to targets "#{targets.map(&:name)}"}
175
-
176
- path = if framework.match(/\.dylib/)
177
- "usr/lib/#{framework}"
178
- else
179
- "System/Library/Frameworks/#{framework}"
180
- end
181
-
182
- targets.each do |t|
183
- # Does the framework already exist?
184
- build_phase = build_phase_for_file("wrapper.framework", t)
185
-
186
- if build_phase
187
- # Does a framework already exist?
188
- existing_framework = build_phase.files.map(&:file_ref).find do |file|
189
- # Some files have names, some done. Framework references
190
- # have names...
191
- if file.respond_to?(:name)
192
- file.name == framework
193
- end
194
- end
195
-
196
- # If an existing framework was found, don't add it again
197
- unless existing_framework
198
- add_file :targets => t, :file => path, :name => framework,
199
- :path => "Frameworks", :source_tree => :sdkroot
200
- end
201
- end
155
+
156
+
157
+ def add_source_files_to_sources_build_phase files, sources_build_phase, per_file_flag
158
+
159
+ unless sources_build_phase
160
+ Vendor.ui.warn "* No sources build phase exists for this target\n"
161
+ return
202
162
  end
203
- end
204
-
205
- def add_build_setting(name, value, options = {})
206
-
207
- targets_from_options(options).each do |target|
208
-
209
- target.build_configuration_list.build_configurations.each do |config|
210
-
211
- build_settings = config.build_settings
212
-
213
- debug_key = "#{target.name}/#{config.name}".inspect
214
-
215
- # If the build setting already has the key
216
- if build_settings.has_key?(name)
217
-
218
- # Is this setting known to have multiple values?
219
- if (setting_type = BUILD_SETTING_TYPES[name])
220
-
221
- # If its an array
222
- if setting_type == :array
223
- # Is it already an array, if so, check to see if
224
- # it already exists, and if it doesn't add it.
225
- if build_settings[name].kind_of?(Array)
226
- unless build_settings[name].include?
227
- Vendor.ui.debug(" Added build setting (#{name.inspect} = #{value.inspect}) to #{debug_key}")
228
-
229
- build_settings[name] << value
230
- end
231
- else
232
- Vendor.ui.debug(" Added build setting (#{name.inspect} = #{value.inspect}) to #{debug_key}")
233
-
234
- # Don't add it if the single build value is already there
235
- unless build_settings[name].strip == value.strip
236
- build_settings[name] = [ build_settings[name], value ]
237
- end
238
- end
239
- end
240
-
241
- else
242
- # If its an unknown type, then we should just throw a warning
243
- # because we should'nt just change stuff willy, nilly.
244
- Vendor.ui.warn(" Build setting #{name.inspect} wanted to change to #{value.inspect}, but it was already #{build_settings[name].inspect} in #{debug_key}")
245
- end
246
-
247
- else
248
- Vendor.ui.debug(" Added build setting (#{name.inspect} = #{value.inspect}) to #{debug_key}")
249
163
 
250
- build_settings[name] = value
251
- end
164
+ Vendor.ui.info "* Sources Build Phase - adding #{files.count} file(s)\n\n"
165
+
166
+ files.each do |file|
252
167
 
168
+ Vendor.ui.debug " > #{file.path}\n\n"
169
+
170
+ if per_file_flag
171
+ sources_build_phase.add_build_file file, { 'COMPILER_FLAGS' => per_file_flag }
172
+ else
173
+ sources_build_phase.add_build_file file
253
174
  end
254
-
255
175
  end
256
-
257
- @dirty = true
258
-
259
176
  end
177
+
178
+ def add_resource_files_to_resources_build_phase files, resources_build_phase
260
179
 
261
- def add_file(options)
262
- require_options options, :path, :file, :source_tree
263
-
264
- # Ensure file exists if we'nre not using the sdk root source tree.
265
- # The SDKROOT source tree has a virtual file on the system, so
266
- # File.exist checks will always return false.
267
- unless options[:source_tree] == :sdkroot
268
- raise StandardError.new("Could not find file `#{options[:file]}`") unless File.exists?(options[:file])
180
+ unless resources_build_phase
181
+ Vendor.ui.warn "* No resources build phase exists for this target\n"
182
+ return
269
183
  end
184
+
185
+ Vendor.ui.info "* Resources Build Phase - adding #{files.count} file(s)\n\n"
186
+
187
+ files.each do |file|
270
188
 
271
- # Find targets and filter out aggregate targets (we can't add files to
272
- # those bad boys)
273
- targets = targets_from_options(options, :ignore_aggregates => true)
274
-
275
- # Create the group
276
- group = create_group(options[:path])
277
-
278
- # File type
279
- type = Vendor::XCode::Proxy::PBXFileReference.file_type_from_extension(File.extname(options[:file]))
280
-
281
- # The file name
282
- name = File.basename(options[:file])
283
-
284
- attributes = {
285
- 'lastKnownFileType' => type,
286
- 'sourceTree' => "<#{options[:source_tree].to_s}>"
287
- }
288
-
289
- # Handle the different source tree types
290
- if options[:source_tree] == :group
291
-
292
- # Ensure the path exists on the filesystem
293
- path = File.join(@project_folder, "..", options[:path])
294
- FileUtils.mkdir_p path
295
-
296
- # Copy the file
297
- FileUtils.cp_r options[:file], File.join(path, name)
298
-
299
- # Set the path of the file
300
- attributes['path'] = name
301
-
302
- elsif options[:source_tree] == :absolute
303
-
304
- # Set the path and the name of the file
305
- attributes['name'] = name
306
- attributes['path'] = options[:file]
307
-
308
- elsif options[:source_tree] == :sdkroot
309
-
310
- # Set the path and the name of the framework
311
- attributes['name'] = name
312
- attributes['path'] = options[:file]
313
- attributes['sourceTree'] = "SDKROOT"
314
-
315
- else
316
-
317
- # Could not handle that option
318
- raise StandardError.new("Invalid :source_tree option `#{options[:source_tree].to_s}`")
319
-
320
- end
321
-
322
- # Add the file to XCode
323
- file = Vendor::XCode::Proxy::PBXFileReference.new(:project => self,
324
- :id => Vendor::XCode::Proxy::Base.generate_id,
325
- :attributes => attributes)
326
-
327
- # Set the parent
328
- file.parent = group
329
-
330
- # Add the file id to the groups children
331
- group.attributes['children'] << file.id
332
-
333
- # Add the file to targets
334
- targets.each do |t|
335
- add_file_to_target file, t
189
+ Vendor.ui.debug " > #{file.path}\n\n"
190
+
191
+ resources_build_phase.add_build_file file
336
192
  end
337
-
338
- # Mark as dirty
339
- @dirty = true
340
-
341
- # Add the file to the internal index
342
- @objects_by_id[file.id] = file
343
193
  end
194
+
195
+ def add_frameworks_to_frameworks_build_phase frameworks, framework_build_phase
344
196
 
345
- def remove_file_from_target(file, target)
346
-
347
- # Search through all the build phases for references to the file
348
- build_files = []
349
- target.build_phases.each do |phase|
350
- build_files << phase.files.find_all do |build_file|
351
- build_file.attributes['fileRef'] == file.id
352
- end
197
+ unless framework_build_phase
198
+ Vendor.ui.warn "* No framework build phase exists for this target\n"
199
+ return
353
200
  end
354
201
 
355
- # Remove the build files from the references
356
- build_files.flatten.each do |build_file|
357
- build_file.parent.attributes['files'].delete build_file.id
358
- @objects_by_id.delete build_file.id
359
- end
360
-
361
- end
362
-
363
- def add_file_to_target(file, target)
364
-
365
- build_phase = build_phase_for_file(file.last_known_file_type, target)
366
-
367
- if build_phase
368
-
369
- Vendor.ui.debug "Adding #{file.attributes} to #{target.name} (build_phase = #{build_phase.class.name})"
370
-
371
- # Add the file to XCode
372
- build_file = Vendor::XCode::Proxy::PBXBuildFile.new(:project => self,
373
- :id => Vendor::XCode::Proxy::Base.generate_id,
374
- :attributes => { 'fileRef' => file.id })
375
-
376
- # Set the parent
377
- build_file.parent = build_phase
378
-
379
- # Add the file to the internal index
380
- @objects_by_id[build_file.id] = build_file
381
-
382
- # Add the file to the build phase
383
- build_phase.attributes['files'] << build_file.id
384
-
202
+ Vendor.ui.info "* Frameworks Build Phase - adding #{frameworks.count} framework(s)\n\n"
203
+
204
+ frameworks.each do |framework|
205
+
206
+ Vendor.ui.debug " > #{framework.name}\n\n"
207
+
208
+ framework_build_phase.add_build_file framework
385
209
  end
386
-
387
- end
388
-
389
- def to_ascii_plist
390
- plist = { :archiveVersion => archive_version,
391
- :classes => {},
392
- :objectVersion => object_version,
393
- :objects => @objects_by_id,
394
- :rootObject => @root_object.id }.to_ascii_plist
395
-
396
- "// !$*UTF8*$!\n" << plist
397
- end
398
-
399
- def save
400
- backup
401
- open(@pbxproject, 'w+') do |f|
402
- f << to_ascii_plist
403
- end if valid?
404
-
405
- # Not dirty anymore
406
- @dirty = false
407
210
  end
211
+
212
+ def add_build_settings_to_target_configurations target, build_settings
213
+
214
+ Vendor.ui.info "* Build Configuration Settings\n\n"
215
+
216
+ target.configs.each do |config|
217
+
218
+ Vendor.ui.debug " > #{config.name} Configuration\n\n"
219
+
220
+ build_settings.each do |name,value|
221
+
222
+ Vendor.ui.debug " > Setting `#{name}` to `#{value}`\n\n"
223
+
224
+ config.append name, value
408
225
 
409
- def backup
410
- dir = File.dirname(@project_folder)
411
- backup_name = "#{@name}.vendorbackup"
412
- backups = Dir[File.join(dir, "#{backup_name}*")].sort
413
-
414
- unless backups.empty?
415
- if backups.last.match(/([\d]+)$/)
416
- backup_name += ".#{$1.to_i + 1}"
417
- else
418
- backup_name += ".1"
419
226
  end
420
227
  end
421
-
422
- backup_to = File.join(dir, backup_name)
423
-
424
- Vendor.ui.warn "Backup created #{backup_to}"
425
- FileUtils.cp_r @project_folder, backup_to
426
- end
427
-
428
- def dirty?
429
- @dirty
430
228
  end
431
-
432
- def valid?
433
- begin
434
- # Try and parse the plist again. If it parses, then we've
435
- # got valid syntax, if it fails, it will raise a parse error. We
436
- # know we've done something bad at this point.
437
- Vendor::Plist.parse_ascii(to_ascii_plist)
438
-
439
- true
440
- rescue Vendor::Plist::AsciiParser::ParseError => e
441
- Vendor.ui.error "There was an error converting the XCode project back to a Plist"
442
- Vendor.ui.error e.inspect
443
- Vendor.ui.debug to_ascii_plist
444
-
445
- false
446
- end
447
- end
448
-
449
- private
450
-
451
- def build_phase_for_file(file_type, target)
452
- # Which build phase does this file belong?
453
- klass = case file_type
454
- when "sourcecode.c.objc", "sourcecode.c.c"
455
- Vendor::XCode::Proxy::PBXSourcesBuildPhase
456
- when "wrapper.framework"
457
- Vendor::XCode::Proxy::PBXFrameworksBuildPhase
458
- when "compiled.mach-o.dylib"
459
- Vendor::XCode::Proxy::PBXFrameworksBuildPhase
460
- end
461
-
462
- if klass
463
- # Find the build phase
464
- build_phase = target.build_phases.find { |phase| phase.kind_of?(klass) }
465
- unless build_phase
466
- Vendor.ui.error "Could not find '#{klass.name}' build phase for target '#{target.name}'"
467
- exit 1
468
- end
469
- build_phase
470
- else
471
- false
472
- end
473
- end
474
-
475
- def require_options(options, *keys)
476
- keys.each { |k| raise StandardError.new("Missing :#{k} option") unless options[k] }
477
- end
478
-
479
- def targets_from_options(options, opts = {})
480
- targets = if options[:targets]
481
- [ *options[:targets] ].map do |t|
482
- if t == :all
483
- root_object.targets
484
- else
485
- target = find_target(t)
486
- raise StandardError.new("Could not find target '#{t}' in project '#{name}'") unless target
487
- target
488
- end
489
- end.flatten.uniq
490
- else
491
- root_object.targets
492
- end
493
-
494
- if opts[:ignore_aggregates]
495
- targets.reject { |t| t.kind_of? Vendor::XCode::Proxy::PBXAggregateTarget }
496
- else
497
- targets
498
- end
499
- end
500
-
229
+
501
230
  end
502
231
 
503
232
  end