xcodeproj 0.11.1 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/xcodeproj/xcodeproj_ext.c +8 -2
- data/lib/xcodeproj/constants.rb +42 -3
- data/lib/xcodeproj/gem_version.rb +1 -1
- data/lib/xcodeproj/project.rb +41 -4
- data/lib/xcodeproj/project/object.rb +19 -11
- data/lib/xcodeproj/project/object/build_configuration.rb +1 -1
- data/lib/xcodeproj/project/object/build_file.rb +5 -1
- data/lib/xcodeproj/project/object/file_reference.rb +7 -0
- data/lib/xcodeproj/project/object/group.rb +51 -7
- data/lib/xcodeproj/project/object/helpers/file_references_factory.rb +6 -2
- data/lib/xcodeproj/project/object/helpers/groupable_helper.rb +15 -24
- data/lib/xcodeproj/project/object/native_target.rb +40 -5
- data/lib/xcodeproj/project/object/target_dependency.rb +1 -1
- data/lib/xcodeproj/project/project_helper.rb +1 -1
- data/lib/xcodeproj/scheme.rb +160 -200
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f165be51aaefe9f3f60310905c4a81e9c01d7868
|
4
|
+
data.tar.gz: 9f07f26df8ac52efd7b8f7f3f922113d13c2f077
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4059f10f78ab4dcd313288657e33684bf535d57a4ae8c6060b044a1e435d1f8d7d57263dcdf80b891b86dd61ce146754302aadf7ac48795858448386b9e056b
|
7
|
+
data.tar.gz: d8c324cc0aace1bc07dbcca1996bb8ea269024093b5d4f28139cc36856174201612d8d87d0bd457a5ac27f4b6bc84a40bea62df1c82be768779570da1ece7d0d
|
@@ -80,7 +80,10 @@ hash_set(const void *keyRef, const void *valueRef, void *hash) {
|
|
80
80
|
CFTypeID valueType = CFGetTypeID(valueRef);
|
81
81
|
if (valueType == CFStringGetTypeID()) {
|
82
82
|
value = cfstr_to_str(valueRef);
|
83
|
-
|
83
|
+
} else if (valueRef == kCFBooleanTrue) {
|
84
|
+
value = Qtrue;
|
85
|
+
} else if (valueRef == kCFBooleanFalse) {
|
86
|
+
value = Qfalse;
|
84
87
|
} else if (valueType == CFDictionaryGetTypeID()) {
|
85
88
|
value = rb_hash_new();
|
86
89
|
CFDictionaryApplyFunction(valueRef, hash_set, (void *)value);
|
@@ -146,7 +149,10 @@ dictionary_set(st_data_t key, st_data_t value, CFMutableDictionaryRef dict) {
|
|
146
149
|
CFArrayAppendValue((CFMutableArrayRef)valueRef, elementRef);
|
147
150
|
CFRelease(elementRef);
|
148
151
|
}
|
149
|
-
|
152
|
+
} else if (value == Qtrue) {
|
153
|
+
valueRef = kCFBooleanTrue;
|
154
|
+
} else if (value == Qfalse) {
|
155
|
+
valueRef = kCFBooleanFalse;
|
150
156
|
} else {
|
151
157
|
valueRef = str_to_cfstr(value);
|
152
158
|
}
|
data/lib/xcodeproj/constants.rb
CHANGED
@@ -6,7 +6,7 @@ module Xcodeproj
|
|
6
6
|
|
7
7
|
# @return [String] The last known iOS SDK (stable).
|
8
8
|
#
|
9
|
-
LAST_KNOWN_IOS_SDK = '
|
9
|
+
LAST_KNOWN_IOS_SDK = '7.0'
|
10
10
|
|
11
11
|
# @return [String] The last known OS X SDK (stable).
|
12
12
|
#
|
@@ -70,7 +70,7 @@ module Xcodeproj
|
|
70
70
|
#
|
71
71
|
FILE_TYPES_BY_EXTENSION = {
|
72
72
|
'a' => 'archive.ar',
|
73
|
-
'
|
73
|
+
'app' => 'wrapper.application',
|
74
74
|
'dylib' => 'compiled.mach-o.dylib',
|
75
75
|
'framework' => 'wrapper.framework',
|
76
76
|
'bundle' => 'wrapper.plug-in',
|
@@ -96,6 +96,16 @@ module Xcodeproj
|
|
96
96
|
:bundle => 'com.apple.product-type.bundle',
|
97
97
|
}.freeze
|
98
98
|
|
99
|
+
# @return [Hash] The extensions or the various product UTIs.
|
100
|
+
#
|
101
|
+
PRODUCT_UTI_EXTENSIONS = {
|
102
|
+
:application => 'app',
|
103
|
+
:framework => 'framework',
|
104
|
+
:dynamic_library => 'dylib',
|
105
|
+
:static_library => 'a',
|
106
|
+
:bundle => 'bundle',
|
107
|
+
}.freeze
|
108
|
+
|
99
109
|
# @return [Hash] The common build settings grouped by platform, and build
|
100
110
|
# configuration name.
|
101
111
|
#
|
@@ -152,10 +162,39 @@ module Xcodeproj
|
|
152
162
|
# @return [Hash] The default build settings for a new project.
|
153
163
|
#
|
154
164
|
PROJECT_DEFAULT_BUILD_SETTINGS = {
|
165
|
+
:all => {
|
166
|
+
'ALWAYS_SEARCH_USER_PATHS' => 'NO',
|
167
|
+
'CLANG_CXX_LANGUAGE_STANDARD' => "gnu++0x",
|
168
|
+
'CLANG_CXX_LIBRARY' => "libc++",
|
169
|
+
'CLANG_ENABLE_OBJC_ARC' => 'YES',
|
170
|
+
'CLANG_WARN_BOOL_CONVERSION' => 'YES',
|
171
|
+
'CLANG_WARN_CONSTANT_CONVERSION' => 'YES',
|
172
|
+
'CLANG_WARN_DIRECT_OBJC_ISA_USAGE' => 'YES_ERROR',
|
173
|
+
'CLANG_WARN_EMPTY_BODY' => 'YES',
|
174
|
+
'CLANG_WARN_ENUM_CONVERSION' => 'YES',
|
175
|
+
'CLANG_WARN_INT_CONVERSION' => 'YES',
|
176
|
+
'CLANG_WARN_OBJC_ROOT_CLASS' => 'YES_ERROR',
|
177
|
+
'CLANG_ENABLE_MODULES' => 'YES',
|
178
|
+
'GCC_C_LANGUAGE_STANDARD' => 'gnu99',
|
179
|
+
'GCC_WARN_64_TO_32_BIT_CONVERSION' => 'YES',
|
180
|
+
'GCC_WARN_ABOUT_RETURN_TYPE' => 'YES_ERROR',
|
181
|
+
'GCC_WARN_UNDECLARED_SELECTOR' => 'YES',
|
182
|
+
'GCC_WARN_UNINITIALIZED_AUTOS' => 'YES',
|
183
|
+
'GCC_WARN_UNUSED_FUNCTION' => 'YES',
|
184
|
+
'GCC_WARN_UNUSED_VARIABLE' => 'YES',
|
185
|
+
},
|
155
186
|
:release => {
|
187
|
+
'COPY_PHASE_STRIP' => 'NO',
|
188
|
+
'ENABLE_NS_ASSERTIONS' => 'NO',
|
189
|
+
'VALIDATE_PRODUCT' => 'YES',
|
156
190
|
}.freeze,
|
157
191
|
:debug => {
|
158
|
-
'ONLY_ACTIVE_ARCH'
|
192
|
+
'ONLY_ACTIVE_ARCH' => 'YES',
|
193
|
+
'COPY_PHASE_STRIP' => 'YES',
|
194
|
+
'GCC_DYNAMIC_NO_PIC' => 'NO',
|
195
|
+
'GCC_OPTIMIZATION_LEVEL' => '0',
|
196
|
+
'GCC_PREPROCESSOR_DEFINITIONS' => ["DEBUG=1", "$(inherited)"],
|
197
|
+
'GCC_SYMBOLS_PRIVATE_EXTERN' => 'NO',
|
159
198
|
}.freeze,
|
160
199
|
}.freeze
|
161
200
|
|
data/lib/xcodeproj/project.rb
CHANGED
@@ -84,6 +84,7 @@ module Xcodeproj
|
|
84
84
|
# Project.open("path/to/Project.xcodeproj")
|
85
85
|
#
|
86
86
|
def self.open(path)
|
87
|
+
path = Pathname.pwd + path
|
87
88
|
unless Pathname.new(path).exist?
|
88
89
|
raise "[Xcodeproj] Unable to open `#{path}` because it doesn't exist."
|
89
90
|
end
|
@@ -605,7 +606,10 @@ module Xcodeproj
|
|
605
606
|
unless build_configuration_list[name]
|
606
607
|
build_configuration = new(XCBuildConfiguration)
|
607
608
|
build_configuration.name = name
|
608
|
-
|
609
|
+
common_settings = Constants::PROJECT_DEFAULT_BUILD_SETTINGS
|
610
|
+
settings = ProjectHelper.deep_dup(common_settings[:all])
|
611
|
+
settings.merge!(ProjectHelper.deep_dup(common_settings[type]))
|
612
|
+
build_configuration.build_settings = settings
|
609
613
|
build_configuration_list.build_configurations << build_configuration
|
610
614
|
build_configuration
|
611
615
|
end
|
@@ -613,16 +617,21 @@ module Xcodeproj
|
|
613
617
|
|
614
618
|
# Sorts the project.
|
615
619
|
#
|
620
|
+
# @param [Hash] options
|
621
|
+
# the sorting options.
|
622
|
+
# @option options [Symbol] :groups_position
|
623
|
+
# the position of the groups can be either `:above` or `:below`.
|
624
|
+
#
|
616
625
|
# @return [void]
|
617
626
|
#
|
618
|
-
def sort
|
619
|
-
root_object.sort_recursively
|
627
|
+
def sort(options = nil)
|
628
|
+
root_object.sort_recursively(options)
|
620
629
|
end
|
621
630
|
|
622
631
|
|
623
632
|
public
|
624
633
|
|
625
|
-
# @!group
|
634
|
+
# @!group Schemes
|
626
635
|
#-------------------------------------------------------------------------#
|
627
636
|
|
628
637
|
# Get list of shared schemes in project
|
@@ -640,6 +649,34 @@ module Xcodeproj
|
|
640
649
|
schemes
|
641
650
|
end
|
642
651
|
|
652
|
+
# Recreates the user schemes of the project from scratch (removes the
|
653
|
+
# folder) and optionally hides them.
|
654
|
+
#
|
655
|
+
# @param [Bool] visible
|
656
|
+
# Wether the schemes should be visible or hidden.
|
657
|
+
#
|
658
|
+
# @return [void]
|
659
|
+
#
|
660
|
+
def recreate_user_schemes(visible = true)
|
661
|
+
schemes_dir = XCScheme.user_data_dir(path)
|
662
|
+
FileUtils.rm_rf(schemes_dir)
|
663
|
+
|
664
|
+
xcschememanagement = {}
|
665
|
+
xcschememanagement['SchemeUserState'] = {}
|
666
|
+
xcschememanagement['SuppressBuildableAutocreation'] = {}
|
667
|
+
|
668
|
+
targets.each do |target|
|
669
|
+
scheme = XCScheme.new
|
670
|
+
scheme.add_build_target(target)
|
671
|
+
scheme.save_as(path, target.name, false)
|
672
|
+
xcschememanagement['SchemeUserState']["#{target.name}.xcscheme"] = {}
|
673
|
+
xcschememanagement['SchemeUserState']["#{target.name}.xcscheme"]['isShown'] = visible
|
674
|
+
end
|
675
|
+
|
676
|
+
xcschememanagement_path = schemes_dir + 'xcschememanagement.plist'
|
677
|
+
Xcodeproj.write_plist(xcschememanagement, xcschememanagement_path)
|
678
|
+
end
|
679
|
+
|
643
680
|
#-------------------------------------------------------------------------#
|
644
681
|
|
645
682
|
end
|
@@ -136,7 +136,7 @@ module Xcodeproj
|
|
136
136
|
# Sorts the to many attributes of the object according to the display
|
137
137
|
# name.
|
138
138
|
#
|
139
|
-
def sort
|
139
|
+
def sort(options = nil)
|
140
140
|
to_many_attributes.each do |attrb|
|
141
141
|
list = attrb.get_value(self)
|
142
142
|
list.sort! do |x, y|
|
@@ -147,25 +147,33 @@ module Xcodeproj
|
|
147
147
|
|
148
148
|
# Sorts the object and the objects that it references.
|
149
149
|
#
|
150
|
-
# @
|
151
|
-
#
|
152
|
-
#
|
153
|
-
#
|
154
|
-
#
|
150
|
+
# @param [Hash] options
|
151
|
+
# the sorting options.
|
152
|
+
# @option options [Symbol] :groups_position
|
153
|
+
# the position of the groups can be either `:above` or
|
154
|
+
# `:below`.
|
155
155
|
#
|
156
|
-
#
|
157
|
-
|
156
|
+
# @note Some objects may in turn refer back to objects higher in the
|
157
|
+
# object tree, which will lead to stack level deep errors.
|
158
|
+
# These objects should **not** try to perform a recursive sort,
|
159
|
+
# also because these objects would get sorted through other
|
160
|
+
# paths in the tree anyways.
|
161
|
+
#
|
162
|
+
# At the time of writing the only known case is
|
163
|
+
# `PBXTargetDependency`.
|
164
|
+
#
|
165
|
+
def sort_recursively(options = nil)
|
158
166
|
to_one_attributes.each do |attrb|
|
159
167
|
value = attrb.get_value(self)
|
160
|
-
value.sort_recursively if value
|
168
|
+
value.sort_recursively(options) if value
|
161
169
|
end
|
162
170
|
|
163
171
|
to_many_attributes.each do |attrb|
|
164
172
|
list = attrb.get_value(self)
|
165
|
-
list.each(
|
173
|
+
list.each { |entry| entry.sort_recursively(options) }
|
166
174
|
end
|
167
175
|
|
168
|
-
sort
|
176
|
+
sort(options)
|
169
177
|
end
|
170
178
|
|
171
179
|
# @!group Reference counting
|
@@ -134,6 +134,13 @@ module Xcodeproj
|
|
134
134
|
GroupableHelper.parent(self)
|
135
135
|
end
|
136
136
|
|
137
|
+
# @return [Array<PBXGroup, PBXProject>] The list of the parents of the
|
138
|
+
# reference.
|
139
|
+
#
|
140
|
+
def parents
|
141
|
+
GroupableHelper.parents(self)
|
142
|
+
end
|
143
|
+
|
137
144
|
# @return [String] A representation of the reference hierarchy.
|
138
145
|
#
|
139
146
|
def hierarchy_path
|
@@ -90,6 +90,13 @@ module Xcodeproj
|
|
90
90
|
GroupableHelper.parent(self)
|
91
91
|
end
|
92
92
|
|
93
|
+
# @return [Array<PBXGroup, PBXProject>] The list of the parents of the
|
94
|
+
# group.
|
95
|
+
#
|
96
|
+
def parents
|
97
|
+
GroupableHelper.parents(self)
|
98
|
+
end
|
99
|
+
|
93
100
|
# @return [String] A representation of the group hierarchy.
|
94
101
|
#
|
95
102
|
def hierarchy_path
|
@@ -180,6 +187,20 @@ module Xcodeproj
|
|
180
187
|
result
|
181
188
|
end
|
182
189
|
|
190
|
+
# @return [Array<PBXGroup,PBXFileReference,PBXReferenceProxy>] the
|
191
|
+
# recursive list of the children of the group.
|
192
|
+
#
|
193
|
+
def recursive_children
|
194
|
+
result = []
|
195
|
+
children.each do |child|
|
196
|
+
result << child
|
197
|
+
if child.is_a?(PBXGroup)
|
198
|
+
result.concat(child.recursive_children)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
result
|
202
|
+
end
|
203
|
+
|
183
204
|
# @return [Bool] Whether the group is empty.
|
184
205
|
#
|
185
206
|
def empty?
|
@@ -212,8 +233,8 @@ module Xcodeproj
|
|
212
233
|
#
|
213
234
|
# @return [PBXFileReference] The new file reference.
|
214
235
|
#
|
215
|
-
def
|
216
|
-
FileReferencesFactory.
|
236
|
+
def new_product_ref_for_target(target_name, product_type)
|
237
|
+
FileReferencesFactory.new_product_ref_for_target(self, target_name, product_type)
|
217
238
|
end
|
218
239
|
|
219
240
|
# Creates a file reference to a new bundle.
|
@@ -342,12 +363,11 @@ module Xcodeproj
|
|
342
363
|
#
|
343
364
|
# @return [void]
|
344
365
|
#
|
345
|
-
def
|
346
|
-
groups.each { |group| group.
|
366
|
+
def sort_recursively_by_type
|
367
|
+
groups.each { |group| group.sort_recursively_by_type }
|
347
368
|
sort_by_type
|
348
369
|
end
|
349
370
|
|
350
|
-
|
351
371
|
public
|
352
372
|
|
353
373
|
# @!group AbstractObject Hooks
|
@@ -369,8 +389,32 @@ module Xcodeproj
|
|
369
389
|
# Sorts the to many attributes of the object according to the display
|
370
390
|
# name.
|
371
391
|
#
|
372
|
-
|
373
|
-
|
392
|
+
# @param [Hash] options
|
393
|
+
# the sorting options.
|
394
|
+
# @option options [Symbol] :groups_position
|
395
|
+
# the position of the groups can be either `:above` or
|
396
|
+
# `:below`.
|
397
|
+
#
|
398
|
+
# @return [void]
|
399
|
+
#
|
400
|
+
def sort(options = nil)
|
401
|
+
children.sort! do |x, y|
|
402
|
+
if options && groups_position = options[:groups_position]
|
403
|
+
raise ArgumentError unless [:above, :below].include?(groups_position)
|
404
|
+
if x.isa == 'PBXGroup' && !(y.isa == 'PBXGroup')
|
405
|
+
next groups_position == :above ? -1 : 1
|
406
|
+
elsif !(x.isa == 'PBXGroup') && y.isa == 'PBXGroup'
|
407
|
+
next groups_position == :above ? 1 : -1
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
result = File.basename(x.display_name, ".*" ) <=> File.basename(y.display_name, ".*" )
|
412
|
+
if result.zero?
|
413
|
+
File.extname(x.display_name) <=> File.extname(y.display_name)
|
414
|
+
else
|
415
|
+
result
|
416
|
+
end
|
417
|
+
end
|
374
418
|
end
|
375
419
|
end
|
376
420
|
|
@@ -44,8 +44,12 @@ module Xcodeproj
|
|
44
44
|
#
|
45
45
|
# @return [PBXFileReference] The new file reference.
|
46
46
|
#
|
47
|
-
def
|
48
|
-
|
47
|
+
def new_product_ref_for_target(group, target_name, product_type)
|
48
|
+
if product_type == :static_library
|
49
|
+
prefix = 'lib'
|
50
|
+
end
|
51
|
+
extension = Constants::PRODUCT_UTI_EXTENSIONS[product_type]
|
52
|
+
ref = new_reference(group, "#{prefix}#{target_name}.#{extension}", :built_products)
|
49
53
|
ref.include_in_index = '0'
|
50
54
|
ref.set_explicit_file_type
|
51
55
|
ref
|
@@ -10,8 +10,21 @@ module Xcodeproj
|
|
10
10
|
# @return [PBXGroup, PBXProject] The parent of the object.
|
11
11
|
#
|
12
12
|
def parent(object)
|
13
|
-
|
14
|
-
|
13
|
+
referrers = object.referrers.uniq
|
14
|
+
if referrers.count > 1
|
15
|
+
referrers = referrers.select{ |obj| obj.isa == 'PBXGroup' }
|
16
|
+
end
|
17
|
+
|
18
|
+
if referrers.count == 0
|
19
|
+
raise "[Xcodeproj] Consistency issue: no parent " \
|
20
|
+
"for object `#{object.display_name}`: "\
|
21
|
+
"`#{object.referrers.join('`, `')}`"
|
22
|
+
elsif referrers.count > 1
|
23
|
+
raise "[Xcodeproj] Consistency issue: unexpected multiple parents " \
|
24
|
+
"for object `#{object.display_name}`: "\
|
25
|
+
"#{object.referrers}"
|
26
|
+
end
|
27
|
+
referrers.first
|
15
28
|
end
|
16
29
|
|
17
30
|
# @param [PBXGroup, PBXFileReference] object
|
@@ -187,28 +200,6 @@ module Xcodeproj
|
|
187
200
|
# @group Helpers
|
188
201
|
#-------------------------------------------------------------------#
|
189
202
|
|
190
|
-
# Checks whether there is a single identifiable parent and raises
|
191
|
-
# otherwise.
|
192
|
-
#
|
193
|
-
# @return [void]
|
194
|
-
#
|
195
|
-
def check_parents_integrity(object)
|
196
|
-
referrers_count = object.referrers.uniq.count
|
197
|
-
if referrers_count > 1
|
198
|
-
referrers_count = object.referrers.select{ |obj| obj.isa == 'PBXGroup' }.count
|
199
|
-
end
|
200
|
-
|
201
|
-
if referrers_count == 0
|
202
|
-
raise "[Xcodeproj] Consistency issue: no parent " \
|
203
|
-
"for object `#{object.display_name}`: "\
|
204
|
-
"`#{object.referrers.join('`, `')}`"
|
205
|
-
elsif referrers_count > 1
|
206
|
-
raise "[Xcodeproj] Consistency issue: unexpected multiple parents " \
|
207
|
-
"for object `#{object.display_name}`: "\
|
208
|
-
"#{object.referrers}"
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
203
|
# Converts the given source tree to its string value.
|
213
204
|
#
|
214
205
|
# @param [Symbol, String] source_tree
|
@@ -52,6 +52,12 @@ module Xcodeproj
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
# @return [String] the version of the SDK.
|
56
|
+
#
|
57
|
+
def sdk_version
|
58
|
+
sdk.scan(/[0-9.]+/).first
|
59
|
+
end
|
60
|
+
|
55
61
|
# @return [String] the deployment target of the target according to its
|
56
62
|
# platform.
|
57
63
|
#
|
@@ -192,13 +198,35 @@ module Xcodeproj
|
|
192
198
|
# @param [Array<String>, String] name
|
193
199
|
# The name or the list of the names of the framework.
|
194
200
|
#
|
201
|
+
# @note Xcode behaviour is following: if the target has the same SDK
|
202
|
+
# of the project it adds the reference relative to the SDK root
|
203
|
+
# otherwise the reference is added relative to the Developer
|
204
|
+
# directory. This can create confusion or duplication of the
|
205
|
+
# references of frameworks linked by iOS and OS X targets. For
|
206
|
+
# this reason the new Xcodeproj behaviour is to add the
|
207
|
+
# frameworks in a subgroup according to the platform.
|
208
|
+
#
|
195
209
|
# @return [void]
|
196
210
|
#
|
197
211
|
def add_system_framework(names)
|
198
212
|
Array(names).each do |name|
|
199
|
-
|
200
|
-
|
201
|
-
|
213
|
+
|
214
|
+
case platform_name
|
215
|
+
when :ios
|
216
|
+
group = project.frameworks_group['iOS'] || project.frameworks_group.new_group('iOS')
|
217
|
+
path_sdk_name = 'iPhoneOS'
|
218
|
+
path_sdk_version = sdk_version || Constants::LAST_KNOWN_IOS_SDK
|
219
|
+
when :osx
|
220
|
+
group = project.frameworks_group['OS X'] || project.frameworks_group.new_group('OS X')
|
221
|
+
path_sdk_name = 'MacOSX'
|
222
|
+
path_sdk_version = sdk_version || Constants::LAST_KNOWN_OSX_SDK
|
223
|
+
else
|
224
|
+
raise "Unknown platform for target"
|
225
|
+
end
|
226
|
+
|
227
|
+
path = "Platforms/#{path_sdk_name}.platform/Developer/SDKs/#{path_sdk_name}#{path_sdk_version}.sdk/System/Library/Frameworks/#{name}.framework"
|
228
|
+
unless ref = group.find_file_by_path(path)
|
229
|
+
ref = group.new_file(path, :developer_dir)
|
202
230
|
end
|
203
231
|
frameworks_build_phase.add_file_reference(ref, true)
|
204
232
|
ref
|
@@ -259,7 +287,7 @@ module Xcodeproj
|
|
259
287
|
|
260
288
|
# @return [String] the build product type identifier.
|
261
289
|
#
|
262
|
-
attribute :product_type, String
|
290
|
+
attribute :product_type, String
|
263
291
|
|
264
292
|
# @return [PBXFileReference] the reference to the product file.
|
265
293
|
#
|
@@ -284,6 +312,13 @@ module Xcodeproj
|
|
284
312
|
# @!group Helpers
|
285
313
|
#--------------------------------------#
|
286
314
|
|
315
|
+
# @return [Symbol] The type of the target expressed as a symbol.
|
316
|
+
#
|
317
|
+
def symbol_type
|
318
|
+
pair = Constants::PRODUCT_TYPE_UTI.find { |key, value| value == product_type }
|
319
|
+
pair.first
|
320
|
+
end
|
321
|
+
|
287
322
|
# Adds source files to the target.
|
288
323
|
#
|
289
324
|
# @param [Array<PBXFileReference>] file_references
|
@@ -409,7 +444,7 @@ module Xcodeproj
|
|
409
444
|
#
|
410
445
|
# Build phases are not sorted as they order is relevant.
|
411
446
|
#
|
412
|
-
def sort
|
447
|
+
def sort(options = nil)
|
413
448
|
attributes_to_sort = to_many_attributes.reject { |attr| attr.name == :build_phases }
|
414
449
|
attributes_to_sort.each do |attrb|
|
415
450
|
list = attrb.get_value(self)
|
@@ -46,7 +46,7 @@ module Xcodeproj
|
|
46
46
|
target.build_configuration_list = configuration_list(project, platform, deployment_target)
|
47
47
|
|
48
48
|
# Product
|
49
|
-
product = product_group.
|
49
|
+
product = product_group.new_product_ref_for_target(name, type)
|
50
50
|
target.product_reference = product
|
51
51
|
|
52
52
|
# Build phases
|
data/lib/xcodeproj/scheme.rb
CHANGED
@@ -13,152 +13,138 @@ module Xcodeproj
|
|
13
13
|
#
|
14
14
|
attr_reader :doc
|
15
15
|
|
16
|
-
# @return [String] the name of the container (the project name file without
|
17
|
-
# the extension) that have the targets used by the scheme.
|
18
|
-
#
|
19
|
-
attr_reader :container
|
20
|
-
|
21
|
-
# @return [Xcodeproj::Project::Object::AbstractTarget] the target used by
|
22
|
-
# scheme in the build step.
|
23
|
-
#
|
24
|
-
attr_reader :build_target
|
25
|
-
|
26
|
-
# @return [Xcodeproj::Project::Object::AbstractTarget] the target used by
|
27
|
-
# scheme in the test step.
|
28
|
-
#
|
29
|
-
attr_reader :test_target
|
30
|
-
|
31
16
|
# Create a new XCScheme instance
|
32
17
|
#
|
33
|
-
|
34
|
-
# The name of the container (the project name file without the extension) that have the targets used by the
|
35
|
-
# scheme.
|
36
|
-
#
|
37
|
-
# @param [Xcodeproj::Project::Object::AbstractTarget] build_target
|
38
|
-
# The target used by scheme in the build step.
|
39
|
-
#
|
40
|
-
# @param [Xcodeproj::Project::Object::AbstractTarget] test_target
|
41
|
-
# The target used by scheme in the test step.
|
42
|
-
#
|
43
|
-
# @example
|
44
|
-
# Xcodeproj::XCScheme.new 'Cocoa Application', project.targets[0], project.targets[1]
|
45
|
-
#
|
46
|
-
def initialize(container, build_target, test_target = nil)
|
47
|
-
@container = container
|
48
|
-
@build_target = build_target
|
49
|
-
@test_target = test_target
|
50
|
-
|
18
|
+
def initialize
|
51
19
|
@doc = REXML::Document.new
|
52
20
|
@doc << REXML::XMLDecl.new(REXML::XMLDecl::DEFAULT_VERSION, 'UTF-8')
|
53
21
|
@doc.context[:attribute_quote] = :quote
|
54
22
|
|
55
|
-
scheme = @doc.add_element 'Scheme'
|
56
|
-
scheme.attributes['LastUpgradeVersion'] = Constants::LAST_UPGRADE_CHECK
|
57
|
-
scheme.attributes['version'] = '1.3'
|
58
|
-
|
59
|
-
build_action = scheme.add_element 'BuildAction'
|
60
|
-
build_action.attributes['parallelizeBuildables'] = 'YES'
|
61
|
-
build_action.attributes['buildImplicitDependencies'] = 'YES'
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
buildable_reference = testable_reference.add_element 'BuildableReference'
|
94
|
-
buildable_reference.attributes['BuildableIdentifier'] = 'primary'
|
95
|
-
buildable_reference.attributes['BlueprintIdentifier'] = test_target.uuid
|
96
|
-
buildable_reference.attributes['BuildableName'] = "#{test_target.name}.octest"
|
97
|
-
buildable_reference.attributes['BlueprintName'] = test_target.name
|
98
|
-
buildable_reference.attributes['ReferencedContainer'] = "container:#{container}.xcodeproj"
|
99
|
-
|
100
|
-
if (build_target.product_type == 'com.apple.product-type.application') then
|
101
|
-
macro_expansion = test_action.add_element 'MacroExpansion'
|
102
|
-
|
103
|
-
buildable_reference = macro_expansion.add_element 'BuildableReference'
|
104
|
-
buildable_reference.attributes['BuildableIdentifier'] = 'primary'
|
105
|
-
buildable_reference.attributes['BlueprintIdentifier'] = build_target.uuid
|
106
|
-
buildable_reference.attributes['BuildableName'] = "#{build_target.name}.app"
|
107
|
-
buildable_reference.attributes['BlueprintName'] = build_target.name
|
108
|
-
buildable_reference.attributes['ReferencedContainer'] = "container:#{container}.xcodeproj"
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
launch_action = scheme.add_element 'LaunchAction'
|
113
|
-
launch_action.attributes['selectedDebuggerIdentifier'] = 'Xcode.DebuggerFoundation.Debugger.LLDB'
|
114
|
-
launch_action.attributes['selectedLauncherIdentifier'] = 'Xcode.DebuggerFoundation.Launcher.LLDB'
|
115
|
-
launch_action.attributes['launchStyle'] = '0'
|
116
|
-
launch_action.attributes['useCustomWorkingDirectory'] = 'NO'
|
117
|
-
launch_action.attributes['buildConfiguration'] = 'Debug'
|
118
|
-
launch_action.attributes['ignoresPersistentStateOnLaunch'] = 'NO'
|
119
|
-
launch_action.attributes['debugDocumentVersioning'] = 'YES'
|
120
|
-
launch_action.attributes['allowLocationSimulation'] = 'YES'
|
121
|
-
|
122
|
-
if (build_target.product_type == 'com.apple.product-type.application') then
|
123
|
-
buildable_product_runnable = launch_action.add_element 'BuildableProductRunnable'
|
124
|
-
|
125
|
-
buildable_reference = buildable_product_runnable.add_element 'BuildableReference'
|
126
|
-
buildable_reference.attributes['BuildableIdentifier'] = 'primary'
|
127
|
-
buildable_reference.attributes['BlueprintIdentifier'] = build_target.uuid
|
128
|
-
buildable_reference.attributes['BuildableName'] = "#{build_target.name}.app"
|
129
|
-
buildable_reference.attributes['BlueprintName'] = build_target.name
|
130
|
-
buildable_reference.attributes['ReferencedContainer'] = "container:#{container}.xcodeproj"
|
131
|
-
end
|
23
|
+
@scheme = @doc.add_element 'Scheme'
|
24
|
+
@scheme.attributes['LastUpgradeVersion'] = Constants::LAST_UPGRADE_CHECK
|
25
|
+
@scheme.attributes['version'] = '1.3'
|
26
|
+
|
27
|
+
@build_action = @scheme.add_element 'BuildAction'
|
28
|
+
@build_action.attributes['parallelizeBuildables'] = 'YES'
|
29
|
+
@build_action.attributes['buildImplicitDependencies'] = 'YES'
|
30
|
+
@build_action_entries = nil
|
31
|
+
|
32
|
+
@test_action = @scheme.add_element 'TestAction'
|
33
|
+
@test_action.attributes['selectedDebuggerIdentifier'] = 'Xcode.DebuggerFoundation.Debugger.LLDB'
|
34
|
+
@test_action.attributes['selectedLauncherIdentifier'] = 'Xcode.DebuggerFoundation.Launcher.LLDB'
|
35
|
+
@test_action.attributes['shouldUseLaunchSchemeArgsEnv'] = 'YES'
|
36
|
+
@test_action.attributes['buildConfiguration'] = 'Debug'
|
37
|
+
|
38
|
+
@testables = @test_action.add_element 'Testables'
|
39
|
+
|
40
|
+
@launch_action = @scheme.add_element 'LaunchAction'
|
41
|
+
@launch_action.attributes['selectedDebuggerIdentifier'] = 'Xcode.DebuggerFoundation.Debugger.LLDB'
|
42
|
+
@launch_action.attributes['selectedLauncherIdentifier'] = 'Xcode.DebuggerFoundation.Launcher.LLDB'
|
43
|
+
@launch_action.attributes['launchStyle'] = '0'
|
44
|
+
@launch_action.attributes['useCustomWorkingDirectory'] = 'NO'
|
45
|
+
@launch_action.attributes['buildConfiguration'] = 'Debug'
|
46
|
+
@launch_action.attributes['ignoresPersistentStateOnLaunch'] = 'NO'
|
47
|
+
@launch_action.attributes['debugDocumentVersioning'] = 'YES'
|
48
|
+
@launch_action.attributes['allowLocationSimulation'] = 'YES'
|
49
|
+
additional_options = @launch_action.add_element 'AdditionalOptions'
|
50
|
+
|
51
|
+
@profile_action = @scheme.add_element 'ProfileAction'
|
52
|
+
@profile_action.attributes['shouldUseLaunchSchemeArgsEnv'] = 'YES'
|
53
|
+
@profile_action.attributes['savedToolIdentifier'] = ''
|
54
|
+
@profile_action.attributes['useCustomWorkingDirectory'] = 'NO'
|
55
|
+
@profile_action.attributes['buildConfiguration'] = 'Release'
|
56
|
+
@profile_action.attributes['debugDocumentVersioning'] = 'YES'
|
57
|
+
|
58
|
+
analyze_action = @scheme.add_element 'AnalyzeAction'
|
59
|
+
analyze_action.attributes['buildConfiguration'] = 'Debug'
|
132
60
|
|
133
|
-
|
61
|
+
archive_action = @scheme.add_element 'ArchiveAction'
|
62
|
+
archive_action.attributes['buildConfiguration'] = 'Release'
|
63
|
+
archive_action.attributes['revealArchiveInOrganizer'] = 'YES'
|
64
|
+
end
|
134
65
|
|
135
|
-
|
136
|
-
profile_action.attributes['shouldUseLaunchSchemeArgsEnv'] = 'YES'
|
137
|
-
profile_action.attributes['savedToolIdentifier'] = ''
|
138
|
-
profile_action.attributes['useCustomWorkingDirectory'] = 'NO'
|
139
|
-
profile_action.attributes['buildConfiguration'] = 'Release'
|
140
|
-
profile_action.attributes['debugDocumentVersioning'] = 'YES'
|
66
|
+
public
|
141
67
|
|
142
|
-
|
143
|
-
buildable_product_runnable = profile_action.add_element 'BuildableProductRunnable'
|
68
|
+
# @!group Target methods
|
144
69
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
70
|
+
# Add a target to the list of targets to build in the build action.
|
71
|
+
#
|
72
|
+
# @param [Xcodeproj::Project::Object::AbstractTarget] build_target
|
73
|
+
# A target used by scheme in the build step.
|
74
|
+
#
|
75
|
+
# @param [Bool] build_for_running
|
76
|
+
# Whether to build this target in the launch action. Often false for test targets.
|
77
|
+
#
|
78
|
+
def add_build_target(build_target, build_for_running = true)
|
79
|
+
if !@build_action_entries then
|
80
|
+
@build_action_entries = @build_action.add_element 'BuildActionEntries'
|
151
81
|
end
|
152
82
|
|
153
|
-
|
154
|
-
|
83
|
+
build_action_entry = @build_action_entries.add_element 'BuildActionEntry'
|
84
|
+
build_action_entry.attributes['buildForTesting'] = 'YES'
|
85
|
+
build_action_entry.attributes['buildForRunning'] = build_for_running ? 'YES' : 'NO'
|
86
|
+
build_action_entry.attributes['buildForProfiling'] = 'YES'
|
87
|
+
build_action_entry.attributes['buildForArchiving'] = 'YES'
|
88
|
+
build_action_entry.attributes['buildForAnalyzing'] = 'YES'
|
89
|
+
|
90
|
+
buildable_reference = build_action_entry.add_element 'BuildableReference'
|
91
|
+
buildable_reference.attributes['BuildableIdentifier'] = 'primary'
|
92
|
+
buildable_reference.attributes['BlueprintIdentifier'] = build_target.uuid
|
93
|
+
buildable_reference.attributes['BuildableName'] = File.basename(build_target.product_reference.path)
|
94
|
+
buildable_reference.attributes['BlueprintName'] = build_target.name
|
95
|
+
buildable_reference.attributes['ReferencedContainer'] = "container:#{build_target.project.path.basename}"
|
96
|
+
end
|
155
97
|
|
156
|
-
|
157
|
-
|
158
|
-
|
98
|
+
# Add a target to the list of targets to build in the build action.
|
99
|
+
#
|
100
|
+
# @param [Xcodeproj::Project::Object::AbstractTarget] test_target
|
101
|
+
# A target used by scheme in the test step.
|
102
|
+
#
|
103
|
+
def add_test_target(test_target)
|
104
|
+
testable_reference = @testables.add_element 'TestableReference'
|
105
|
+
testable_reference.attributes['skipped'] = 'NO'
|
106
|
+
|
107
|
+
buildable_reference = testable_reference.add_element 'BuildableReference'
|
108
|
+
buildable_reference.attributes['BuildableIdentifier'] = 'primary'
|
109
|
+
buildable_reference.attributes['BlueprintIdentifier'] = test_target.uuid
|
110
|
+
buildable_reference.attributes['BuildableName'] = "#{test_target.name}.octest"
|
111
|
+
buildable_reference.attributes['BlueprintName'] = test_target.name
|
112
|
+
buildable_reference.attributes['ReferencedContainer'] = "container:#{test_target.project.path.basename}"
|
159
113
|
end
|
160
114
|
|
161
|
-
|
115
|
+
# Sets a runnable target target to be the target of the launch action of the scheme.
|
116
|
+
#
|
117
|
+
# @param [Xcodeproj::Project::Object::AbstractTarget] build_target
|
118
|
+
# A target used by scheme in the launch step.
|
119
|
+
#
|
120
|
+
def set_launch_target(build_target)
|
121
|
+
launch_product_runnable = @launch_action.add_element 'BuildableProductRunnable'
|
122
|
+
|
123
|
+
launch_buildable_reference = launch_product_runnable.add_element 'BuildableReference'
|
124
|
+
launch_buildable_reference.attributes['BuildableIdentifier'] = 'primary'
|
125
|
+
launch_buildable_reference.attributes['BlueprintIdentifier'] = build_target.uuid
|
126
|
+
launch_buildable_reference.attributes['BuildableName'] = "#{build_target.name}.app"
|
127
|
+
launch_buildable_reference.attributes['BlueprintName'] = build_target.name
|
128
|
+
launch_buildable_reference.attributes['ReferencedContainer'] = "container:#{build_target.project.path.basename}"
|
129
|
+
|
130
|
+
profile_product_runnable = @profile_action.add_element 'BuildableProductRunnable'
|
131
|
+
|
132
|
+
profile_buildable_reference = profile_product_runnable.add_element 'BuildableReference'
|
133
|
+
profile_buildable_reference.attributes['BuildableIdentifier'] = 'primary'
|
134
|
+
profile_buildable_reference.attributes['BlueprintIdentifier'] = build_target.uuid
|
135
|
+
profile_buildable_reference.attributes['BuildableName'] = "#{build_target.name}.app"
|
136
|
+
profile_buildable_reference.attributes['BlueprintName'] = build_target.name
|
137
|
+
profile_buildable_reference.attributes['ReferencedContainer'] = "container:#{build_target.project.path.basename}"
|
138
|
+
|
139
|
+
macro_expansion = @test_action.add_element 'MacroExpansion'
|
140
|
+
|
141
|
+
buildable_reference = macro_expansion.add_element 'BuildableReference'
|
142
|
+
buildable_reference.attributes['BuildableIdentifier'] = 'primary'
|
143
|
+
buildable_reference.attributes['BlueprintIdentifier'] = build_target.uuid
|
144
|
+
buildable_reference.attributes['BuildableName'] = File.basename(build_target.product_reference.path)
|
145
|
+
buildable_reference.attributes['BlueprintName'] = build_target.name
|
146
|
+
buildable_reference.attributes['ReferencedContainer'] = "container:#{build_target.project.path.basename}"
|
147
|
+
end
|
162
148
|
|
163
149
|
# @!group Class methods
|
164
150
|
|
@@ -201,84 +187,24 @@ module Xcodeproj
|
|
201
187
|
|
202
188
|
public
|
203
189
|
|
204
|
-
# @!group
|
205
|
-
|
206
|
-
#-------------------------------------------------------------------------#
|
207
|
-
|
208
|
-
# Returns the current value if the build target must be runned during the
|
209
|
-
# build step.
|
210
|
-
#
|
211
|
-
# @return [Boolean]
|
212
|
-
# true => run during the build step
|
213
|
-
# false => not run during the build step
|
214
|
-
#
|
215
|
-
def build_target_for_running?
|
216
|
-
build_target_for_running = ''
|
217
|
-
|
218
|
-
if build_action = @doc.root.elements['BuildAction']
|
219
|
-
if build_action_entries = build_action.elements['BuildActionEntries']
|
220
|
-
if build_action_entry = build_action_entries.elements['BuildActionEntry']
|
221
|
-
build_target_for_running = build_action_entry.attributes['buildForRunning']
|
222
|
-
end
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
build_target_for_running == 'YES'
|
227
|
-
end
|
228
|
-
|
229
|
-
# Set the build target to run or not run during the build step. Useful for
|
230
|
-
# cases where the build target is a unit test bundle.
|
231
|
-
#
|
232
|
-
# @param [Boolean] build_target_for_running
|
233
|
-
# true => run during the build step
|
234
|
-
# false => not run during the build step
|
235
|
-
#
|
236
|
-
def build_target_for_running=(build_target_for_running)
|
237
|
-
build_action = @doc.root.elements['BuildAction']
|
238
|
-
|
239
|
-
if (build_action.elements['BuildActionEntries'] == nil) then
|
240
|
-
build_action_entries = build_action.add_element('BuildActionEntries')
|
241
|
-
else
|
242
|
-
build_action_entries = build_action.elements['BuildActionEntries']
|
243
|
-
end
|
244
|
-
|
245
|
-
if (build_action_entries.elements['BuildActionEntry'] == nil) then
|
246
|
-
build_action_entry = build_action_entries.add_element 'BuildActionEntry'
|
247
|
-
build_action_entry.attributes['buildForTesting'] = 'YES'
|
248
|
-
build_action_entry.attributes['buildForProfiling'] = 'NO'
|
249
|
-
build_action_entry.attributes['buildForArchiving'] = 'NO'
|
250
|
-
build_action_entry.attributes['buildForAnalyzing'] = 'NO'
|
251
|
-
else
|
252
|
-
build_action_entry = build_action_entries.elements['BuildActionEntry']
|
253
|
-
end
|
254
|
-
|
255
|
-
build_action_entry.attributes['buildForRunning'] = build_target_for_running ? 'YES' : 'NO'
|
256
|
-
|
257
|
-
if (build_action_entry.elements['BuildableReference'] == nil) then
|
258
|
-
buildable_reference = build_action_entry.add_element 'BuildableReference'
|
259
|
-
buildable_reference.attributes['BuildableIdentifier'] = 'primary'
|
260
|
-
buildable_reference.attributes['BlueprintIdentifier'] = build_target.uuid
|
261
|
-
buildable_reference.attributes['BuildableName'] = "#{build_target.name}.octest"
|
262
|
-
buildable_reference.attributes['BlueprintName'] = build_target.name
|
263
|
-
buildable_reference.attributes['ReferencedContainer'] = "container:#{container}.xcodeproj"
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
public
|
268
|
-
|
269
190
|
# @!group Serialization
|
270
191
|
|
271
192
|
#-------------------------------------------------------------------------#
|
272
193
|
|
273
194
|
# Serializes the current state of the object to a String.
|
274
195
|
#
|
196
|
+
# @note The goal of the string representation is to match Xcode output as
|
197
|
+
# close as possible to aide comparison.
|
198
|
+
#
|
275
199
|
# @return [String] the XML string value of the current state of the object.
|
276
200
|
#
|
277
201
|
def to_s
|
278
|
-
formatter =
|
279
|
-
formatter.compact =
|
202
|
+
formatter = XML_Fromatter.new(2)
|
203
|
+
formatter.compact = false
|
280
204
|
out = ''
|
281
205
|
formatter.write(@doc, out)
|
206
|
+
out.gsub!("<?xml version='1.0' encoding='UTF-8'?>", '<?xml version="1.0" encoding="UTF-8"?>')
|
207
|
+
out << "\n"
|
282
208
|
out
|
283
209
|
end
|
284
210
|
|
@@ -287,6 +213,9 @@ module Xcodeproj
|
|
287
213
|
# @param [String, Pathname] project_path
|
288
214
|
# The path where the ".xcscheme" file should be stored.
|
289
215
|
#
|
216
|
+
# @param [String] name
|
217
|
+
# The name of the scheme, to have ".xcscheme" appended.
|
218
|
+
#
|
290
219
|
# @param [Boolean] shared
|
291
220
|
# true => if the scheme must be a shared scheme (default value)
|
292
221
|
# false => if the scheme must be a user scheme
|
@@ -296,14 +225,14 @@ module Xcodeproj
|
|
296
225
|
# @example Saving a scheme
|
297
226
|
# scheme.save_as('path/to/Project.xcodeproj') #=> true
|
298
227
|
#
|
299
|
-
def save_as(project_path, shared = true)
|
228
|
+
def save_as(project_path, name, shared = true)
|
300
229
|
if shared
|
301
230
|
scheme_folder_path = self.class.shared_data_dir(project_path)
|
302
231
|
else
|
303
232
|
scheme_folder_path = self.class.user_data_dir(project_path)
|
304
233
|
end
|
305
234
|
scheme_folder_path.mkpath
|
306
|
-
scheme_path = scheme_folder_path + "#{
|
235
|
+
scheme_path = scheme_folder_path + "#{name}.xcscheme"
|
307
236
|
File.open(scheme_path, 'w') do |f|
|
308
237
|
f.write(to_s)
|
309
238
|
end
|
@@ -311,5 +240,36 @@ module Xcodeproj
|
|
311
240
|
|
312
241
|
#-------------------------------------------------------------------------#
|
313
242
|
|
243
|
+
# XML formatter which closely mimics the output generated by Xcode.
|
244
|
+
#
|
245
|
+
class XML_Fromatter < REXML::Formatters::Pretty
|
246
|
+
def write_element(node, output)
|
247
|
+
@indentation = 3
|
248
|
+
output << ' '*@level
|
249
|
+
output << "<#{node.expanded_name}"
|
250
|
+
|
251
|
+
@level += @indentation
|
252
|
+
node.attributes.each_attribute do |attr|
|
253
|
+
output << "\n"
|
254
|
+
output << ' '*@level
|
255
|
+
output << attr.to_string.gsub(/=/, ' = ')
|
256
|
+
end unless node.attributes.empty?
|
257
|
+
|
258
|
+
output << ">"
|
259
|
+
|
260
|
+
output << "\n"
|
261
|
+
node.children.each { |child|
|
262
|
+
next if child.kind_of?(REXML::Text) and child.to_s.strip.length == 0
|
263
|
+
write(child, output)
|
264
|
+
output << "\n"
|
265
|
+
}
|
266
|
+
@level -= @indentation
|
267
|
+
output << ' '*@level
|
268
|
+
output << "</#{node.expanded_name}>"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
#-------------------------------------------------------------------------#
|
273
|
+
|
314
274
|
end
|
315
275
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xcodeproj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eloy Duran
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|