vendor 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/LICENSE +1 -1
- data/Readme.markdown +2 -1
- data/VERSION +1 -1
- data/lib/vendor/cli/app.rb +13 -17
- data/lib/vendor/spec.rb +244 -55
- data/lib/vendor/vendor_file/library/base.rb +43 -63
- data/lib/vendor/vendor_file/loader.rb +8 -0
- data/lib/vendor/vendor_spec/builder.rb +19 -8
- data/lib/vendor/xcode.rb +0 -1
- data/lib/vendor/xcode/project.rb +198 -469
- data/spec/lib/vendor/spec_spec.rb +34 -10
- data/spec/lib/vendor/vendor_file/library/base_spec.rb +41 -49
- data/spec/lib/vendor/vendor_spec/builder_spec.rb +26 -0
- data/spec/support/resources/cache/base/DKBenchmark-0.1-Manifest/vendor.json +1 -1
- data/spec/support/resources/cache/base/DKBenchmark-0.1-Vendorspec/DKBenchmark.vendorspec +2 -0
- data/spec/support/resources/vendors/DKBenchmark/DKBenchmark.vendorspec +2 -0
- data/spec/support/resources/vendors/DKBenchmarkFramework/DKBenchmark.framework/DKBenchmark +0 -0
- data/spec/support/resources/vendors/DKBenchmarkFramework/DKBenchmark.framework/Versions/A/DKBenchmark +0 -0
- data/spec/support/resources/vendors/DKBenchmarkFramework/DKBenchmark.framework/Versions/A/Headers/DKBenchmark.h +18 -0
- data/spec/support/resources/vendors/DKBenchmarkFramework/DKBenchmark.vendorspec +23 -0
- data/vendor.gemspec +1 -0
- metadata +111 -63
- data/lib/vendor/xcode/proxy.rb +0 -31
- data/lib/vendor/xcode/proxy/base.rb +0 -129
- data/lib/vendor/xcode/proxy/pbx_aggregate_target.rb +0 -11
- data/lib/vendor/xcode/proxy/pbx_build_file.rb +0 -9
- data/lib/vendor/xcode/proxy/pbx_container_item_proxy.rb +0 -8
- data/lib/vendor/xcode/proxy/pbx_file_reference.rb +0 -41
- data/lib/vendor/xcode/proxy/pbx_frameworks_build_phase.rb +0 -15
- data/lib/vendor/xcode/proxy/pbx_group.rb +0 -35
- data/lib/vendor/xcode/proxy/pbx_native_target.rb +0 -11
- data/lib/vendor/xcode/proxy/pbx_project.rb +0 -12
- data/lib/vendor/xcode/proxy/pbx_reference_proxy.rb +0 -7
- data/lib/vendor/xcode/proxy/pbx_resources_build_phase.rb +0 -15
- data/lib/vendor/xcode/proxy/pbx_shell_script_build_phase.rb +0 -15
- data/lib/vendor/xcode/proxy/pbx_sources_build_phase.rb +0 -15
- data/lib/vendor/xcode/proxy/pbx_target_dependency.rb +0 -7
- data/lib/vendor/xcode/proxy/pbx_variant_group.rb +0 -7
- data/lib/vendor/xcode/proxy/unknown.rb +0 -8
- data/lib/vendor/xcode/proxy/xc_build_configuration.rb +0 -7
- data/lib/vendor/xcode/proxy/xc_configuration_list.rb +0 -9
- data/lib/vendor/xcode/proxy/xc_version_group.rb +0 -7
- data/spec/lib/vendor/xcode/project_spec.rb +0 -635
- data/spec/lib/vendor/xcode/proxy/base_spec.rb +0 -88
- data/spec/lib/vendor/xcode/proxy/pbx_file_reference_spec.rb +0 -26
- data/spec/lib/vendor/xcode/proxy/pbx_group_spec.rb +0 -27
- 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
|
-
|
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
|
-
|
61
|
-
|
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.
|
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(/^\//, '')
|
data/lib/vendor/xcode.rb
CHANGED
data/lib/vendor/xcode/project.rb
CHANGED
@@ -1,503 +1,232 @@
|
|
1
|
-
require '
|
1
|
+
require 'xcoder'
|
2
2
|
|
3
3
|
module Vendor::XCode
|
4
4
|
|
5
5
|
class Project
|
6
6
|
|
7
|
-
|
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
|
-
@
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
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
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
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
|
-
|
251
|
-
|
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
|
-
|
262
|
-
|
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
|
-
|
272
|
-
|
273
|
-
|
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
|
-
|
346
|
-
|
347
|
-
|
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
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
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
|