plasmo_xcodeproj 1.21.1
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.
- checksums.yaml +7 -0
- data/LICENSE +19 -0
- data/README.md +95 -0
- data/bin/xcodeproj +10 -0
- data/lib/xcodeproj/command/config_dump.rb +91 -0
- data/lib/xcodeproj/command/project_diff.rb +56 -0
- data/lib/xcodeproj/command/show.rb +60 -0
- data/lib/xcodeproj/command/sort.rb +44 -0
- data/lib/xcodeproj/command/target_diff.rb +43 -0
- data/lib/xcodeproj/command.rb +63 -0
- data/lib/xcodeproj/config/other_linker_flags_parser.rb +73 -0
- data/lib/xcodeproj/config.rb +386 -0
- data/lib/xcodeproj/constants.rb +465 -0
- data/lib/xcodeproj/differ.rb +239 -0
- data/lib/xcodeproj/gem_version.rb +5 -0
- data/lib/xcodeproj/helper.rb +30 -0
- data/lib/xcodeproj/plist.rb +94 -0
- data/lib/xcodeproj/project/case_converter.rb +90 -0
- data/lib/xcodeproj/project/object/build_configuration.rb +255 -0
- data/lib/xcodeproj/project/object/build_file.rb +84 -0
- data/lib/xcodeproj/project/object/build_phase.rb +369 -0
- data/lib/xcodeproj/project/object/build_rule.rb +109 -0
- data/lib/xcodeproj/project/object/configuration_list.rb +117 -0
- data/lib/xcodeproj/project/object/container_item_proxy.rb +116 -0
- data/lib/xcodeproj/project/object/file_reference.rb +338 -0
- data/lib/xcodeproj/project/object/group.rb +506 -0
- data/lib/xcodeproj/project/object/helpers/build_settings_array_settings_by_object_version.rb +72 -0
- data/lib/xcodeproj/project/object/helpers/file_references_factory.rb +245 -0
- data/lib/xcodeproj/project/object/helpers/groupable_helper.rb +260 -0
- data/lib/xcodeproj/project/object/native_target.rb +751 -0
- data/lib/xcodeproj/project/object/reference_proxy.rb +86 -0
- data/lib/xcodeproj/project/object/root_object.rb +100 -0
- data/lib/xcodeproj/project/object/swift_package_product_dependency.rb +29 -0
- data/lib/xcodeproj/project/object/swift_package_remote_reference.rb +33 -0
- data/lib/xcodeproj/project/object/target_dependency.rb +94 -0
- data/lib/xcodeproj/project/object.rb +534 -0
- data/lib/xcodeproj/project/object_attributes.rb +522 -0
- data/lib/xcodeproj/project/object_dictionary.rb +210 -0
- data/lib/xcodeproj/project/object_list.rb +223 -0
- data/lib/xcodeproj/project/project_helper.rb +341 -0
- data/lib/xcodeproj/project/uuid_generator.rb +132 -0
- data/lib/xcodeproj/project.rb +874 -0
- data/lib/xcodeproj/scheme/abstract_scheme_action.rb +100 -0
- data/lib/xcodeproj/scheme/analyze_action.rb +19 -0
- data/lib/xcodeproj/scheme/archive_action.rb +59 -0
- data/lib/xcodeproj/scheme/build_action.rb +298 -0
- data/lib/xcodeproj/scheme/buildable_product_runnable.rb +55 -0
- data/lib/xcodeproj/scheme/buildable_reference.rb +129 -0
- data/lib/xcodeproj/scheme/command_line_arguments.rb +162 -0
- data/lib/xcodeproj/scheme/environment_variables.rb +170 -0
- data/lib/xcodeproj/scheme/execution_action.rb +86 -0
- data/lib/xcodeproj/scheme/launch_action.rb +179 -0
- data/lib/xcodeproj/scheme/location_scenario_reference.rb +49 -0
- data/lib/xcodeproj/scheme/macro_expansion.rb +34 -0
- data/lib/xcodeproj/scheme/profile_action.rb +57 -0
- data/lib/xcodeproj/scheme/remote_runnable.rb +92 -0
- data/lib/xcodeproj/scheme/send_email_action_content.rb +84 -0
- data/lib/xcodeproj/scheme/shell_script_action_content.rb +77 -0
- data/lib/xcodeproj/scheme/test_action.rb +394 -0
- data/lib/xcodeproj/scheme/xml_element_wrapper.rb +82 -0
- data/lib/xcodeproj/scheme.rb +375 -0
- data/lib/xcodeproj/user_interface.rb +22 -0
- data/lib/xcodeproj/workspace/file_reference.rb +79 -0
- data/lib/xcodeproj/workspace/group_reference.rb +67 -0
- data/lib/xcodeproj/workspace/reference.rb +40 -0
- data/lib/xcodeproj/workspace.rb +277 -0
- data/lib/xcodeproj/xcodebuild_helper.rb +108 -0
- data/lib/xcodeproj.rb +29 -0
- metadata +208 -0
@@ -0,0 +1,375 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
require 'xcodeproj/scheme/build_action'
|
4
|
+
require 'xcodeproj/scheme/test_action'
|
5
|
+
require 'xcodeproj/scheme/launch_action'
|
6
|
+
require 'xcodeproj/scheme/profile_action'
|
7
|
+
require 'xcodeproj/scheme/analyze_action'
|
8
|
+
require 'xcodeproj/scheme/archive_action'
|
9
|
+
|
10
|
+
require 'xcodeproj/scheme/buildable_product_runnable'
|
11
|
+
require 'xcodeproj/scheme/buildable_reference'
|
12
|
+
require 'xcodeproj/scheme/location_scenario_reference'
|
13
|
+
require 'xcodeproj/scheme/execution_action'
|
14
|
+
require 'xcodeproj/scheme/macro_expansion'
|
15
|
+
require 'xcodeproj/scheme/remote_runnable'
|
16
|
+
require 'xcodeproj/scheme/send_email_action_content'
|
17
|
+
require 'xcodeproj/scheme/shell_script_action_content'
|
18
|
+
|
19
|
+
module Xcodeproj
|
20
|
+
# This class represents a Scheme document represented by a ".xcscheme" file
|
21
|
+
# usually stored in a xcuserdata or xcshareddata (for a shared scheme)
|
22
|
+
# folder.
|
23
|
+
#
|
24
|
+
class XCScheme
|
25
|
+
# @return [REXML::Document] the XML object that will be manipulated to save
|
26
|
+
# the scheme file after.
|
27
|
+
#
|
28
|
+
attr_reader :doc
|
29
|
+
|
30
|
+
# Create a XCScheme either from scratch or using an existing file
|
31
|
+
#
|
32
|
+
# @param [String] file_path
|
33
|
+
# The path of the existing .xcscheme file. If nil will create an empty scheme
|
34
|
+
#
|
35
|
+
def initialize(file_path = nil)
|
36
|
+
if file_path
|
37
|
+
@file_path = file_path
|
38
|
+
@doc = File.open(file_path, 'r') do |f|
|
39
|
+
REXML::Document.new(f)
|
40
|
+
end
|
41
|
+
@doc.context[:attribute_quote] = :quote
|
42
|
+
|
43
|
+
@scheme = @doc.elements['Scheme']
|
44
|
+
else
|
45
|
+
@doc = REXML::Document.new
|
46
|
+
@doc.context[:attribute_quote] = :quote
|
47
|
+
@doc << REXML::XMLDecl.new(REXML::XMLDecl::DEFAULT_VERSION, 'UTF-8')
|
48
|
+
|
49
|
+
@scheme = @doc.add_element 'Scheme'
|
50
|
+
@scheme.attributes['LastUpgradeVersion'] = Constants::LAST_UPGRADE_CHECK
|
51
|
+
@scheme.attributes['version'] = Xcodeproj::Constants::XCSCHEME_FORMAT_VERSION
|
52
|
+
|
53
|
+
self.build_action = BuildAction.new
|
54
|
+
self.test_action = TestAction.new
|
55
|
+
self.launch_action = LaunchAction.new
|
56
|
+
self.profile_action = ProfileAction.new
|
57
|
+
self.analyze_action = AnalyzeAction.new
|
58
|
+
self.archive_action = ArchiveAction.new
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Convenience method to quickly add app and test targets to a new scheme.
|
63
|
+
#
|
64
|
+
# It will add the runnable_target to the Build, Launch and Profile actions
|
65
|
+
# and the test_target to the Build and Test actions
|
66
|
+
#
|
67
|
+
# @param [Xcodeproj::Project::Object::PBXAbstractTarget] runnable_target
|
68
|
+
# The target to use for the 'Run', 'Profile' and 'Analyze' actions
|
69
|
+
#
|
70
|
+
# @param [Xcodeproj::Project::Object::PBXAbstractTarget] test_target
|
71
|
+
# The target to use for the 'Test' action
|
72
|
+
#
|
73
|
+
# @param [Boolean] launch_target
|
74
|
+
# Determines if the runnable_target is launchable.
|
75
|
+
#
|
76
|
+
def configure_with_targets(runnable_target, test_target, launch_target: false)
|
77
|
+
if runnable_target
|
78
|
+
add_build_target(runnable_target)
|
79
|
+
set_launch_target(runnable_target) if launch_target
|
80
|
+
end
|
81
|
+
if test_target
|
82
|
+
add_build_target(test_target, false) if test_target != runnable_target
|
83
|
+
add_test_target(test_target)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
public
|
88
|
+
|
89
|
+
# @!group Access Action nodes
|
90
|
+
|
91
|
+
# @return [XCScheme::BuildAction]
|
92
|
+
# The Build Action associated with this scheme
|
93
|
+
#
|
94
|
+
def build_action
|
95
|
+
@build_action ||= BuildAction.new(@scheme.elements['BuildAction'])
|
96
|
+
end
|
97
|
+
|
98
|
+
# @param [XCScheme::BuildAction] action
|
99
|
+
# The Build Action to associate to this scheme
|
100
|
+
#
|
101
|
+
def build_action=(action)
|
102
|
+
@scheme.delete_element('BuildAction')
|
103
|
+
@scheme.add_element(action.xml_element)
|
104
|
+
@build_action = action
|
105
|
+
end
|
106
|
+
|
107
|
+
# @return [XCScheme::TestAction]
|
108
|
+
# The Test Action associated with this scheme
|
109
|
+
#
|
110
|
+
def test_action
|
111
|
+
@test_action ||= TestAction.new(@scheme.elements['TestAction'])
|
112
|
+
end
|
113
|
+
|
114
|
+
# @param [XCScheme::TestAction] action
|
115
|
+
# The Test Action to associate to this scheme
|
116
|
+
#
|
117
|
+
def test_action=(action)
|
118
|
+
@scheme.delete_element('TestAction')
|
119
|
+
@scheme.add_element(action.xml_element)
|
120
|
+
@test_action = action
|
121
|
+
end
|
122
|
+
|
123
|
+
# @return [XCScheme::LaunchAction]
|
124
|
+
# The Launch Action associated with this scheme
|
125
|
+
#
|
126
|
+
def launch_action
|
127
|
+
@launch_action ||= LaunchAction.new(@scheme.elements['LaunchAction'])
|
128
|
+
end
|
129
|
+
|
130
|
+
# @param [XCScheme::LaunchAction] action
|
131
|
+
# The Launch Action to associate to this scheme
|
132
|
+
#
|
133
|
+
def launch_action=(action)
|
134
|
+
@scheme.delete_element('LaunchAction')
|
135
|
+
@scheme.add_element(action.xml_element)
|
136
|
+
@launch_action = action
|
137
|
+
end
|
138
|
+
|
139
|
+
# @return [XCScheme::ProfileAction]
|
140
|
+
# The Profile Action associated with this scheme
|
141
|
+
#
|
142
|
+
def profile_action
|
143
|
+
@profile_action ||= ProfileAction.new(@scheme.elements['ProfileAction'])
|
144
|
+
end
|
145
|
+
|
146
|
+
# @param [XCScheme::ProfileAction] action
|
147
|
+
# The Profile Action to associate to this scheme
|
148
|
+
#
|
149
|
+
def profile_action=(action)
|
150
|
+
@scheme.delete_element('ProfileAction')
|
151
|
+
@scheme.add_element(action.xml_element)
|
152
|
+
@profile_action = action
|
153
|
+
end
|
154
|
+
|
155
|
+
# @return [XCScheme::AnalyzeAction]
|
156
|
+
# The Analyze Action associated with this scheme
|
157
|
+
#
|
158
|
+
def analyze_action
|
159
|
+
@analyze_action ||= AnalyzeAction.new(@scheme.elements['AnalyzeAction'])
|
160
|
+
end
|
161
|
+
|
162
|
+
# @param [XCScheme::AnalyzeAction] action
|
163
|
+
# The Analyze Action to associate to this scheme
|
164
|
+
#
|
165
|
+
def analyze_action=(action)
|
166
|
+
@scheme.delete_element('AnalyzeAction')
|
167
|
+
@scheme.add_element(action.xml_element)
|
168
|
+
@analyze_action = action
|
169
|
+
end
|
170
|
+
|
171
|
+
# @return [XCScheme::ArchiveAction]
|
172
|
+
# The Archive Action associated with this scheme
|
173
|
+
#
|
174
|
+
def archive_action
|
175
|
+
@archive_action ||= ArchiveAction.new(@scheme.elements['ArchiveAction'])
|
176
|
+
end
|
177
|
+
|
178
|
+
# @param [XCScheme::ArchiveAction] action
|
179
|
+
# The Archive Action to associate to this scheme
|
180
|
+
#
|
181
|
+
def archive_action=(action)
|
182
|
+
@scheme.delete_element('ArchiveAction')
|
183
|
+
@scheme.add_element(action.xml_element)
|
184
|
+
@archive_action = action
|
185
|
+
end
|
186
|
+
|
187
|
+
# @!group Target methods
|
188
|
+
|
189
|
+
# Add a target to the list of targets to build in the build action.
|
190
|
+
#
|
191
|
+
# @param [Xcodeproj::Project::Object::AbstractTarget] build_target
|
192
|
+
# A target used by scheme in the build step.
|
193
|
+
#
|
194
|
+
# @param [Bool] build_for_running
|
195
|
+
# Whether to build this target in the launch action. Often false for test targets.
|
196
|
+
#
|
197
|
+
def add_build_target(build_target, build_for_running = true)
|
198
|
+
entry = BuildAction::Entry.new(build_target)
|
199
|
+
|
200
|
+
entry.build_for_testing = true
|
201
|
+
entry.build_for_running = build_for_running
|
202
|
+
entry.build_for_profiling = build_for_running
|
203
|
+
entry.build_for_archiving = build_for_running
|
204
|
+
entry.build_for_analyzing = build_for_running
|
205
|
+
|
206
|
+
build_action.add_entry(entry)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Add a target to the list of targets to build in the build action.
|
210
|
+
#
|
211
|
+
# @param [Xcodeproj::Project::Object::AbstractTarget] test_target
|
212
|
+
# A target used by scheme in the test step.
|
213
|
+
#
|
214
|
+
def add_test_target(test_target)
|
215
|
+
testable = TestAction::TestableReference.new(test_target)
|
216
|
+
test_action.add_testable(testable)
|
217
|
+
end
|
218
|
+
|
219
|
+
# Sets a runnable target to be the target of the launch action of the scheme.
|
220
|
+
#
|
221
|
+
# @param [Xcodeproj::Project::Object::AbstractTarget] build_target
|
222
|
+
# A target used by scheme in the launch step.
|
223
|
+
#
|
224
|
+
def set_launch_target(build_target)
|
225
|
+
launch_runnable = BuildableProductRunnable.new(build_target, 0)
|
226
|
+
launch_action.buildable_product_runnable = launch_runnable
|
227
|
+
|
228
|
+
profile_runnable = BuildableProductRunnable.new(build_target, 0)
|
229
|
+
profile_action.buildable_product_runnable = profile_runnable
|
230
|
+
|
231
|
+
macro_exp = MacroExpansion.new(build_target)
|
232
|
+
test_action.add_macro_expansion(macro_exp)
|
233
|
+
end
|
234
|
+
|
235
|
+
# @!group Class methods
|
236
|
+
|
237
|
+
#-------------------------------------------------------------------------#
|
238
|
+
|
239
|
+
# Share a User Scheme. Basically this method move the xcscheme file from
|
240
|
+
# the xcuserdata folder to xcshareddata folder.
|
241
|
+
#
|
242
|
+
# @param [String] project_path
|
243
|
+
# Path of the .xcodeproj folder.
|
244
|
+
#
|
245
|
+
# @param [String] scheme_name
|
246
|
+
# The name of scheme that will be shared.
|
247
|
+
#
|
248
|
+
# @param [String] user
|
249
|
+
# The user name that have the scheme.
|
250
|
+
#
|
251
|
+
def self.share_scheme(project_path, scheme_name, user = nil)
|
252
|
+
to_folder = shared_data_dir(project_path)
|
253
|
+
to_folder.mkpath
|
254
|
+
to = to_folder + "#{scheme_name}.xcscheme"
|
255
|
+
from = user_data_dir(project_path, user) + "#{scheme_name}.xcscheme"
|
256
|
+
FileUtils.mv(from, to)
|
257
|
+
end
|
258
|
+
|
259
|
+
# @return [Pathname]
|
260
|
+
#
|
261
|
+
def self.shared_data_dir(project_path)
|
262
|
+
project_path = Pathname.new(project_path)
|
263
|
+
project_path + 'xcshareddata/xcschemes'
|
264
|
+
end
|
265
|
+
|
266
|
+
# @return [Pathname]
|
267
|
+
#
|
268
|
+
def self.user_data_dir(project_path, user = nil)
|
269
|
+
project_path = Pathname.new(project_path)
|
270
|
+
user ||= ENV['USER']
|
271
|
+
project_path + "xcuserdata/#{user}.xcuserdatad/xcschemes"
|
272
|
+
end
|
273
|
+
|
274
|
+
public
|
275
|
+
|
276
|
+
# @!group Serialization
|
277
|
+
|
278
|
+
#-------------------------------------------------------------------------#
|
279
|
+
|
280
|
+
# Serializes the current state of the object to a String.
|
281
|
+
#
|
282
|
+
# @note The goal of the string representation is to match Xcode output as
|
283
|
+
# close as possible to aide comparison.
|
284
|
+
#
|
285
|
+
# @return [String] the XML string value of the current state of the object.
|
286
|
+
#
|
287
|
+
def to_s
|
288
|
+
formatter = XMLFormatter.new(2)
|
289
|
+
formatter.compact = false
|
290
|
+
out = ''
|
291
|
+
formatter.write(@doc, out)
|
292
|
+
out.gsub!("<?xml version='1.0' encoding='UTF-8'?>", '<?xml version="1.0" encoding="UTF-8"?>')
|
293
|
+
out << "\n"
|
294
|
+
out
|
295
|
+
end
|
296
|
+
|
297
|
+
# Serializes the current state of the object to a ".xcscheme" file.
|
298
|
+
#
|
299
|
+
# @param [String, Pathname] project_path
|
300
|
+
# The path where the ".xcscheme" file should be stored.
|
301
|
+
#
|
302
|
+
# @param [String] name
|
303
|
+
# The name of the scheme, to have ".xcscheme" appended.
|
304
|
+
#
|
305
|
+
# @param [Boolean] shared
|
306
|
+
# true => if the scheme must be a shared scheme (default value)
|
307
|
+
# false => if the scheme must be a user scheme
|
308
|
+
#
|
309
|
+
# @return [void]
|
310
|
+
#
|
311
|
+
# @example Saving a scheme
|
312
|
+
# scheme.save_as('path/to/Project.xcodeproj') #=> true
|
313
|
+
#
|
314
|
+
def save_as(project_path, name, shared = true)
|
315
|
+
scheme_folder_path = if shared
|
316
|
+
self.class.shared_data_dir(project_path)
|
317
|
+
else
|
318
|
+
self.class.user_data_dir(project_path)
|
319
|
+
end
|
320
|
+
scheme_folder_path.mkpath
|
321
|
+
scheme_path = scheme_folder_path + "#{name}.xcscheme"
|
322
|
+
@file_path = scheme_path
|
323
|
+
File.open(scheme_path, 'w') do |f|
|
324
|
+
f.write(to_s)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
# Serializes the current state of the object to the original ".xcscheme"
|
329
|
+
# file this XCScheme was created from, overriding the original file.
|
330
|
+
#
|
331
|
+
# Requires that the XCScheme object was initialized using a file path.
|
332
|
+
#
|
333
|
+
def save!
|
334
|
+
raise Informative, 'This XCScheme object was not initialized ' \
|
335
|
+
'using a file path. Use save_as instead.' unless @file_path
|
336
|
+
File.open(@file_path, 'w') do |f|
|
337
|
+
f.write(to_s)
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
#-------------------------------------------------------------------------#
|
342
|
+
|
343
|
+
# XML formatter which closely mimics the output generated by Xcode.
|
344
|
+
#
|
345
|
+
class XMLFormatter < REXML::Formatters::Pretty
|
346
|
+
def write_element(node, output)
|
347
|
+
@indentation = 3
|
348
|
+
output << ' ' * @level
|
349
|
+
output << "<#{node.expanded_name}"
|
350
|
+
|
351
|
+
@level += @indentation
|
352
|
+
node.context = node.parent.context # HACK: to ensure strings are properly quoted
|
353
|
+
node.attributes.each_attribute do |attr|
|
354
|
+
output << "\n"
|
355
|
+
output << ' ' * @level
|
356
|
+
output << attr.to_string.sub(/=/, ' = ')
|
357
|
+
end unless node.attributes.empty?
|
358
|
+
|
359
|
+
output << '>'
|
360
|
+
|
361
|
+
output << "\n"
|
362
|
+
node.children.each do |child|
|
363
|
+
next if child.is_a?(REXML::Text) && child.to_s.strip.length == 0
|
364
|
+
write(child, output)
|
365
|
+
output << "\n"
|
366
|
+
end
|
367
|
+
@level -= @indentation
|
368
|
+
output << ' ' * @level
|
369
|
+
output << "</#{node.expanded_name}>"
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
#-------------------------------------------------------------------------#
|
374
|
+
end
|
375
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
# Manages the UI output so clients can customize it.
|
3
|
+
#
|
4
|
+
module UserInterface
|
5
|
+
# Prints a message to standard output.
|
6
|
+
#
|
7
|
+
# @return [void]
|
8
|
+
#
|
9
|
+
def self.puts(message)
|
10
|
+
STDOUT.puts message
|
11
|
+
end
|
12
|
+
|
13
|
+
# Prints a message to standard error.
|
14
|
+
#
|
15
|
+
# @return [void]
|
16
|
+
#
|
17
|
+
def self.warn(message)
|
18
|
+
STDERR.puts message
|
19
|
+
end
|
20
|
+
end
|
21
|
+
UI = UserInterface
|
22
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'xcodeproj/workspace/reference'
|
2
|
+
|
3
|
+
module Xcodeproj
|
4
|
+
class Workspace
|
5
|
+
# Describes a file reference of a Workspace.
|
6
|
+
#
|
7
|
+
class FileReference < Reference
|
8
|
+
# @return [String] the path to the project
|
9
|
+
#
|
10
|
+
attr_reader :path
|
11
|
+
|
12
|
+
# @param [#to_s] path @see path
|
13
|
+
# @param [#to_s] type @see type
|
14
|
+
#
|
15
|
+
def initialize(path, type = 'group')
|
16
|
+
@path = Pathname.new(path.to_s).cleanpath.to_s
|
17
|
+
@type = type.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Bool] Wether a file reference is equal to another.
|
21
|
+
#
|
22
|
+
def ==(other)
|
23
|
+
path == other.path && type == other.type
|
24
|
+
end
|
25
|
+
alias_method :eql?, :==
|
26
|
+
|
27
|
+
# @return [Fixnum] A hash identical for equals objects.
|
28
|
+
#
|
29
|
+
def hash
|
30
|
+
[path, type].hash
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns a file reference given XML representation.
|
34
|
+
#
|
35
|
+
# @param [REXML::Element] xml_node
|
36
|
+
# the XML representation.
|
37
|
+
#
|
38
|
+
# @return [FileReference] The new file reference instance.
|
39
|
+
#
|
40
|
+
def self.from_node(xml_node)
|
41
|
+
type, path = xml_node.attribute('location').value.split(':', 2)
|
42
|
+
if type == 'group'
|
43
|
+
path = prepend_parent_path(xml_node, path)
|
44
|
+
end
|
45
|
+
new(path, type)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [REXML::Element] the XML representation of the file reference.
|
49
|
+
#
|
50
|
+
def to_node
|
51
|
+
REXML::Element.new('FileRef').tap do |element|
|
52
|
+
element.add_attribute('location', "#{type}:#{path}")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns the absolute path of a file reference given the path of the
|
57
|
+
# directory containing workspace.
|
58
|
+
#
|
59
|
+
# @param [#to_s] workspace_dir_path
|
60
|
+
# The Path of the directory containing the workspace.
|
61
|
+
#
|
62
|
+
# @return [String] The absolute path to the project.
|
63
|
+
#
|
64
|
+
def absolute_path(workspace_dir_path)
|
65
|
+
workspace_dir_path = workspace_dir_path.to_s
|
66
|
+
case type
|
67
|
+
when 'group', 'container', 'self'
|
68
|
+
File.expand_path(File.join(workspace_dir_path, path))
|
69
|
+
when 'absolute'
|
70
|
+
File.expand_path(path)
|
71
|
+
when 'developer'
|
72
|
+
raise "Developer workspace file reference type is not yet supported (#{path})"
|
73
|
+
else
|
74
|
+
raise "Unsupported workspace file reference type `#{type}`"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'xcodeproj/workspace/reference'
|
2
|
+
|
3
|
+
module Xcodeproj
|
4
|
+
class Workspace
|
5
|
+
# Describes a group reference of a Workspace.
|
6
|
+
#
|
7
|
+
class GroupReference < Reference
|
8
|
+
# @return [String] the name of the group
|
9
|
+
#
|
10
|
+
attr_reader :name
|
11
|
+
|
12
|
+
# @return [String] the location of the group on disk
|
13
|
+
#
|
14
|
+
attr_reader :location
|
15
|
+
|
16
|
+
# @param [#to_s] name @see name
|
17
|
+
# @param [#to_s] type @see type
|
18
|
+
# @param [#to_s] location @see location
|
19
|
+
#
|
20
|
+
def initialize(name, type = 'container', location = '')
|
21
|
+
@name = name.to_s
|
22
|
+
@type = type.to_s
|
23
|
+
@location = location.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Bool] Whether a group reference is equal to another.
|
27
|
+
#
|
28
|
+
def ==(other)
|
29
|
+
name == other.name && type == other.type && location == other.location
|
30
|
+
end
|
31
|
+
alias_method :eql?, :==
|
32
|
+
|
33
|
+
# @return [Fixnum] A hash identical for equals objects.
|
34
|
+
#
|
35
|
+
def hash
|
36
|
+
[name, type, location].hash
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns a group reference given XML representation.
|
40
|
+
#
|
41
|
+
# @param [REXML::Element] xml_node
|
42
|
+
# the XML representation.
|
43
|
+
#
|
44
|
+
# @return [GroupReference] The new group reference instance.
|
45
|
+
#
|
46
|
+
def self.from_node(xml_node)
|
47
|
+
location_array = xml_node.attribute('location').value.split(':', 2)
|
48
|
+
type = location_array.first
|
49
|
+
location = location_array[1] || ''
|
50
|
+
if type == 'group'
|
51
|
+
location = prepend_parent_path(xml_node, location)
|
52
|
+
end
|
53
|
+
name = xml_node.attribute('name').value
|
54
|
+
new(name, type, location)
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [REXML::Element] the XML representation of the group reference.
|
58
|
+
#
|
59
|
+
def to_node
|
60
|
+
REXML::Element.new('Group').tap do |element|
|
61
|
+
element.add_attribute('location', "#{type}:#{location}")
|
62
|
+
element.add_attribute('name', "#{name}")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
class Workspace
|
3
|
+
# Describes a file/group reference of a Workspace.
|
4
|
+
#
|
5
|
+
class Reference
|
6
|
+
# @return [String] the type of reference to the project
|
7
|
+
#
|
8
|
+
# This can be of the following values:
|
9
|
+
# - absolute
|
10
|
+
# - group
|
11
|
+
# - container
|
12
|
+
# - developer (unsupported)
|
13
|
+
#
|
14
|
+
attr_reader :type
|
15
|
+
|
16
|
+
# Returns the relative path to the parent group reference (if one exists)
|
17
|
+
# prepended to the passed in path.
|
18
|
+
#
|
19
|
+
# @param [REXML::Element] xml_node
|
20
|
+
# the XML representation.
|
21
|
+
#
|
22
|
+
# @param [String] path
|
23
|
+
# the path that will be prepended to.
|
24
|
+
#
|
25
|
+
# @return [String] the extended path including the parent node's path.
|
26
|
+
#
|
27
|
+
def self.prepend_parent_path(xml_node, path)
|
28
|
+
if !xml_node.parent.nil? && (xml_node.parent.name == 'Group')
|
29
|
+
group = GroupReference.from_node(xml_node.parent)
|
30
|
+
if !group.location.nil? && !group.location.empty?
|
31
|
+
path = '' if path.nil?
|
32
|
+
path = File.join(group.location, path)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
path
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|