xcodeproj 0.4.3 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|