xcodeproj 0.4.0.rc2 → 0.4.0.rc3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/xcodeproj.rb +1 -1
- data/lib/xcodeproj/constants.rb +25 -19
- data/lib/xcodeproj/project.rb +1 -0
- data/lib/xcodeproj/project/object.rb +43 -4
- data/lib/xcodeproj/project/object/aggregate_target.rb +0 -0
- data/lib/xcodeproj/project/object/build_phase.rb +37 -2
- data/lib/xcodeproj/project/object/container_item_proxy.rb +24 -5
- data/lib/xcodeproj/project/object/group.rb +12 -2
- data/lib/xcodeproj/project/object/native_target.rb +120 -65
- data/lib/xcodeproj/project/object/reference_proxy.rb +35 -0
- data/lib/xcodeproj/project/object/root_object.rb +8 -1
- data/lib/xcodeproj/project/object_attributes.rb +45 -0
- data/lib/xcodeproj/project/object_dictionary.rb +191 -0
- data/lib/xcodeproj/project/object_list.rb +59 -9
- metadata +6 -3
data/lib/xcodeproj.rb
CHANGED
data/lib/xcodeproj/constants.rb
CHANGED
@@ -16,31 +16,37 @@ module Xcodeproj
|
|
16
16
|
#
|
17
17
|
KNOWN_ISAS = {
|
18
18
|
'AbstractObject' => %w[
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
19
|
+
PBXBuildFile
|
20
|
+
AbstractBuildPhase
|
21
|
+
PBXBuildRule
|
22
|
+
XCBuildConfiguration
|
23
|
+
XCConfigurationList
|
24
|
+
PBXContainerItemProxy
|
25
|
+
PBXFileReference
|
26
|
+
PBXGroup
|
27
|
+
PBXProject
|
28
|
+
PBXTargetDependency
|
29
|
+
PBXReferenceProxy
|
30
30
|
],
|
31
31
|
|
32
32
|
'AbstractBuildPhase' => %w[
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
PBXCopyFilesBuildPhase
|
34
|
+
PBXResourcesBuildPhase
|
35
|
+
PBXSourcesBuildPhase
|
36
|
+
PBXFrameworksBuildPhase
|
37
|
+
PBXHeadersBuildPhase
|
38
|
+
PBXShellScriptBuildPhase
|
39
|
+
],
|
40
|
+
|
41
|
+
'AbstractTarget' => %w[
|
42
|
+
PBXNativeTarget
|
43
|
+
PBXAggregateTarget
|
44
|
+
PBXLegacyTarget
|
39
45
|
],
|
40
46
|
|
41
47
|
'PBXGroup' => %w[
|
42
|
-
|
43
|
-
|
48
|
+
XCVersionGroup
|
49
|
+
PBXVariantGroup
|
44
50
|
]
|
45
51
|
}.freeze
|
46
52
|
|
data/lib/xcodeproj/project.rb
CHANGED
@@ -176,6 +176,7 @@ module Xcodeproj
|
|
176
176
|
#
|
177
177
|
def new_from_plist(uuid, objects_by_uuid_plist, root_object = false)
|
178
178
|
attributes = objects_by_uuid_plist[uuid]
|
179
|
+
raise "[Xcodeproj] Unable to find attributes for UUID #{uuid}" unless attributes
|
179
180
|
klass = Object.const_get(attributes['isa'])
|
180
181
|
object = klass.new(self, uuid)
|
181
182
|
object.add_referrer(self) if root_object
|
@@ -156,6 +156,11 @@ module Xcodeproj
|
|
156
156
|
list = attrb.get_value(self)
|
157
157
|
list.delete(object)
|
158
158
|
end
|
159
|
+
|
160
|
+
references_by_keys_attributes.each do |attrb|
|
161
|
+
list = attrb.get_value(self)
|
162
|
+
list.each { |dictionary| dictionary.remove_reference(object) }
|
163
|
+
end
|
159
164
|
end
|
160
165
|
|
161
166
|
# @!group Plist related methods
|
@@ -191,12 +196,25 @@ module Xcodeproj
|
|
191
196
|
to_many_attributes.each do |attrb|
|
192
197
|
ref_uuids = object_plist[attrb.plist_name] || []
|
193
198
|
list = attrb.get_value(self)
|
194
|
-
ref_uuids.each do |
|
195
|
-
|
196
|
-
|
199
|
+
ref_uuids.each do |uuid|
|
200
|
+
list << object_with_uuid(uuid, objects_by_uuid_plist)
|
201
|
+
end
|
202
|
+
object_plist.delete(attrb.plist_name)
|
203
|
+
end
|
204
|
+
|
205
|
+
references_by_keys_attributes.each do |attrb|
|
206
|
+
hashes = object_plist[attrb.plist_name] || {}
|
207
|
+
list = attrb.get_value(self)
|
208
|
+
hashes.each do |hash|
|
209
|
+
dictionary = ObjectDictionary.new(attrb, self)
|
210
|
+
hash.each do |key, uuid|
|
211
|
+
dictionary[key] = object_with_uuid(uuid, objects_by_uuid_plist)
|
212
|
+
end
|
213
|
+
list << dictionary
|
197
214
|
end
|
198
215
|
object_plist.delete(attrb.plist_name)
|
199
216
|
end
|
217
|
+
|
200
218
|
unless object_plist.empty?
|
201
219
|
raise "[!] Xcodeproj doesn't know about the following attributes " \
|
202
220
|
"#{object_plist} for the '#{isa}' isa.\n" \
|
@@ -204,6 +222,15 @@ module Xcodeproj
|
|
204
222
|
end
|
205
223
|
end
|
206
224
|
|
225
|
+
def object_with_uuid(uuid, objects_by_uuid_plist)
|
226
|
+
project.objects_by_uuid[uuid] || project.new_from_plist(uuid, objects_by_uuid_plist)
|
227
|
+
rescue NameError => exception
|
228
|
+
attributes = objects_by_uuid_plist[uuid]
|
229
|
+
raise "`#{isa}` attempted to initialize an object with unknown ISA "\
|
230
|
+
"`#{attributes['isa']}` from attributes: `#{attributes}`\n" \
|
231
|
+
"Please file and issue: https://github.com/CocoaPods/Xcodeproj/issues/new"
|
232
|
+
end
|
233
|
+
|
207
234
|
# @note the key for simple and to_one attributes usually appears only
|
208
235
|
# if there is a value. To many keys always appear with an empty
|
209
236
|
# array.
|
@@ -227,6 +254,11 @@ module Xcodeproj
|
|
227
254
|
plist[attrb.plist_name] = list.uuids
|
228
255
|
end
|
229
256
|
|
257
|
+
references_by_keys_attributes.each do |attrb|
|
258
|
+
list = attrb.get_value(self)
|
259
|
+
plist[attrb.plist_name] = list.map { |dictionary| dictionary.to_plist }
|
260
|
+
end
|
261
|
+
|
230
262
|
plist
|
231
263
|
end
|
232
264
|
alias :to_hash :to_plist
|
@@ -262,6 +294,11 @@ module Xcodeproj
|
|
262
294
|
hash[attrb.plist_name] = list.map { |obj| obj.to_tree_hash }
|
263
295
|
end
|
264
296
|
|
297
|
+
references_by_keys_attributes.each do |attrb|
|
298
|
+
list = attrb.get_value(self)
|
299
|
+
hash[attrb.plist_name] = list.map { |dictionary| dictionary.to_tree_hash }
|
300
|
+
end
|
301
|
+
|
265
302
|
hash
|
266
303
|
end
|
267
304
|
|
@@ -285,8 +322,9 @@ module Xcodeproj
|
|
285
322
|
end
|
286
323
|
end
|
287
324
|
|
288
|
-
require 'xcodeproj/project/object_attributes'
|
289
325
|
require 'xcodeproj/project/object_list'
|
326
|
+
require 'xcodeproj/project/object_dictionary'
|
327
|
+
require 'xcodeproj/project/object_attributes'
|
290
328
|
|
291
329
|
# Required because some classes have cyclical references to each other.
|
292
330
|
#
|
@@ -317,4 +355,5 @@ require 'xcodeproj/project/object/group'
|
|
317
355
|
require 'xcodeproj/project/object/native_target'
|
318
356
|
require 'xcodeproj/project/object/root_object'
|
319
357
|
require 'xcodeproj/project/object/target_dependency'
|
358
|
+
require 'xcodeproj/project/object/reference_proxy'
|
320
359
|
|
File without changes
|
@@ -121,6 +121,12 @@ module Xcodeproj
|
|
121
121
|
|
122
122
|
end
|
123
123
|
|
124
|
+
# Apparently a build phase named `Build Carbon Resources` (Observed for
|
125
|
+
# kernel extensions targets).
|
126
|
+
#
|
127
|
+
class PBXRezBuildPhase < AbstractBuildPhase
|
128
|
+
end
|
129
|
+
|
124
130
|
class AbstractBuildPhase < AbstractObject
|
125
131
|
|
126
132
|
## CONVENIENCE METHODS #################################################
|
@@ -148,13 +154,42 @@ module Xcodeproj
|
|
148
154
|
files << build_file
|
149
155
|
build_file
|
150
156
|
end
|
151
|
-
|
157
|
+
|
158
|
+
# Removes the build file associated with the given file reference from
|
159
|
+
# the phase.
|
160
|
+
#
|
161
|
+
# @param [PBXFileReference] file the file to remove
|
162
|
+
#
|
163
|
+
# @return [void]
|
164
|
+
#
|
152
165
|
def remove_file_reference(file)
|
153
166
|
build_file = files.find { |bf| bf.file_ref == file }
|
154
|
-
files.delete(build_file)
|
155
167
|
build_file.file_ref = nil
|
156
168
|
build_file.remove_from_project
|
157
169
|
end
|
170
|
+
|
171
|
+
# Removes a build file from the phase and clears its relationship to
|
172
|
+
# the file reference.
|
173
|
+
#
|
174
|
+
# @param [PBXBuildFile] file the file to remove
|
175
|
+
#
|
176
|
+
# @return [void]
|
177
|
+
#
|
178
|
+
def remove_build_file(build_file)
|
179
|
+
build_file.file_ref = nil
|
180
|
+
build_file.remove_from_project
|
181
|
+
end
|
182
|
+
|
183
|
+
# Removes all the build files from the phase and clears their
|
184
|
+
# relationship to the file reference.
|
185
|
+
#
|
186
|
+
# @return [void]
|
187
|
+
#
|
188
|
+
def clear_build_files
|
189
|
+
files.objects.each do |bf|
|
190
|
+
remove_build_file(bf)
|
191
|
+
end
|
192
|
+
end
|
158
193
|
end
|
159
194
|
end
|
160
195
|
end
|
@@ -8,21 +8,32 @@ module Xcodeproj
|
|
8
8
|
# This class is referenced by {PBXTargetDependency}; for information
|
9
9
|
# about it usage see the specs of that class.
|
10
10
|
#
|
11
|
-
# @note This class references the other objects by
|
11
|
+
# @note This class references the other objects by UUID instead of
|
12
12
|
# creating proper relationships because the other objects might be
|
13
13
|
# part of another project. This implies that the references to
|
14
|
-
# other objects should not increase the retain
|
14
|
+
# other objects should not increase the retain count of the
|
15
15
|
# targets.
|
16
16
|
#
|
17
|
-
# @todo: this class needs some work to support targets
|
17
|
+
# @todo: this class needs some work to support targets across workspaces,
|
18
18
|
# as the container portal might not be initialized leading
|
19
|
-
#
|
19
|
+
# xcodeproj to raise because ti can't find the UUID.
|
20
20
|
#
|
21
21
|
class PBXContainerItemProxy < AbstractObject
|
22
22
|
|
23
23
|
# @return [String] apparently the UUID of the root object
|
24
24
|
# {PBXProject} of the project containing the represented object.
|
25
25
|
#
|
26
|
+
# @todo this is an attribute because a it is usually a reference to the
|
27
|
+
# root object or to a file reference to another project. The
|
28
|
+
# reference to the root object causes a retain cycle that could
|
29
|
+
# cause issues (e.g. in to_tree_hash). Usually those objects are
|
30
|
+
# retained by at least another object (the {Project} for the root
|
31
|
+
# object and a {PBXGroup} for the reference to another project)
|
32
|
+
# and so the referenced object should be serialized.
|
33
|
+
#
|
34
|
+
# If this assumption is incorrect, there could be loss of
|
35
|
+
# information opening and saving an existing project.
|
36
|
+
#
|
26
37
|
attribute :container_portal, String
|
27
38
|
|
28
39
|
# @return [String] the type of the proxy.
|
@@ -34,7 +45,15 @@ module Xcodeproj
|
|
34
45
|
# @return [String] apparently the UUID of the represented
|
35
46
|
# object.
|
36
47
|
#
|
37
|
-
# @note If the object is in another project
|
48
|
+
# @note If the object is in another project the UUID would not be
|
49
|
+
# present in the {Project#objects_by_uuid} hash. For this reason
|
50
|
+
# this is not an `has_one` attribute. It is assumes that if the
|
51
|
+
# object belongs to the project at least another object should be
|
52
|
+
# retaining it. This assumption is reasonable because this is a
|
53
|
+
# proxy class.
|
54
|
+
#
|
55
|
+
# If this assumption is incorrect, there could be loss of
|
56
|
+
# information opening and saving an existing project.
|
38
57
|
#
|
39
58
|
attribute :remote_global_id_string, String
|
40
59
|
|
@@ -10,7 +10,7 @@ module Xcodeproj
|
|
10
10
|
# @return [ObjectList<PBXGroup, PBXFileReference>]
|
11
11
|
# the objects contained by the group.
|
12
12
|
#
|
13
|
-
has_many :children, [PBXGroup, PBXFileReference]
|
13
|
+
has_many :children, [PBXGroup, PBXFileReference, PBXReferenceProxy]
|
14
14
|
|
15
15
|
# @return [String] the source tree to which this group is relative.
|
16
16
|
#
|
@@ -57,7 +57,7 @@ module Xcodeproj
|
|
57
57
|
|
58
58
|
end
|
59
59
|
|
60
|
-
#
|
60
|
+
# This class is used to gather localized files into one entry.
|
61
61
|
#
|
62
62
|
class PBXVariantGroup < PBXGroup
|
63
63
|
|
@@ -209,6 +209,16 @@ module Xcodeproj
|
|
209
209
|
find_subpath(path)
|
210
210
|
end
|
211
211
|
|
212
|
+
# Removes children files and groups under this group.
|
213
|
+
#
|
214
|
+
def remove_children_recursively
|
215
|
+
groups.each do |g|
|
216
|
+
g.remove_children_recursively
|
217
|
+
g.remove_from_project
|
218
|
+
end
|
219
|
+
files.each { |f| f.remove_from_project }
|
220
|
+
end
|
221
|
+
|
212
222
|
# Traverses the children groups and finds the children with the given
|
213
223
|
# path, optionally, creating any needed group. If the given path is
|
214
224
|
# `nil` it returns itself.
|
@@ -2,20 +2,48 @@ module Xcodeproj
|
|
2
2
|
class Project
|
3
3
|
module Object
|
4
4
|
|
5
|
-
|
6
|
-
#
|
7
|
-
class PBXNativeTarget < AbstractObject
|
5
|
+
class AbstractTarget < AbstractObject
|
8
6
|
|
9
7
|
# @return [String] The name of the Target.
|
10
8
|
#
|
11
9
|
attribute :name, String
|
12
10
|
|
11
|
+
# @return [String] the name of the build product.
|
12
|
+
#
|
13
|
+
attribute :product_name, String
|
14
|
+
|
13
15
|
# @return [XCConfigurationList] the list of the build configurations of
|
14
16
|
# the target. This list commonly include two configurations `Debug`
|
15
17
|
# and `Release`.
|
16
18
|
#
|
17
19
|
has_one :build_configuration_list, XCConfigurationList
|
18
20
|
|
21
|
+
# @return [PBXNativeTarget] the targets necessary to build this target.
|
22
|
+
#
|
23
|
+
has_many :dependencies, PBXTargetDependency
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
# Represents a target handled by Xcode.
|
28
|
+
#
|
29
|
+
class PBXNativeTarget < AbstractTarget
|
30
|
+
|
31
|
+
# @return [PBXBuildRule] the build rules of this target.
|
32
|
+
#
|
33
|
+
has_many :build_rules, PBXBuildRule
|
34
|
+
|
35
|
+
# @return [String] the build product type identifier.
|
36
|
+
#
|
37
|
+
attribute :product_type, String, 'com.apple.product-type.library.static'
|
38
|
+
|
39
|
+
# @return [PBXFileReference] the reference to the product file.
|
40
|
+
#
|
41
|
+
has_one :product_reference, PBXFileReference
|
42
|
+
|
43
|
+
# @return [String] the install path of the product.
|
44
|
+
#
|
45
|
+
attribute :product_install_path, String
|
46
|
+
|
19
47
|
# @return [PBXBuildRule] the build phases of the target.
|
20
48
|
#
|
21
49
|
# @note Apparently only PBXCopyFilesBuildPhase and
|
@@ -23,31 +51,58 @@ module Xcodeproj
|
|
23
51
|
#
|
24
52
|
has_many :build_phases, AbstractBuildPhase
|
25
53
|
|
26
|
-
|
54
|
+
end
|
55
|
+
|
56
|
+
# Represents a target that only consists in a aggregate of targets.
|
57
|
+
#
|
58
|
+
# @todo apparently it can't have build rules.
|
59
|
+
#
|
60
|
+
class PBXAggregateTarget < AbstractTarget
|
61
|
+
|
62
|
+
# @return [PBXBuildRule] the build phases of the target.
|
27
63
|
#
|
28
|
-
|
64
|
+
# @note Apparently only PBXCopyFilesBuildPhase and
|
65
|
+
# PBXShellScriptBuildPhase can appear multiple times in a target.
|
66
|
+
#
|
67
|
+
has_many :build_phases, [ PBXCopyFilesBuildPhase, PBXShellScriptBuildPhase ]
|
29
68
|
|
30
|
-
|
69
|
+
end
|
70
|
+
|
71
|
+
# Represents a legacy target which uses an external build tool.
|
72
|
+
#
|
73
|
+
# Apparently it can't have any build phase but the attribute can be
|
74
|
+
# present.
|
75
|
+
#
|
76
|
+
class PBXLegacyTarget < AbstractTarget
|
77
|
+
|
78
|
+
# @return [String] e.g "Dir"
|
31
79
|
#
|
32
|
-
|
80
|
+
attribute :build_working_directory, String
|
33
81
|
|
34
|
-
# @return [String]
|
82
|
+
# @return [String] e.g "$(ACTION)"
|
35
83
|
#
|
36
|
-
attribute :
|
84
|
+
attribute :build_arguments_string, String
|
37
85
|
|
38
|
-
# @return [String]
|
86
|
+
# @return [String] e.g "1"
|
39
87
|
#
|
40
|
-
attribute :
|
88
|
+
attribute :pass_build_settings_in_environment, String
|
41
89
|
|
42
|
-
# @return [
|
90
|
+
# @return [String] e.g "/usr/bin/make"
|
43
91
|
#
|
44
|
-
|
92
|
+
attribute :build_tool_path, String
|
45
93
|
|
46
|
-
# @return [
|
94
|
+
# @return [PBXBuildRule] the build phases of the target.
|
47
95
|
#
|
48
|
-
|
96
|
+
# @note Apparently only PBXCopyFilesBuildPhase and
|
97
|
+
# PBXShellScriptBuildPhase can appear multiple times in a target.
|
98
|
+
#
|
99
|
+
has_many :build_phases, AbstractBuildPhase
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
#----------------------------------------------------------------------#
|
49
104
|
|
50
|
-
|
105
|
+
class AbstractTarget < AbstractObject
|
51
106
|
|
52
107
|
# @!group Convenience methods
|
53
108
|
|
@@ -68,6 +123,54 @@ module Xcodeproj
|
|
68
123
|
build_configuration_list.build_settings(build_configuration_name)
|
69
124
|
end
|
70
125
|
|
126
|
+
|
127
|
+
# @return [Array<PBXCopyFilesBuildPhase>]
|
128
|
+
# the copy files build phases of the target.
|
129
|
+
#
|
130
|
+
def copy_files_build_phases
|
131
|
+
build_phases.select { |bp| bp.class == PBXCopyFilesBuildPhase }
|
132
|
+
end
|
133
|
+
|
134
|
+
# @return [Array<PBXShellScriptBuildPhase>]
|
135
|
+
# the copy files build phases of the target.
|
136
|
+
#
|
137
|
+
def shell_script_build_phases
|
138
|
+
build_phases.select { |bp| bp.class == PBXShellScriptBuildPhase }
|
139
|
+
end
|
140
|
+
|
141
|
+
# Creates a new copy files build phase.
|
142
|
+
#
|
143
|
+
# @param [String] name
|
144
|
+
# an optional name for the phase.
|
145
|
+
#
|
146
|
+
# @return [PBXCopyFilesBuildPhase] the new phase.
|
147
|
+
#
|
148
|
+
def new_copy_files_build_phase(name = nil)
|
149
|
+
phase = project.new(PBXCopyFilesBuildPhase)
|
150
|
+
phase.name = name
|
151
|
+
build_phases << phase
|
152
|
+
phase
|
153
|
+
end
|
154
|
+
|
155
|
+
# Creates a new shell script build phase.
|
156
|
+
#
|
157
|
+
# @param (see #new_copy_files_build_phase)
|
158
|
+
#
|
159
|
+
# @return [PBXShellScriptBuildPhase] the new phase.
|
160
|
+
#
|
161
|
+
def new_shell_script_build_phase(name = nil)
|
162
|
+
phase = project.new(PBXShellScriptBuildPhase)
|
163
|
+
phase.name = name
|
164
|
+
build_phases << phase
|
165
|
+
phase
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
class PBXNativeTarget < AbstractTarget
|
171
|
+
|
172
|
+
# @!group Convenience methods
|
173
|
+
|
71
174
|
# Adds source files to the target.
|
72
175
|
#
|
73
176
|
# @param [Array<PBXFileReference>] file_references
|
@@ -88,8 +191,7 @@ module Xcodeproj
|
|
88
191
|
header_extensions = Constants::HEADER_FILES_EXTENSIONS
|
89
192
|
if (header_extensions.include?(extension))
|
90
193
|
build_file.settings = { 'ATTRIBUTES' => ["Public"] }
|
91
|
-
|
92
|
-
phase.files << build_file
|
194
|
+
headers_build_phase.files << build_file
|
93
195
|
else
|
94
196
|
build_file.settings = { 'COMPILER_FLAGS' => compiler_flags } if compiler_flags && !compiler_flags.empty?
|
95
197
|
source_build_phase.files << build_file
|
@@ -97,9 +199,6 @@ module Xcodeproj
|
|
97
199
|
end
|
98
200
|
end
|
99
201
|
|
100
|
-
|
101
|
-
# @!group Accessing build phases
|
102
|
-
|
103
202
|
# Finds or creates the headers build phase of the target.
|
104
203
|
#
|
105
204
|
# @note A target should have only one headers build phase.
|
@@ -169,50 +268,6 @@ module Xcodeproj
|
|
169
268
|
end
|
170
269
|
bp
|
171
270
|
end
|
172
|
-
|
173
|
-
# @return [Array<PBXCopyFilesBuildPhase>]
|
174
|
-
# the copy files build phases of the target.
|
175
|
-
#
|
176
|
-
def copy_files_build_phases
|
177
|
-
build_phases.select { |bp| bp.class == PBXCopyFilesBuildPhase }
|
178
|
-
end
|
179
|
-
|
180
|
-
# @return [Array<PBXShellScriptBuildPhase>]
|
181
|
-
# the copy files build phases of the target.
|
182
|
-
#
|
183
|
-
def shell_script_build_phases
|
184
|
-
build_phases.select { |bp| bp.class == PBXShellScriptBuildPhase }
|
185
|
-
end
|
186
|
-
|
187
|
-
|
188
|
-
# @!group Creating build phases
|
189
|
-
|
190
|
-
# Creates a new copy files build phase.
|
191
|
-
#
|
192
|
-
# @param [String] name
|
193
|
-
# an optional name for the pahse.
|
194
|
-
#
|
195
|
-
# @return [PBXCopyFilesBuildPhase] the new phase.
|
196
|
-
#
|
197
|
-
def new_copy_files_build_phase(name = nil)
|
198
|
-
phase = project.new(PBXCopyFilesBuildPhase)
|
199
|
-
phase.name = name
|
200
|
-
build_phases << phase
|
201
|
-
phase
|
202
|
-
end
|
203
|
-
|
204
|
-
# Creates a new shell script build phase.
|
205
|
-
#
|
206
|
-
# @param (see #new_copy_files_build_phase)
|
207
|
-
#
|
208
|
-
# @return [PBXShellScriptBuildPhase] the new phase.
|
209
|
-
#
|
210
|
-
def new_shell_script_build_phase(name = nil)
|
211
|
-
phase = project.new(PBXShellScriptBuildPhase)
|
212
|
-
phase.name = name
|
213
|
-
build_phases << phase
|
214
|
-
phase
|
215
|
-
end
|
216
271
|
end
|
217
272
|
end
|
218
273
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
class Project
|
3
|
+
module Object
|
4
|
+
|
5
|
+
# Apparently a proxy for a reference object which might belong another
|
6
|
+
# project contained in the same workspace of the project document.
|
7
|
+
#
|
8
|
+
# This class is used for referencing the products of another project.
|
9
|
+
#
|
10
|
+
class PBXReferenceProxy < AbstractObject
|
11
|
+
|
12
|
+
# @return [String] the path of the referenced filed.
|
13
|
+
#
|
14
|
+
attribute :path, String
|
15
|
+
|
16
|
+
# @return [String] the file type of the referenced filed.
|
17
|
+
#
|
18
|
+
attribute :file_type, String
|
19
|
+
|
20
|
+
# @return [PBXContainerItemProxy] the proxy to the project that
|
21
|
+
# contains the object.
|
22
|
+
#
|
23
|
+
has_one :remote_ref, PBXContainerItemProxy
|
24
|
+
|
25
|
+
# @return [String] the source tree for the path of the reference.
|
26
|
+
#
|
27
|
+
# E.g. "BUILT_PRODUCTS_DIR"
|
28
|
+
#
|
29
|
+
attribute :source_tree, String
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -9,7 +9,7 @@ module Xcodeproj
|
|
9
9
|
# @return [ObjectList<PBXNativeTarget>] a list of all the targets in
|
10
10
|
# the project.
|
11
11
|
#
|
12
|
-
has_many :targets,
|
12
|
+
has_many :targets, AbstractTarget
|
13
13
|
|
14
14
|
# @return [Hash{String => String}] attributes the attributes of the
|
15
15
|
# target.
|
@@ -60,6 +60,13 @@ module Xcodeproj
|
|
60
60
|
#
|
61
61
|
attribute :project_root, String
|
62
62
|
|
63
|
+
# @return [Array<ObjectDictionary>] any reference to other projects.
|
64
|
+
#
|
65
|
+
has_many_references_by_keys :project_references, {
|
66
|
+
:project_ref => PBXFileReference,
|
67
|
+
:product_group => PBXGroup
|
68
|
+
}
|
69
|
+
|
63
70
|
end
|
64
71
|
end
|
65
72
|
end
|
@@ -205,6 +205,10 @@ module Xcodeproj
|
|
205
205
|
@to_many_attributes ||= attributes.select { |a| a.type == :to_many }
|
206
206
|
end
|
207
207
|
|
208
|
+
def references_by_keys_attributes
|
209
|
+
@references_by_keys_attributes ||= attributes.select { |a| a.type == :references_by_keys }
|
210
|
+
end
|
211
|
+
|
208
212
|
private
|
209
213
|
|
210
214
|
# Defines a new simple attribute and synthesises the corresponding
|
@@ -330,6 +334,41 @@ module Xcodeproj
|
|
330
334
|
end
|
331
335
|
end
|
332
336
|
|
337
|
+
# Defines a new ordered relationship to many.
|
338
|
+
#
|
339
|
+
# @note This attribute only generates the reader method. Clients are
|
340
|
+
# not supposed to create {ObjectList} objects which are created
|
341
|
+
# by the methods synthesised by this attribute on demand.
|
342
|
+
# Clients, however can mutate the list according to its
|
343
|
+
# interface. The list is responsible to manage the reference
|
344
|
+
# counting for its values.
|
345
|
+
#
|
346
|
+
# @param [String] plural_name
|
347
|
+
# the name of the relationship.
|
348
|
+
#
|
349
|
+
# @param [Class, Array<Class>] isas
|
350
|
+
# the list of the classes corresponding to the accepted isas for
|
351
|
+
# this relationship.
|
352
|
+
#
|
353
|
+
# @macro [attach] has_many
|
354
|
+
# @!attribute [r] $1
|
355
|
+
#
|
356
|
+
def has_many_references_by_keys(plural_name, isas_hash)
|
357
|
+
attrb = AbstractObjectAttribute.new(:references_by_keys, plural_name, self)
|
358
|
+
attrb.classes = isas_hash.values
|
359
|
+
add_attribute(attrb)
|
360
|
+
|
361
|
+
define_method(attrb.name) do
|
362
|
+
# Here we are in the context of the instance
|
363
|
+
list = instance_variable_get("@#{attrb.name}")
|
364
|
+
unless list
|
365
|
+
list = ObjectList.new(attrb, self)
|
366
|
+
instance_variable_set("@#{attrb.name}", list)
|
367
|
+
end
|
368
|
+
list
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
333
372
|
protected
|
334
373
|
|
335
374
|
# Adds an attribute to the list of attributes of the class.
|
@@ -376,6 +415,12 @@ module Xcodeproj
|
|
376
415
|
def to_many_attributes
|
377
416
|
self.class.to_many_attributes
|
378
417
|
end
|
418
|
+
|
419
|
+
# @return (see AbstractObject.to_many_attributes)
|
420
|
+
#
|
421
|
+
def references_by_keys_attributes
|
422
|
+
self.class.references_by_keys_attributes
|
423
|
+
end
|
379
424
|
end # AbstractObject
|
380
425
|
end
|
381
426
|
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
class Project
|
3
|
+
|
4
|
+
# This class represents relationships to other objects stored in a
|
5
|
+
# Dictionary.
|
6
|
+
#
|
7
|
+
# It works in conjunction with the {AbstractObject} class to ensure that
|
8
|
+
# the project is not serialized with unreachable objects by updating the
|
9
|
+
# with reference count on modifications.
|
10
|
+
#
|
11
|
+
# @note This class is a stub currently only being used by
|
12
|
+
# {PBXProject#project_references}. It doesn't perform type cheeking
|
13
|
+
# and the keys of the dictionary are in camel-case. To provide full
|
14
|
+
# support as the other classes the dictionary should be able to
|
15
|
+
#
|
16
|
+
# Give the following attribute:
|
17
|
+
#
|
18
|
+
# has_many_references_by_keys :project_references, {
|
19
|
+
# :project_ref => PBXFileReference,
|
20
|
+
# :product_group => PBXGroup
|
21
|
+
# }
|
22
|
+
#
|
23
|
+
# This should be possible:
|
24
|
+
#
|
25
|
+
# #=> Note the API:
|
26
|
+
# root_object.project_references.project_ref = file
|
27
|
+
#
|
28
|
+
# #=> This should raise:
|
29
|
+
# root_object.project_references.product_group = file
|
30
|
+
#
|
31
|
+
# generate setters and getters from the specification hash.
|
32
|
+
#
|
33
|
+
# Also the interface is a dirty hybrid between the
|
34
|
+
# {AbstractObjectAttribute} and the {ObjectList}.
|
35
|
+
#
|
36
|
+
# @note Concerning the mutations methods it is safe to call only those
|
37
|
+
# which are overridden to inform objects reference count. Ideally all
|
38
|
+
# the hash methods should be covered, but this is not done yet.
|
39
|
+
# Moreover it is a moving target because the methods of array
|
40
|
+
# usually are implemented in C
|
41
|
+
#
|
42
|
+
# @todo Cover all the mutations methods of the {Hash} class.
|
43
|
+
#
|
44
|
+
class ObjectDictionary < Hash
|
45
|
+
|
46
|
+
# {Xcodeproj} clients are not expected to create instances of
|
47
|
+
# {ObjectDictionary}, it is always initialized empty and automatically by
|
48
|
+
# the synthesized methods generated by {AbstractObject.has_many}.
|
49
|
+
#
|
50
|
+
def initialize(attribute, owner)
|
51
|
+
@attribute = attribute
|
52
|
+
@owner = owner
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [Array<Class>] The attribute that generated the list.
|
56
|
+
#
|
57
|
+
attr_reader :attribute
|
58
|
+
|
59
|
+
# @return [Array<Class>] The object that owns the list.
|
60
|
+
#
|
61
|
+
attr_reader :owner
|
62
|
+
|
63
|
+
#------------------------------------------------------------------------#
|
64
|
+
|
65
|
+
# @!group Notification enabled methods
|
66
|
+
|
67
|
+
# TODO: the overridden methods are incomplete.
|
68
|
+
|
69
|
+
# Associates an object to the given key and updates its references count.
|
70
|
+
#
|
71
|
+
# @param [String] key
|
72
|
+
# the key
|
73
|
+
#
|
74
|
+
# @param [AbstractObject] object
|
75
|
+
# the object to add to the dictionary.
|
76
|
+
#
|
77
|
+
# @return [void]
|
78
|
+
#
|
79
|
+
def []=(key, object)
|
80
|
+
if object
|
81
|
+
perform_additions_operations(object)
|
82
|
+
else
|
83
|
+
perform_deletion_operations(self[key])
|
84
|
+
end
|
85
|
+
super
|
86
|
+
end
|
87
|
+
|
88
|
+
# Removes the given key from the dictionary and informs the object that
|
89
|
+
# is not longer referenced by the owner.
|
90
|
+
#
|
91
|
+
# @param [String] key
|
92
|
+
# the key
|
93
|
+
#
|
94
|
+
# @return [void]
|
95
|
+
#
|
96
|
+
def delete(key)
|
97
|
+
object = self[key]
|
98
|
+
perform_deletion_operations(object)
|
99
|
+
super
|
100
|
+
end
|
101
|
+
|
102
|
+
#------------------------------------------------------------------------#
|
103
|
+
|
104
|
+
# @!group Integration with {AbstractObject}
|
105
|
+
|
106
|
+
# The plist reppresentation of the dictionary where the objects are
|
107
|
+
# replaced by their UUIDs.
|
108
|
+
#
|
109
|
+
# @return [Hash<String => String>]
|
110
|
+
#
|
111
|
+
def to_plist
|
112
|
+
result = {}
|
113
|
+
each { |key, obj| result[key] = obj.uuid }
|
114
|
+
result
|
115
|
+
end
|
116
|
+
|
117
|
+
# Returns a cascade reppresentation of the object without UUIDs.
|
118
|
+
#
|
119
|
+
# @return [Hash<String => String>]
|
120
|
+
#
|
121
|
+
def to_tree_hash
|
122
|
+
result = {}
|
123
|
+
each { |key, obj| result[key] = obj.to_tree_hash }
|
124
|
+
result
|
125
|
+
end
|
126
|
+
|
127
|
+
# Removes all the references to a given object.
|
128
|
+
#
|
129
|
+
# @return [void]
|
130
|
+
#
|
131
|
+
def remove_reference(object)
|
132
|
+
each { |key, obj| self[key] = nil if obj == object }
|
133
|
+
end
|
134
|
+
|
135
|
+
#------------------------------------------------------------------------#
|
136
|
+
|
137
|
+
# @!group Integration with {ObjectList}
|
138
|
+
|
139
|
+
# Informs the objects contained in the dictionary that another object is
|
140
|
+
# referencing them.
|
141
|
+
#
|
142
|
+
# @return [void]
|
143
|
+
#
|
144
|
+
def add_referrer(referrer)
|
145
|
+
values.each { |obj| obj.add_referrer(referrer) }
|
146
|
+
end
|
147
|
+
|
148
|
+
# Informs the objects contained in the dictionary that another object
|
149
|
+
# stopped referencing them.
|
150
|
+
#
|
151
|
+
# @return [void]
|
152
|
+
#
|
153
|
+
def remove_referrer(referrer)
|
154
|
+
values.each { |obj| obj.remove_referrer(referrer) }
|
155
|
+
end
|
156
|
+
|
157
|
+
#------------------------------------------------------------------------#
|
158
|
+
|
159
|
+
# @!group Notification Methods
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
# Informs an object that it was added to the dictionary. In practice it
|
164
|
+
# adds the owner of the list as referrer to the objects. It also
|
165
|
+
# validates the value.
|
166
|
+
#
|
167
|
+
# @return [void]
|
168
|
+
#
|
169
|
+
def perform_additions_operations(objects)
|
170
|
+
objects = [objects] unless objects.is_a?(Array)
|
171
|
+
objects.each do |obj|
|
172
|
+
obj.add_referrer(owner)
|
173
|
+
attribute.validate_value(obj)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Informs an object that it was removed from to the dictionary, so it can
|
178
|
+
# remove it from its referrers and take the appropriate actions.
|
179
|
+
#
|
180
|
+
# @return [void]
|
181
|
+
#
|
182
|
+
def perform_deletion_operations(objects)
|
183
|
+
objects = [objects] unless objects.is_a?(Array)
|
184
|
+
objects.each do |obj|
|
185
|
+
obj.remove_referrer(owner)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
@@ -10,10 +10,10 @@ module Xcodeproj
|
|
10
10
|
# @note Concerning the mutations methods it is safe to call only those
|
11
11
|
# which are overridden to inform objects reference count. Ideally all
|
12
12
|
# the array methods should be covered, but this is not done yet.
|
13
|
-
# Moreover it is a moving target because the methods of array
|
13
|
+
# Moreover it is a moving target because the methods of array
|
14
14
|
# usually are implemented in C
|
15
15
|
#
|
16
|
-
# @todo Cover all the
|
16
|
+
# @todo Cover all the mutations methods of the {Array} class.
|
17
17
|
#
|
18
18
|
class ObjectList < Array
|
19
19
|
|
@@ -26,40 +26,90 @@ module Xcodeproj
|
|
26
26
|
@owner = owner
|
27
27
|
end
|
28
28
|
|
29
|
-
# @return [Array<Class>]
|
29
|
+
# @return [Array<Class>] the attribute that generated the list.
|
30
30
|
#
|
31
31
|
attr_reader :attribute
|
32
32
|
|
33
|
-
# @return [Array<Class>]
|
33
|
+
# @return [Array<Class>] the object that owns the list.
|
34
34
|
#
|
35
35
|
attr_reader :owner
|
36
36
|
|
37
|
-
|
38
|
-
|
37
|
+
#------------------------------------------------------------------------#
|
38
|
+
|
39
|
+
# @!group Integration with {ObjectList}
|
40
|
+
|
41
|
+
# @return [Array<String>]
|
42
|
+
# the UUIDs of all the objects referenced by this list.
|
39
43
|
#
|
40
44
|
def uuids
|
41
45
|
map { |obj| obj.uuid }
|
42
46
|
end
|
43
47
|
|
48
|
+
# @return [Array<AbstractObject>]
|
49
|
+
# a new array generated with the objects contained in the list.
|
50
|
+
#
|
51
|
+
def objects
|
52
|
+
to_a
|
53
|
+
end
|
54
|
+
|
55
|
+
#------------------------------------------------------------------------#
|
56
|
+
|
44
57
|
# @!group Notification enabled methods
|
45
58
|
|
46
59
|
# TODO: the overridden methods are incomplete.
|
47
60
|
|
61
|
+
# Adds an array of objects to list and updates their references count.
|
62
|
+
#
|
63
|
+
# @param [Array<AbstractObject, ObjectDictionary>] object
|
64
|
+
# an array of objects to add to the list.
|
65
|
+
#
|
66
|
+
# @return [void]
|
67
|
+
#
|
48
68
|
def +(objects)
|
49
69
|
super
|
50
70
|
perform_additions_operations(objects)
|
51
71
|
end
|
52
72
|
|
73
|
+
# Adds an object to list and updates its references count.
|
74
|
+
#
|
75
|
+
# @param [AbstractObject, ObjectDictionary] object
|
76
|
+
# the object to add to the list.
|
77
|
+
#
|
78
|
+
# @return [void]
|
79
|
+
#
|
53
80
|
def <<(object)
|
54
81
|
super
|
55
82
|
perform_additions_operations(object)
|
56
83
|
end
|
57
84
|
|
85
|
+
# Removes an object to list and updates its references count.
|
86
|
+
#
|
87
|
+
# @param [AbstractObject, ObjectDictionary] object
|
88
|
+
# the object to delete from the list.
|
89
|
+
#
|
90
|
+
# @return [void]
|
91
|
+
#
|
58
92
|
def delete(object)
|
59
93
|
super
|
60
94
|
perform_deletion_operations(object)
|
61
95
|
end
|
62
96
|
|
97
|
+
# Removes all the objects contained in the list and updates their
|
98
|
+
# reference counts.
|
99
|
+
#
|
100
|
+
# @return [void]
|
101
|
+
#
|
102
|
+
def clear
|
103
|
+
objects.each do |object|
|
104
|
+
perform_deletion_operations(object)
|
105
|
+
end
|
106
|
+
super
|
107
|
+
end
|
108
|
+
|
109
|
+
#------------------------------------------------------------------------#
|
110
|
+
|
111
|
+
# @!group Notification Methods
|
112
|
+
|
63
113
|
private
|
64
114
|
|
65
115
|
# Informs an object that it was added to the list. In practice it adds
|
@@ -72,19 +122,19 @@ module Xcodeproj
|
|
72
122
|
objects = [objects] unless objects.is_a?(Array)
|
73
123
|
objects.each do |obj|
|
74
124
|
obj.add_referrer(owner)
|
75
|
-
attribute.validate_value(obj)
|
125
|
+
attribute.validate_value(obj) unless obj.is_a?(ObjectDictionary)
|
76
126
|
end
|
77
127
|
end
|
78
128
|
|
79
129
|
# Informs an object that it was removed from to the list, so it can
|
80
|
-
# remove
|
130
|
+
# remove its owner from its referrers and take the appropriate actions.
|
81
131
|
#
|
82
132
|
# @return [void]
|
83
133
|
#
|
84
134
|
def perform_deletion_operations(objects)
|
85
135
|
objects = [objects] unless objects.is_a?(Array)
|
86
136
|
objects.each do |obj|
|
87
|
-
obj.remove_referrer(owner)
|
137
|
+
obj.remove_referrer(owner) unless obj.is_a?(ObjectDictionary)
|
88
138
|
end
|
89
139
|
end
|
90
140
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xcodeproj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.0.
|
4
|
+
version: 0.4.0.rc3
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -60,6 +60,7 @@ files:
|
|
60
60
|
- lib/xcodeproj/config.rb
|
61
61
|
- lib/xcodeproj/constants.rb
|
62
62
|
- lib/xcodeproj/helper.rb
|
63
|
+
- lib/xcodeproj/project/object/aggregate_target.rb
|
63
64
|
- lib/xcodeproj/project/object/build_configuration.rb
|
64
65
|
- lib/xcodeproj/project/object/build_file.rb
|
65
66
|
- lib/xcodeproj/project/object/build_phase.rb
|
@@ -69,10 +70,12 @@ files:
|
|
69
70
|
- lib/xcodeproj/project/object/file_reference.rb
|
70
71
|
- lib/xcodeproj/project/object/group.rb
|
71
72
|
- lib/xcodeproj/project/object/native_target.rb
|
73
|
+
- lib/xcodeproj/project/object/reference_proxy.rb
|
72
74
|
- lib/xcodeproj/project/object/root_object.rb
|
73
75
|
- lib/xcodeproj/project/object/target_dependency.rb
|
74
76
|
- lib/xcodeproj/project/object.rb
|
75
77
|
- lib/xcodeproj/project/object_attributes.rb
|
78
|
+
- lib/xcodeproj/project/object_dictionary.rb
|
76
79
|
- lib/xcodeproj/project/object_list.rb
|
77
80
|
- lib/xcodeproj/project/recursive_diff.rb
|
78
81
|
- lib/xcodeproj/project.rb
|
@@ -99,7 +102,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
102
|
version: '0'
|
100
103
|
segments:
|
101
104
|
- 0
|
102
|
-
hash:
|
105
|
+
hash: 1005029667767319661
|
103
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
107
|
none: false
|
105
108
|
requirements:
|