xcodeproj 0.4.3 → 0.5.0
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/ext/xcodeproj/xcodeproj_ext.c +1 -1
- data/lib/xcodeproj.rb +9 -7
- data/lib/xcodeproj/command/project_diff.rb +7 -7
- data/lib/xcodeproj/command/show.rb +11 -2
- data/lib/xcodeproj/config.rb +102 -38
- data/lib/xcodeproj/constants.rb +16 -14
- data/lib/xcodeproj/differ.rb +243 -0
- data/lib/xcodeproj/helper.rb +1 -0
- data/lib/xcodeproj/project.rb +92 -68
- data/lib/xcodeproj/project/object.rb +32 -9
- data/lib/xcodeproj/project/object/build_configuration.rb +21 -1
- data/lib/xcodeproj/project/object/build_file.rb +40 -6
- data/lib/xcodeproj/project/object/build_phase.rb +96 -84
- data/lib/xcodeproj/project/object/build_rule.rb +14 -8
- data/lib/xcodeproj/project/object/configuration_list.rb +7 -3
- data/lib/xcodeproj/project/object/container_item_proxy.rb +31 -29
- data/lib/xcodeproj/project/object/file_reference.rb +33 -20
- data/lib/xcodeproj/project/object/group.rb +58 -35
- data/lib/xcodeproj/project/object/native_target.rb +132 -108
- data/lib/xcodeproj/project/object/reference_proxy.rb +7 -3
- data/lib/xcodeproj/project/object/root_object.rb +4 -4
- data/lib/xcodeproj/project/object_attributes.rb +9 -6
- data/lib/xcodeproj/user_interface.rb +26 -0
- data/lib/xcodeproj/workspace.rb +23 -19
- metadata +4 -3
- data/lib/xcodeproj/project/recursive_diff.rb +0 -116
data/lib/xcodeproj/helper.rb
CHANGED
@@ -16,6 +16,7 @@ module Xcodeproj
|
|
16
16
|
# @return [Array<PBXBuildFile>] A list of source files (that will be
|
17
17
|
# compiled) which are in ‘target 2’ but not in ‘target 1’. The list is
|
18
18
|
# sorted by file path.
|
19
|
+
#
|
19
20
|
def new_source_build_files
|
20
21
|
@target2.source_build_phase.files.reject do |target2_build_file|
|
21
22
|
@target1.source_build_phase.files.any? do |target1_build_file|
|
data/lib/xcodeproj/project.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'pathname'
|
3
3
|
require 'xcodeproj/xcodeproj_ext'
|
4
|
-
|
5
4
|
require 'xcodeproj/project/object'
|
6
|
-
require 'xcodeproj/project/recursive_diff'
|
7
5
|
|
8
6
|
module Xcodeproj
|
9
7
|
|
@@ -55,7 +53,7 @@ module Xcodeproj
|
|
55
53
|
attr_reader :object_version
|
56
54
|
|
57
55
|
# @return [Hash{String => AbstractObject}] A hash containing all the
|
58
|
-
#
|
56
|
+
# objects of the project by UUID.
|
59
57
|
#
|
60
58
|
attr_reader :objects_by_uuid
|
61
59
|
|
@@ -66,15 +64,16 @@ module Xcodeproj
|
|
66
64
|
# Creates a new Project instance or initializes one with the data of an
|
67
65
|
# existing Xcode document.
|
68
66
|
#
|
69
|
-
# @param
|
70
|
-
#
|
67
|
+
# @param [Pathname, String] xcodeproj
|
68
|
+
# The path to the Xcode project document (xcodeproj).
|
71
69
|
#
|
72
|
-
# @raise
|
73
|
-
#
|
74
|
-
#
|
70
|
+
# @raise If the project versions are more recent than the ones know to
|
71
|
+
# Xcodeproj to prevent it from corrupting existing projects.
|
72
|
+
# Naturally, this would never happen with a project generated by
|
73
|
+
# xcodeproj itself.
|
75
74
|
#
|
76
|
-
# @raise
|
77
|
-
#
|
75
|
+
# @raise If it can't find the root object. This means that the project is
|
76
|
+
# malformed.
|
78
77
|
#
|
79
78
|
# @example Opening a project
|
80
79
|
# Project.new("path/to/Project.xcodeproj")
|
@@ -95,7 +94,7 @@ module Xcodeproj
|
|
95
94
|
root_object_uuid = plist['rootObject']
|
96
95
|
@root_object = new_from_plist(root_object_uuid, plist['objects'], self)
|
97
96
|
|
98
|
-
|
97
|
+
if (@archive_version.to_i > Constants::LAST_KNOWN_ARCHIVE_VERSION || @object_version.to_i > Constants::LAST_KNOWN_OBJECT_VERSION)
|
99
98
|
raise '[Xcodeproj] Unknown archive or object version.'
|
100
99
|
end
|
101
100
|
|
@@ -131,7 +130,7 @@ module Xcodeproj
|
|
131
130
|
|
132
131
|
# Compares the project to another one, or to a plist representation.
|
133
132
|
#
|
134
|
-
# @param
|
133
|
+
# @param [#to_hash] other the object to compare.
|
135
134
|
#
|
136
135
|
# @return [Boolean] whether the project is equivalent to the given object.
|
137
136
|
#
|
@@ -145,7 +144,9 @@ module Xcodeproj
|
|
145
144
|
|
146
145
|
alias :inspect :to_s
|
147
146
|
|
147
|
+
#-------------------------------------------------------------------------#
|
148
148
|
|
149
|
+
public
|
149
150
|
|
150
151
|
# @!group Plist serialization
|
151
152
|
|
@@ -154,26 +155,26 @@ module Xcodeproj
|
|
154
155
|
# The method sets up any relationship of the new object, generating the
|
155
156
|
# destination object(s) if not already present in the project.
|
156
157
|
#
|
157
|
-
# @note
|
158
|
-
#
|
159
|
-
#
|
160
|
-
#
|
161
|
-
#
|
162
|
-
# @visibility private.
|
158
|
+
# @note This method is used to generate the root object
|
159
|
+
# from a plist. Subsequent invocation are called by the
|
160
|
+
# {AbstractObject#configure_with_plist}. Clients of {Xcodeproj} are
|
161
|
+
# not expected to call this method.
|
163
162
|
#
|
164
|
-
# @param
|
165
|
-
#
|
163
|
+
# @param [String] uuid
|
164
|
+
# The UUID of the object that needs to be generated.
|
166
165
|
#
|
167
|
-
# @param
|
168
|
-
#
|
166
|
+
# @param [Hash {String => Hash}] objects_by_uuid_plist
|
167
|
+
# The `objects` hash of the plist representation of the project.
|
169
168
|
#
|
170
|
-
# @param
|
171
|
-
#
|
172
|
-
#
|
173
|
-
#
|
169
|
+
# @param [Boolean] root_object
|
170
|
+
# Whether the requested object is the root object and needs to be
|
171
|
+
# retained by the project before configuration to add it to the
|
172
|
+
# `objects` hash and avoid infinite loops.
|
174
173
|
#
|
175
174
|
# @return [AbstractObject] the new object.
|
176
175
|
#
|
176
|
+
# @visibility private.
|
177
|
+
#
|
177
178
|
def new_from_plist(uuid, objects_by_uuid_plist, root_object = false)
|
178
179
|
attributes = objects_by_uuid_plist[uuid]
|
179
180
|
if attributes
|
@@ -202,16 +203,16 @@ module Xcodeproj
|
|
202
203
|
alias :to_plist :to_hash
|
203
204
|
|
204
205
|
# Converts the objects tree to a hash substituting the hash
|
205
|
-
# of the referenced to their
|
206
|
-
# object might appear multiple times and the information about their
|
206
|
+
# of the referenced to their UUID reference. As a consequence the hash of
|
207
|
+
# an object might appear multiple times and the information about their
|
207
208
|
# uniqueness is lost.
|
208
209
|
#
|
209
|
-
# This method is designed to work in
|
210
|
-
# to
|
211
|
-
#
|
210
|
+
# This method is designed to work in conjunction with {Hash#recursive_diff}
|
211
|
+
# to provide a complete, yet readable, diff of two projects *not* affected
|
212
|
+
# by differences in UUIDs.
|
212
213
|
#
|
213
|
-
# @return [Hash] a hash
|
214
|
-
#
|
214
|
+
# @return [Hash] a hash representation of the project different from the
|
215
|
+
# plist one.
|
215
216
|
#
|
216
217
|
def to_tree_hash
|
217
218
|
hash = {}
|
@@ -224,16 +225,28 @@ module Xcodeproj
|
|
224
225
|
hash
|
225
226
|
end
|
226
227
|
|
228
|
+
# @return [Hash{String => Hash}] A hash suitable to display the project
|
229
|
+
# to the user.
|
230
|
+
#
|
231
|
+
def pretty_print
|
232
|
+
build_configurations = root_object.build_configuration_list.build_configurations
|
233
|
+
{
|
234
|
+
'File References' => root_object.main_group.pretty_print.values.first,
|
235
|
+
'Targets' => root_object.targets.map(&:pretty_print),
|
236
|
+
'Build Configurations' => build_configurations.map(&:pretty_print)
|
237
|
+
}
|
238
|
+
end
|
239
|
+
|
227
240
|
# Serializes the internal data as a property list and stores it on disk at
|
228
241
|
# the given path (`xcodeproj` file).
|
229
242
|
#
|
230
243
|
# @example Saving a project
|
231
244
|
# project.save_as("path/to/Project.xcodeproj") #=> true
|
232
245
|
#
|
233
|
-
# @param
|
234
|
-
#
|
246
|
+
# @param [String, Pathname] projpath
|
247
|
+
# The path where the data should be stored.
|
235
248
|
#
|
236
|
-
# @return [Boolean]
|
249
|
+
# @return [Boolean] Whether or not saving was successful.
|
237
250
|
#
|
238
251
|
def save_as(projpath)
|
239
252
|
projpath = projpath.to_s
|
@@ -241,7 +254,9 @@ module Xcodeproj
|
|
241
254
|
Xcodeproj.write_plist(to_plist, File.join(projpath, 'project.pbxproj'))
|
242
255
|
end
|
243
256
|
|
257
|
+
#-------------------------------------------------------------------------#
|
244
258
|
|
259
|
+
public
|
245
260
|
|
246
261
|
# @!group Creating objects
|
247
262
|
|
@@ -251,8 +266,8 @@ module Xcodeproj
|
|
251
266
|
# attributes, for this reason it is better to use the convenience methods
|
252
267
|
# offered by the {AbstractObject} subclasses or by this class.
|
253
268
|
#
|
254
|
-
# @param
|
255
|
-
#
|
269
|
+
# @param [Class] klass
|
270
|
+
# The concrete subclass of AbstractObject for new object.
|
256
271
|
#
|
257
272
|
# @return [AbstractObject] the new object.
|
258
273
|
#
|
@@ -264,13 +279,13 @@ module Xcodeproj
|
|
264
279
|
|
265
280
|
# Generates a UUID unique for the project.
|
266
281
|
#
|
267
|
-
# @note
|
268
|
-
#
|
282
|
+
# @note UUIDs are not guaranteed to be generated unique because we need
|
283
|
+
# to trim the ones generated in the xcodeproj extension.
|
269
284
|
#
|
270
|
-
# @note
|
271
|
-
#
|
272
|
-
#
|
273
|
-
#
|
285
|
+
# @note Implementation detail: as objects usually are created serially
|
286
|
+
# this method creates a batch of UUID and stores the not colliding
|
287
|
+
# ones, so the search for collisions with known UUIDS (a
|
288
|
+
# performance bottleneck) is performed is performed less often.
|
274
289
|
#
|
275
290
|
# @return [String] A UUID unique to the project.
|
276
291
|
#
|
@@ -283,9 +298,9 @@ module Xcodeproj
|
|
283
298
|
|
284
299
|
# @return [Array<String>] the list of all the generated UUIDs.
|
285
300
|
#
|
286
|
-
# Used for checking new UUIDs for duplicates with UUIDs already
|
287
|
-
#
|
288
|
-
#
|
301
|
+
# @note Used for checking new UUIDs for duplicates with UUIDs already
|
302
|
+
# generated but used for objects which are not yet part of the
|
303
|
+
# `objects` hash but which might be added at a later time.
|
289
304
|
#
|
290
305
|
attr_reader :generated_uuids
|
291
306
|
|
@@ -293,12 +308,12 @@ module Xcodeproj
|
|
293
308
|
# performance when the rough number of objects that will be created is
|
294
309
|
# known in advance.
|
295
310
|
#
|
296
|
-
# @param
|
297
|
-
#
|
311
|
+
# @param [Integer] count
|
312
|
+
# the number of UUIDs that should be generated.
|
298
313
|
#
|
299
|
-
# @note
|
300
|
-
#
|
301
|
-
#
|
314
|
+
# @note This method might generated a minor number of uniques UUIDs than
|
315
|
+
# the given count, because some might be duplicated a thus will be
|
316
|
+
# discarded.
|
302
317
|
#
|
303
318
|
# @return [void]
|
304
319
|
#
|
@@ -311,6 +326,8 @@ module Xcodeproj
|
|
311
326
|
|
312
327
|
#-------------------------------------------------------------------------#
|
313
328
|
|
329
|
+
public
|
330
|
+
|
314
331
|
# @!group Convenience accessors
|
315
332
|
|
316
333
|
# @return [Array<AbstractObject>] all the objects of the project.
|
@@ -326,7 +343,7 @@ module Xcodeproj
|
|
326
343
|
end
|
327
344
|
|
328
345
|
# @return [Array<AbstractObject>] all the objects of the project with a
|
329
|
-
#
|
346
|
+
# given ISA.
|
330
347
|
#
|
331
348
|
def list_by_class(klass)
|
332
349
|
objects.select { |o| o.class == klass }
|
@@ -339,7 +356,7 @@ module Xcodeproj
|
|
339
356
|
end
|
340
357
|
|
341
358
|
# @return [ObjectList<PBXGroup>] a list of all the groups in the
|
342
|
-
#
|
359
|
+
# project.
|
343
360
|
#
|
344
361
|
def groups
|
345
362
|
main_group.groups
|
@@ -352,7 +369,7 @@ module Xcodeproj
|
|
352
369
|
# frameworks.name #=> 'Frameworks'
|
353
370
|
# main_group.children.include? frameworks #=> True
|
354
371
|
#
|
355
|
-
# @param
|
372
|
+
# @param [String] group_path @see MobileCoreServices
|
356
373
|
#
|
357
374
|
# @return [PBXGroup] the group at the given subpath.
|
358
375
|
#
|
@@ -361,14 +378,14 @@ module Xcodeproj
|
|
361
378
|
end
|
362
379
|
|
363
380
|
# @return [ObjectList<PBXFileReference>] a list of all the files in the
|
364
|
-
#
|
381
|
+
# project.
|
365
382
|
#
|
366
383
|
def files
|
367
384
|
objects.select { |obj| obj.class == PBXFileReference }
|
368
385
|
end
|
369
386
|
|
370
387
|
# @return [ObjectList<PBXNativeTarget>] A list of all the targets in the
|
371
|
-
#
|
388
|
+
# project.
|
372
389
|
#
|
373
390
|
def targets
|
374
391
|
root_object.targets
|
@@ -381,7 +398,7 @@ module Xcodeproj
|
|
381
398
|
end
|
382
399
|
|
383
400
|
# @return [ObjectList<PBXFileReference>] A list of the product file
|
384
|
-
#
|
401
|
+
# references.
|
385
402
|
#
|
386
403
|
def products
|
387
404
|
products_group.children
|
@@ -394,28 +411,33 @@ module Xcodeproj
|
|
394
411
|
end
|
395
412
|
|
396
413
|
# @return [ObjectList<XCBuildConfiguration>] A list of project wide
|
397
|
-
#
|
414
|
+
# build configurations.
|
398
415
|
#
|
399
416
|
def build_configurations
|
400
417
|
root_object.build_configuration_list.build_configurations
|
401
418
|
end
|
402
419
|
|
403
|
-
#
|
420
|
+
# Returns the build settings of the project wide build configuration with
|
421
|
+
# the given name.
|
422
|
+
#
|
423
|
+
# @param [String] name
|
424
|
+
# The name of a project wide build configuration.
|
404
425
|
#
|
405
|
-
# @return [Hash]
|
406
|
-
# configuration with the given name.
|
426
|
+
# @return [Hash] The build settings.
|
407
427
|
#
|
408
428
|
def build_settings(name)
|
409
429
|
root_object.build_configuration_list.build_settings(name)
|
410
430
|
end
|
411
431
|
|
432
|
+
#-------------------------------------------------------------------------#
|
412
433
|
|
434
|
+
public
|
413
435
|
|
414
436
|
# @!group Helpers for generating objects
|
415
437
|
|
416
438
|
# Creates a new file reference at the given subpath of the main group.
|
417
439
|
#
|
418
|
-
# @param
|
440
|
+
# @param @see PBXGroup#new_file
|
419
441
|
#
|
420
442
|
# @return [PBXFileReference] the new file.
|
421
443
|
#
|
@@ -425,7 +447,7 @@ module Xcodeproj
|
|
425
447
|
|
426
448
|
# Creates a new group at the given subpath of the main group.
|
427
449
|
#
|
428
|
-
# @param
|
450
|
+
# @param @see PBXGroup#new_group
|
429
451
|
#
|
430
452
|
# @return [PBXGroup] the new group.
|
431
453
|
#
|
@@ -440,11 +462,11 @@ module Xcodeproj
|
|
440
462
|
#
|
441
463
|
# @example Adding QuartzCore
|
442
464
|
#
|
443
|
-
#
|
465
|
+
# framework = project.add_system_framework('QuartzCore', :ios)
|
444
466
|
#
|
445
|
-
#
|
446
|
-
#
|
447
|
-
#
|
467
|
+
# target = project.targets.first
|
468
|
+
# build_phase = target.frameworks_build_phases.first
|
469
|
+
# build_phase.files << framework.buildFiles.new
|
448
470
|
#
|
449
471
|
# @param [String] name
|
450
472
|
# The name of a framework.
|
@@ -599,5 +621,7 @@ module Xcodeproj
|
|
599
621
|
settings
|
600
622
|
end
|
601
623
|
|
624
|
+
#-------------------------------------------------------------------------#
|
625
|
+
|
602
626
|
end
|
603
627
|
end
|
@@ -113,10 +113,16 @@ module Xcodeproj
|
|
113
113
|
# @return [String] a name for the object.
|
114
114
|
#
|
115
115
|
def display_name
|
116
|
-
|
117
|
-
|
116
|
+
declared_name = name if self.respond_to?(:name)
|
117
|
+
if declared_name && !declared_name.empty?
|
118
|
+
declared_name
|
119
|
+
else
|
120
|
+
isa.gsub(/^(PBX|XC)/, '')
|
121
|
+
end
|
118
122
|
end
|
119
123
|
|
124
|
+
alias :to_s :display_name
|
125
|
+
|
120
126
|
# @!group Reference counting
|
121
127
|
|
122
128
|
# @return [Array<ObjectList>] The list of the objects that have a
|
@@ -179,6 +185,8 @@ module Xcodeproj
|
|
179
185
|
|
180
186
|
#---------------------------------------------------------------------#
|
181
187
|
|
188
|
+
public
|
189
|
+
|
182
190
|
# @!group Plist related methods
|
183
191
|
|
184
192
|
# Configures the object with the objects hash from a plist.
|
@@ -265,13 +273,13 @@ module Xcodeproj
|
|
265
273
|
#
|
266
274
|
def object_with_uuid(uuid, objects_by_uuid_plist, attribute)
|
267
275
|
unless object = project.objects_by_uuid[uuid] || project.new_from_plist(uuid, objects_by_uuid_plist)
|
268
|
-
|
276
|
+
UI.warn "`#{inspect}` attempted to initialize an object with " \
|
269
277
|
"an unknown UUID. `#{uuid}` for attribute: `#{attribute.name}`."\
|
270
|
-
" This can be the result of a merge and the
|
278
|
+
" This can be the result of a merge and the unknown UUID is " \
|
271
279
|
"being discarded."
|
272
280
|
end
|
273
281
|
object
|
274
|
-
rescue NameError
|
282
|
+
rescue NameError
|
275
283
|
attributes = objects_by_uuid_plist[uuid]
|
276
284
|
raise "`#{isa}` attempted to initialize an object with unknown ISA "\
|
277
285
|
"`#{attributes['isa']}` from attributes: `#{attributes}`\n" \
|
@@ -325,7 +333,7 @@ module Xcodeproj
|
|
325
333
|
#
|
326
334
|
def to_tree_hash
|
327
335
|
hash = {}
|
328
|
-
hash['displayName'] = display_name
|
336
|
+
hash['displayName'] = display_name
|
329
337
|
hash['isa'] = isa
|
330
338
|
|
331
339
|
simple_attributes.each do |attrb|
|
@@ -351,6 +359,22 @@ module Xcodeproj
|
|
351
359
|
hash
|
352
360
|
end
|
353
361
|
|
362
|
+
# @return [Hash{String => Hash}] A hash suitable to display the object
|
363
|
+
# to the user.
|
364
|
+
#
|
365
|
+
def pretty_print
|
366
|
+
if to_many_attributes.count == 1
|
367
|
+
children = to_many_attributes.first.get_value(self)
|
368
|
+
{display_name => children.map(&:pretty_print)}
|
369
|
+
else
|
370
|
+
display_name
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
#---------------------------------------------------------------------#
|
375
|
+
|
376
|
+
public
|
377
|
+
|
354
378
|
# @!group Object methods
|
355
379
|
|
356
380
|
def ==(other)
|
@@ -362,9 +386,8 @@ module Xcodeproj
|
|
362
386
|
end
|
363
387
|
|
364
388
|
def inspect
|
365
|
-
|
366
|
-
|
367
|
-
s
|
389
|
+
name_part = " name=#{self.name}" if respond_to?(:name)
|
390
|
+
"<#{self.class}#{name_part} UUID=#{uuid}>"
|
368
391
|
end
|
369
392
|
end
|
370
393
|
end
|