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