xcodeproj 0.11.1 → 0.12.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.
- 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
|