xcodeproj 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/xcodeproj/xcodeproj_ext.c +3 -5
- data/lib/xcodeproj.rb +1 -1
- data/lib/xcodeproj/config.rb +39 -32
- data/lib/xcodeproj/constants.rb +8 -0
- data/lib/xcodeproj/project.rb +91 -47
- data/lib/xcodeproj/project/object.rb +43 -18
- data/lib/xcodeproj/project/object/build_configuration.rb +2 -0
- data/lib/xcodeproj/project/object/build_file.rb +2 -0
- data/lib/xcodeproj/project/object/build_phase.rb +36 -7
- data/lib/xcodeproj/project/object/build_rule.rb +2 -0
- data/lib/xcodeproj/project/object/configuration_list.rb +4 -2
- data/lib/xcodeproj/project/object/container_item_proxy.rb +2 -0
- data/lib/xcodeproj/project/object/file_reference.rb +7 -5
- data/lib/xcodeproj/project/object/group.rb +49 -35
- data/lib/xcodeproj/project/object/native_target.rb +84 -28
- data/lib/xcodeproj/project/object/reference_proxy.rb +9 -6
- data/lib/xcodeproj/project/object/root_object.rb +6 -4
- data/lib/xcodeproj/project/object/target_dependency.rb +8 -6
- data/lib/xcodeproj/project/object_attributes.rb +35 -10
- data/lib/xcodeproj/project/object_dictionary.rb +4 -4
- data/lib/xcodeproj/project/object_list.rb +2 -2
- metadata +3 -7
- data/lib/xcodeproj/project/object/aggregate_target.rb +0 -0
@@ -21,13 +21,10 @@ static VALUE
|
|
21
21
|
cfstr_to_str(const void *cfstr) {
|
22
22
|
CFDataRef data = CFStringCreateExternalRepresentation(NULL, cfstr, kCFStringEncodingUTF8, 0);
|
23
23
|
assert(data != NULL);
|
24
|
-
long
|
25
|
-
char *buf = (char *)
|
26
|
-
assert(buf != NULL);
|
27
|
-
CFDataGetBytes(data, CFRangeMake(0, len), buf);
|
24
|
+
long len = (long)CFDataGetLength(data);
|
25
|
+
char *buf = (char *)CFDataGetBytePtr(data);
|
28
26
|
|
29
27
|
register VALUE str = rb_str_new(buf, len);
|
30
|
-
free(buf);
|
31
28
|
|
32
29
|
// force UTF-8 encoding in Ruby 1.9+
|
33
30
|
ID forceEncodingId = rb_intern("force_encoding");
|
@@ -35,6 +32,7 @@ cfstr_to_str(const void *cfstr) {
|
|
35
32
|
rb_funcall(str, forceEncodingId, 1, rb_str_new("UTF-8", 5));
|
36
33
|
}
|
37
34
|
|
35
|
+
CFRelease(data);
|
38
36
|
return str;
|
39
37
|
}
|
40
38
|
|
data/lib/xcodeproj.rb
CHANGED
data/lib/xcodeproj/config.rb
CHANGED
@@ -12,17 +12,17 @@ module Xcodeproj
|
|
12
12
|
#
|
13
13
|
attr_accessor :attributes
|
14
14
|
|
15
|
-
# @return [
|
15
|
+
# @return [Set<String>] The list of the frameworks required by this
|
16
16
|
# settings file.
|
17
17
|
#
|
18
18
|
attr_accessor :frameworks
|
19
19
|
|
20
|
-
# @return [
|
20
|
+
# @return [Set<String>] The list of the *weak* frameworks required by
|
21
21
|
# this settings file.
|
22
22
|
#
|
23
23
|
attr_accessor :weak_frameworks
|
24
24
|
|
25
|
-
# @return [
|
25
|
+
# @return [Set<String>] The list of the libraries required by this
|
26
26
|
# settings file.
|
27
27
|
#
|
28
28
|
attr_accessor :libraries
|
@@ -43,19 +43,21 @@ module Xcodeproj
|
|
43
43
|
merge!(extract_hash(xcconfig_hash_or_file))
|
44
44
|
end
|
45
45
|
|
46
|
+
#-------------------------------------------------------------------------#
|
46
47
|
|
47
|
-
|
48
|
+
# @!group Serialization
|
48
49
|
|
49
|
-
#
|
50
|
+
# Sorts the internal data by setting name and serializes it in the xcconfig
|
51
|
+
# format.
|
50
52
|
#
|
51
53
|
# @example
|
52
54
|
#
|
53
55
|
# config = Config.new('PODS_ROOT' => '"$(SRCROOT)/Pods"', 'OTHER_LDFLAGS' => '-lxml2')
|
54
|
-
# config.to_s # => "
|
56
|
+
# config.to_s # => "OTHER_LDFLAGS = -lxml2\nPODS_ROOT = \"$(SRCROOT)/Pods\""
|
55
57
|
#
|
56
58
|
# @return [String] The serialized internal data.
|
57
59
|
def to_s
|
58
|
-
to_hash.map { |
|
60
|
+
to_hash.sort_by(&:first).map { |k, v| "#{k} = #{v}" }.join("\n")
|
59
61
|
end
|
60
62
|
|
61
63
|
# @return [void] Writes the serialized representation of the internal data
|
@@ -83,13 +85,13 @@ module Xcodeproj
|
|
83
85
|
hash
|
84
86
|
end
|
85
87
|
|
88
|
+
#-------------------------------------------------------------------------#
|
86
89
|
|
87
|
-
|
88
|
-
#@! group Merging
|
90
|
+
# @!group Merging
|
89
91
|
|
90
92
|
# Merges the given xcconfig hash or Config into the internal data.
|
91
93
|
#
|
92
|
-
# If a key in the given hash already exists
|
94
|
+
# If a key in the given hash already exists in the internal data then its
|
93
95
|
# value is appended to the value in the internal data.
|
94
96
|
#
|
95
97
|
# @example
|
@@ -103,41 +105,42 @@ module Xcodeproj
|
|
103
105
|
def merge!(xcconfig)
|
104
106
|
if xcconfig.is_a? Config
|
105
107
|
@attributes.merge!(xcconfig.attributes) { |key, v1, v2| "#{v1} #{v2}" }
|
106
|
-
@libraries.merge
|
107
|
-
@frameworks.merge
|
108
|
-
@weak_frameworks.merge
|
108
|
+
@libraries.merge(xcconfig.libraries)
|
109
|
+
@frameworks.merge(xcconfig.frameworks)
|
110
|
+
@weak_frameworks.merge(xcconfig.weak_frameworks)
|
109
111
|
else
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
112
|
+
@attributes.merge!(xcconfig.to_hash) { |key, v1, v2| "#{v1} #{v2}" }
|
113
|
+
# Parse frameworks and libraries. Then remove the from the linker flags
|
114
|
+
flags = @attributes['OTHER_LDFLAGS']
|
115
|
+
return unless flags
|
116
|
+
|
117
|
+
frameworks = flags.scan(/-framework\s+([^\s]+)/).map { |m| m[0] }
|
118
|
+
weak_frameworks = flags.scan(/-weak_framework\s+([^\s]+)/).map { |m| m[0] }
|
119
|
+
libraries = flags.scan(/-l ?([^\s]+)/).map { |m| m[0] }
|
120
|
+
@frameworks.merge frameworks
|
121
|
+
@weak_frameworks.merge weak_frameworks
|
122
|
+
@libraries.merge libraries
|
123
|
+
|
124
|
+
new_flags = flags.dup
|
125
|
+
frameworks.each {|f| new_flags.gsub!("-framework #{f}", "") }
|
126
|
+
weak_frameworks.each {|f| new_flags.gsub!("-weak_framework #{f}", "") }
|
127
|
+
libraries.each {|l| new_flags.gsub!("-l#{l}", ""); new_flags.gsub!("-l #{l}", "") }
|
128
|
+
@attributes['OTHER_LDFLAGS'] = new_flags.gsub("\w*", ' ').strip
|
127
129
|
end
|
128
130
|
end
|
129
131
|
alias_method :<<, :merge!
|
130
132
|
|
131
133
|
def merge(config)
|
132
|
-
self.dup.tap { |x|x.merge!(config) }
|
134
|
+
self.dup.tap { |x| x.merge!(config) }
|
133
135
|
end
|
134
136
|
|
135
137
|
def dup
|
136
138
|
Xcodeproj::Config.new(self.to_hash.dup)
|
137
139
|
end
|
138
140
|
|
141
|
+
#-------------------------------------------------------------------------#
|
139
142
|
|
140
|
-
|
143
|
+
# @!group Object methods
|
141
144
|
|
142
145
|
def inspect
|
143
146
|
to_hash.inspect
|
@@ -147,6 +150,10 @@ module Xcodeproj
|
|
147
150
|
other.respond_to?(:to_hash) && other.to_hash == self.to_hash
|
148
151
|
end
|
149
152
|
|
153
|
+
#-------------------------------------------------------------------------#
|
154
|
+
|
155
|
+
# @!group Private Helpers
|
156
|
+
|
150
157
|
private
|
151
158
|
|
152
159
|
def extract_hash(argument)
|
data/lib/xcodeproj/constants.rb
CHANGED
@@ -4,6 +4,14 @@ module Xcodeproj
|
|
4
4
|
#
|
5
5
|
module Constants
|
6
6
|
|
7
|
+
# The last known iOS SDK (stable).
|
8
|
+
#
|
9
|
+
LAST_KNOWN_IOS_SDK = '6.0'
|
10
|
+
|
11
|
+
# The last known OS X SDK (stable).
|
12
|
+
#
|
13
|
+
LAST_KNOWN_OSX_SDK = '10.8'
|
14
|
+
|
7
15
|
# The last known archive version to Xcodeproj.
|
8
16
|
#
|
9
17
|
LAST_KNOWN_ARCHIVE_VERSION = 1
|
data/lib/xcodeproj/project.rb
CHANGED
@@ -309,7 +309,7 @@ module Xcodeproj
|
|
309
309
|
@available_uuids += uniques
|
310
310
|
end
|
311
311
|
|
312
|
-
|
312
|
+
#-------------------------------------------------------------------------#
|
313
313
|
|
314
314
|
# @!group Convenience accessors
|
315
315
|
|
@@ -352,7 +352,7 @@ module Xcodeproj
|
|
352
352
|
# frameworks.name #=> 'Frameworks'
|
353
353
|
# main_group.children.include? frameworks #=> True
|
354
354
|
#
|
355
|
-
# @param [String] group_path
|
355
|
+
# @param [String] group_path @see MobileCoreServices
|
356
356
|
#
|
357
357
|
# @return [PBXGroup] the group at the given subpath.
|
358
358
|
#
|
@@ -411,7 +411,7 @@ module Xcodeproj
|
|
411
411
|
|
412
412
|
|
413
413
|
|
414
|
-
# @!group
|
414
|
+
# @!group Helpers for generating objects
|
415
415
|
|
416
416
|
# Creates a new file reference at the given subpath of the main group.
|
417
417
|
#
|
@@ -438,55 +438,81 @@ module Xcodeproj
|
|
438
438
|
# The file reference can then be added to the build files of a
|
439
439
|
# {PBXFrameworksBuildPhase}.
|
440
440
|
#
|
441
|
-
# @example
|
441
|
+
# @example Adding QuartzCore
|
442
442
|
#
|
443
|
-
# framework = project.add_system_framework('QuartzCore')
|
443
|
+
# framework = project.add_system_framework('QuartzCore', :ios)
|
444
444
|
#
|
445
445
|
# target = project.targets.first
|
446
446
|
# build_phase = target.frameworks_build_phases.first
|
447
447
|
# build_phase.files << framework.buildFiles.new
|
448
448
|
#
|
449
|
-
# @param
|
450
|
-
#
|
451
|
-
#
|
449
|
+
# @param [String] name
|
450
|
+
# The name of a framework.
|
451
|
+
#
|
452
|
+
# @param [PBXNativeTarget] target
|
453
|
+
# The target for which to add the framework.
|
454
|
+
#
|
455
|
+
# @note This method adds a reference to the highest know SDK for the
|
456
|
+
# given platform.
|
457
|
+
#
|
458
|
+
# @return [PBXFileReference] The generated file reference.
|
452
459
|
#
|
453
|
-
def add_system_framework(name)
|
454
|
-
|
455
|
-
|
460
|
+
def add_system_framework(name, target)
|
461
|
+
sdk = target.sdk
|
462
|
+
raise "Unable to find and SDK for the target `#{target.name}`" unless sdk
|
463
|
+
if sdk.include?('iphoneos')
|
464
|
+
if sdk == 'iphoneos'
|
465
|
+
base_dir = "Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS#{Constants::LAST_KNOWN_IOS_SDK}.sdk/"
|
466
|
+
else
|
467
|
+
base_dir = "Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS#{sdk.gsub('iphoneos', '')}.sdk/"
|
468
|
+
end
|
469
|
+
elsif sdk.include?('macosx')
|
470
|
+
if sdk == 'macosx'
|
471
|
+
base_dir = "Platforms/MacOSX.platform/Developer/SDKs/MacOSX#{Constants::LAST_KNOWN_OSX_SDK}.sdk/"
|
472
|
+
else
|
473
|
+
base_dir = "Platforms/MacOSX.platform/Developer/SDKs/MacOSX#{sdk.gsub('iphoneos', '')}.sdk/"
|
474
|
+
end
|
475
|
+
end
|
476
|
+
path = base_dir + "System/Library/Frameworks/#{name}.framework"
|
477
|
+
|
478
|
+
if file = frameworks_group.files.find { |f| f.path == path }
|
456
479
|
file
|
457
480
|
else
|
458
481
|
framework_ref = frameworks_group.new_file(path)
|
459
482
|
framework_ref.name = "#{name}.framework"
|
460
|
-
framework_ref.source_tree = '
|
483
|
+
framework_ref.source_tree = 'DEVELOPER_DIR'
|
484
|
+
framework_ref.last_known_file_type = "wrapper.framework"
|
461
485
|
framework_ref
|
462
486
|
end
|
463
487
|
end
|
464
488
|
|
465
|
-
#
|
466
|
-
#
|
489
|
+
# Creates a new target and adds it to the project.
|
490
|
+
#
|
491
|
+
# The target is configured for the given platform and its file reference it
|
492
|
+
# is added to the {products_group}.
|
467
493
|
#
|
468
|
-
#
|
469
|
-
#
|
494
|
+
# The target is pre-populated with common build phases, and all the
|
495
|
+
# Frameworks of the project are added to to its Frameworks phase.
|
470
496
|
#
|
471
|
-
#
|
472
|
-
#
|
497
|
+
# @todo Adding all the Frameworks is required by CocoaPods and should be
|
498
|
+
# performed there.
|
473
499
|
#
|
474
|
-
# @
|
475
|
-
#
|
500
|
+
# @param [Symbol] type
|
501
|
+
# the type of target. Can be `:application`, `:dynamic_library` or
|
502
|
+
# `:static_library`.
|
476
503
|
#
|
477
|
-
# @param
|
478
|
-
#
|
479
|
-
# Can be `:application`, `:dynamic_library` or `:static_library`.
|
504
|
+
# @param [String] name
|
505
|
+
# the name of the static library product.
|
480
506
|
#
|
481
|
-
# @param
|
482
|
-
#
|
507
|
+
# @param [Symbol] platform
|
508
|
+
# the platform of the static library. Can be `:ios` or `:osx`.
|
483
509
|
#
|
484
|
-
# @param
|
485
|
-
#
|
486
|
-
# Can be `:ios` or `:osx`.
|
510
|
+
# @param [String] deployment_target
|
511
|
+
# the deployment target for the platform.
|
487
512
|
#
|
488
|
-
|
489
|
-
|
513
|
+
# @return [PBXNativeTarget] the target.
|
514
|
+
#
|
515
|
+
def new_target(type, name, platform, deployment_target = nil)
|
490
516
|
|
491
517
|
# Target
|
492
518
|
target = new(PBXNativeTarget)
|
@@ -494,16 +520,20 @@ module Xcodeproj
|
|
494
520
|
target.name = name
|
495
521
|
target.product_name = name
|
496
522
|
target.product_type = Constants::PRODUCT_TYPE_UTI[type]
|
497
|
-
target.build_configuration_list = configuration_list(platform)
|
523
|
+
target.build_configuration_list = configuration_list(platform, deployment_target)
|
498
524
|
|
499
525
|
# Product
|
500
526
|
product = products_group.new_static_library(name)
|
501
527
|
target.product_reference = product
|
502
528
|
|
529
|
+
# Frameworks
|
530
|
+
framework_name = (platform == :ios) ? 'Foundation' : 'Cocoa'
|
531
|
+
framework_ref = add_system_framework(framework_name, target)
|
532
|
+
|
503
533
|
# Build phases
|
504
534
|
target.build_phases << new(PBXSourcesBuildPhase)
|
505
535
|
frameworks_phase = new(PBXFrameworksBuildPhase)
|
506
|
-
|
536
|
+
frameworks_phase.add_file_reference(framework_ref)
|
507
537
|
target.build_phases << frameworks_phase
|
508
538
|
|
509
539
|
target
|
@@ -512,23 +542,26 @@ module Xcodeproj
|
|
512
542
|
# Returns a new configuration list, populated with release and debug
|
513
543
|
# configurations with common build settings for the given platform.
|
514
544
|
#
|
515
|
-
# @param
|
516
|
-
#
|
545
|
+
# @param [Symbol] platform
|
546
|
+
# the platform for the configuration list, can be `:ios` or `:osx`.
|
547
|
+
#
|
548
|
+
# @param [String] deployment_target
|
549
|
+
# the deployment target for the platform.
|
517
550
|
#
|
518
551
|
# @return [XCConfigurationList] the generated configuration list.
|
519
552
|
#
|
520
|
-
def configuration_list(platform)
|
553
|
+
def configuration_list(platform, deployment_target = nil)
|
521
554
|
cl = new(XCConfigurationList)
|
522
555
|
cl.default_configuration_is_visible = '0'
|
523
556
|
cl.default_configuration_name = 'Release'
|
524
557
|
|
525
558
|
release_conf = new(XCBuildConfiguration)
|
526
559
|
release_conf.name = 'Release'
|
527
|
-
release_conf.build_settings =
|
560
|
+
release_conf.build_settings = common_build_settings(:release, platform, deployment_target)
|
528
561
|
|
529
562
|
debug_conf = new(XCBuildConfiguration)
|
530
563
|
debug_conf.name = 'Debug'
|
531
|
-
debug_conf.build_settings =
|
564
|
+
debug_conf.build_settings = common_build_settings(:debug, platform, deployment_target)
|
532
565
|
|
533
566
|
cl.build_configurations << release_conf
|
534
567
|
cl.build_configurations << debug_conf
|
@@ -538,21 +571,32 @@ module Xcodeproj
|
|
538
571
|
# Returns the common build settings for a given platform and configuration
|
539
572
|
# name.
|
540
573
|
#
|
541
|
-
# @param
|
542
|
-
#
|
574
|
+
# @param [Symbol] type
|
575
|
+
# the type of the build configuration, can be `:release` or
|
576
|
+
# `:debug`.
|
577
|
+
#
|
578
|
+
# @param [Symbol] platform
|
579
|
+
# the platform for the build settings, can be `:ios` or `:osx`.
|
543
580
|
#
|
544
|
-
# @param
|
545
|
-
#
|
581
|
+
# @param [String] deployment_target
|
582
|
+
# the deployment target for the platform.
|
546
583
|
#
|
547
584
|
# @return [Hash] The common build settings
|
548
585
|
#
|
549
|
-
def
|
586
|
+
def common_build_settings(type, platform, deployment_target = nil)
|
550
587
|
common_settings = Constants::COMMON_BUILD_SETTINGS
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
588
|
+
settings = common_settings[:all].dup
|
589
|
+
settings.merge!(common_settings[type])
|
590
|
+
settings.merge!(common_settings[platform])
|
591
|
+
settings.merge!(common_settings[[platform, type]])
|
592
|
+
if deployment_target
|
593
|
+
if platform == :ios
|
594
|
+
settings['IPHONEOS_DEPLOYMENT_TARGET'] = deployment_target
|
595
|
+
elsif platform == :osx
|
596
|
+
settings['MACOSX_DEPLOYMENT_TARGET'] = deployment_target
|
597
|
+
end
|
598
|
+
end
|
599
|
+
settings
|
556
600
|
end
|
557
601
|
|
558
602
|
end
|
@@ -35,7 +35,9 @@ module Xcodeproj
|
|
35
35
|
#
|
36
36
|
class AbstractObject
|
37
37
|
|
38
|
-
#
|
38
|
+
# @!group AbstractObject
|
39
|
+
|
40
|
+
# @return [String] the ISA of the class.
|
39
41
|
#
|
40
42
|
def self.isa
|
41
43
|
@isa ||= name.split('::').last
|
@@ -57,6 +59,8 @@ module Xcodeproj
|
|
57
59
|
# @param [String] uuid
|
58
60
|
# the UUID of the new object.
|
59
61
|
#
|
62
|
+
# @visibility private
|
63
|
+
#
|
60
64
|
def initialize(project, uuid)
|
61
65
|
@project, @uuid = project, uuid
|
62
66
|
@isa = self.class.isa
|
@@ -67,11 +71,13 @@ module Xcodeproj
|
|
67
71
|
# Initializes the object with the default values of simple attributes.
|
68
72
|
#
|
69
73
|
# This method is called by the {Project#new} and is not performed on
|
70
|
-
# initialization to
|
74
|
+
# initialization to prevent adding defaults to objects generated by a
|
71
75
|
# plist.
|
72
76
|
#
|
73
77
|
# @return [void]
|
74
78
|
#
|
79
|
+
# @visibility private
|
80
|
+
#
|
75
81
|
def initialize_defaults
|
76
82
|
simple_attributes.each { |a| a.set_default(self) }
|
77
83
|
end
|
@@ -116,6 +122,8 @@ module Xcodeproj
|
|
116
122
|
# @return [Array<ObjectList>] The list of the objects that have a
|
117
123
|
# reference to this object.
|
118
124
|
#
|
125
|
+
# @visibility private
|
126
|
+
#
|
119
127
|
attr_reader :referrers
|
120
128
|
|
121
129
|
# Informs the object that another object is referencing it. If the
|
@@ -124,6 +132,8 @@ module Xcodeproj
|
|
124
132
|
#
|
125
133
|
# @return [void]
|
126
134
|
#
|
135
|
+
# @visibility private
|
136
|
+
#
|
127
137
|
def add_referrer(referrer)
|
128
138
|
@referrers << referrer
|
129
139
|
@project.objects_by_uuid[uuid] = self
|
@@ -135,6 +145,8 @@ module Xcodeproj
|
|
135
145
|
#
|
136
146
|
# @return [void]
|
137
147
|
#
|
148
|
+
# @visibility private
|
149
|
+
#
|
138
150
|
def remove_referrer(referrer)
|
139
151
|
@referrers.delete(referrer)
|
140
152
|
if @referrers.count == 0
|
@@ -146,6 +158,8 @@ module Xcodeproj
|
|
146
158
|
#
|
147
159
|
# @return [void]
|
148
160
|
#
|
161
|
+
# @visibility private
|
162
|
+
#
|
149
163
|
def remove_reference(object)
|
150
164
|
to_one_attributes.each do |attrb|
|
151
165
|
value = attrb.get_value(self)
|
@@ -163,6 +177,8 @@ module Xcodeproj
|
|
163
177
|
end
|
164
178
|
end
|
165
179
|
|
180
|
+
#---------------------------------------------------------------------#
|
181
|
+
|
166
182
|
# @!group Plist related methods
|
167
183
|
|
168
184
|
# Configures the object with the objects hash from a plist.
|
@@ -173,6 +189,8 @@ module Xcodeproj
|
|
173
189
|
#
|
174
190
|
# @return [void]
|
175
191
|
#
|
192
|
+
# @visibility private
|
193
|
+
#
|
176
194
|
def configure_with_plist(objects_by_uuid_plist)
|
177
195
|
object_plist = objects_by_uuid_plist[uuid].dup
|
178
196
|
|
@@ -188,7 +206,7 @@ module Xcodeproj
|
|
188
206
|
ref_uuid = object_plist[attrb.plist_name]
|
189
207
|
if ref_uuid
|
190
208
|
ref = object_with_uuid(ref_uuid, objects_by_uuid_plist, attrb)
|
191
|
-
attrb.set_value(self, ref)
|
209
|
+
attrb.set_value(self, ref) if ref
|
192
210
|
end
|
193
211
|
object_plist.delete(attrb.plist_name)
|
194
212
|
end
|
@@ -197,7 +215,8 @@ module Xcodeproj
|
|
197
215
|
ref_uuids = object_plist[attrb.plist_name] || []
|
198
216
|
list = attrb.get_value(self)
|
199
217
|
ref_uuids.each do |uuid|
|
200
|
-
|
218
|
+
ref = object_with_uuid(uuid, objects_by_uuid_plist, attrb)
|
219
|
+
list << ref if ref
|
201
220
|
end
|
202
221
|
object_plist.delete(attrb.plist_name)
|
203
222
|
end
|
@@ -208,7 +227,8 @@ module Xcodeproj
|
|
208
227
|
hashes.each do |hash|
|
209
228
|
dictionary = ObjectDictionary.new(attrb, self)
|
210
229
|
hash.each do |key, uuid|
|
211
|
-
|
230
|
+
ref = object_with_uuid(uuid, objects_by_uuid_plist, attrb)
|
231
|
+
dictionary[key] = ref if ref
|
212
232
|
end
|
213
233
|
list << dictionary
|
214
234
|
end
|
@@ -222,7 +242,7 @@ module Xcodeproj
|
|
222
242
|
end
|
223
243
|
end
|
224
244
|
|
225
|
-
# Initializes and returns the object with the given
|
245
|
+
# Initializes and returns the object with the given UUID.
|
226
246
|
#
|
227
247
|
# @param [String] uuid
|
228
248
|
# The UUID of the object that should be initialized.
|
@@ -237,15 +257,18 @@ module Xcodeproj
|
|
237
257
|
#
|
238
258
|
# @raise If the hash for the given UUID contains an unknown ISA.
|
239
259
|
#
|
240
|
-
# @raise If the UUID can't be found in the objects hash.
|
241
|
-
#
|
242
260
|
# @return [AbstractObject] the initialized object.
|
261
|
+
# @return [Nil] if the UUID could not be found in the objects hash. In
|
262
|
+
# this case a warning is printed to STDERR.
|
263
|
+
#
|
264
|
+
# @visibility private
|
243
265
|
#
|
244
266
|
def object_with_uuid(uuid, objects_by_uuid_plist, attribute)
|
245
267
|
unless object = project.objects_by_uuid[uuid] || project.new_from_plist(uuid, objects_by_uuid_plist)
|
246
|
-
|
247
|
-
|
248
|
-
|
268
|
+
STDERR.puts "`#{inspect}` attempted to initialize an object with "\
|
269
|
+
"an unknown UUID. `#{uuid}` for attribute: `#{attribute.name}`."\
|
270
|
+
" This can be the result of a merge and the unkonw UUID is " \
|
271
|
+
"being discarded."
|
249
272
|
end
|
250
273
|
object
|
251
274
|
rescue NameError => exception
|
@@ -289,14 +312,16 @@ module Xcodeproj
|
|
289
312
|
|
290
313
|
# Returns a cascade representation of the object without UUIDs.
|
291
314
|
#
|
292
|
-
# This method is designed to work in
|
293
|
-
# to
|
294
|
-
#
|
315
|
+
# This method is designed to work in conjunction with
|
316
|
+
# {Hash#recursive_diff} to provide a complete, yet readable, diff of
|
317
|
+
# two projects *not* affected by ISA differences.
|
318
|
+
#
|
319
|
+
# @todo The current implementation might lead to infinite loops.
|
295
320
|
#
|
296
|
-
# @
|
321
|
+
# @return [Hash] a hash representation of the project different from
|
322
|
+
# the plist one.
|
297
323
|
#
|
298
|
-
# @
|
299
|
-
# plist one.
|
324
|
+
# @visibility private
|
300
325
|
#
|
301
326
|
def to_tree_hash
|
302
327
|
hash = {}
|
@@ -326,7 +351,7 @@ module Xcodeproj
|
|
326
351
|
hash
|
327
352
|
end
|
328
353
|
|
329
|
-
#
|
354
|
+
# @!group Object methods
|
330
355
|
|
331
356
|
def ==(other)
|
332
357
|
other.is_a?(AbstractObject) && self.to_plist == other.to_plist
|