plasmo_xcodeproj 1.21.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +19 -0
  3. data/README.md +95 -0
  4. data/bin/xcodeproj +10 -0
  5. data/lib/xcodeproj/command/config_dump.rb +91 -0
  6. data/lib/xcodeproj/command/project_diff.rb +56 -0
  7. data/lib/xcodeproj/command/show.rb +60 -0
  8. data/lib/xcodeproj/command/sort.rb +44 -0
  9. data/lib/xcodeproj/command/target_diff.rb +43 -0
  10. data/lib/xcodeproj/command.rb +63 -0
  11. data/lib/xcodeproj/config/other_linker_flags_parser.rb +73 -0
  12. data/lib/xcodeproj/config.rb +386 -0
  13. data/lib/xcodeproj/constants.rb +465 -0
  14. data/lib/xcodeproj/differ.rb +239 -0
  15. data/lib/xcodeproj/gem_version.rb +5 -0
  16. data/lib/xcodeproj/helper.rb +30 -0
  17. data/lib/xcodeproj/plist.rb +94 -0
  18. data/lib/xcodeproj/project/case_converter.rb +90 -0
  19. data/lib/xcodeproj/project/object/build_configuration.rb +255 -0
  20. data/lib/xcodeproj/project/object/build_file.rb +84 -0
  21. data/lib/xcodeproj/project/object/build_phase.rb +369 -0
  22. data/lib/xcodeproj/project/object/build_rule.rb +109 -0
  23. data/lib/xcodeproj/project/object/configuration_list.rb +117 -0
  24. data/lib/xcodeproj/project/object/container_item_proxy.rb +116 -0
  25. data/lib/xcodeproj/project/object/file_reference.rb +338 -0
  26. data/lib/xcodeproj/project/object/group.rb +506 -0
  27. data/lib/xcodeproj/project/object/helpers/build_settings_array_settings_by_object_version.rb +72 -0
  28. data/lib/xcodeproj/project/object/helpers/file_references_factory.rb +245 -0
  29. data/lib/xcodeproj/project/object/helpers/groupable_helper.rb +260 -0
  30. data/lib/xcodeproj/project/object/native_target.rb +751 -0
  31. data/lib/xcodeproj/project/object/reference_proxy.rb +86 -0
  32. data/lib/xcodeproj/project/object/root_object.rb +100 -0
  33. data/lib/xcodeproj/project/object/swift_package_product_dependency.rb +29 -0
  34. data/lib/xcodeproj/project/object/swift_package_remote_reference.rb +33 -0
  35. data/lib/xcodeproj/project/object/target_dependency.rb +94 -0
  36. data/lib/xcodeproj/project/object.rb +534 -0
  37. data/lib/xcodeproj/project/object_attributes.rb +522 -0
  38. data/lib/xcodeproj/project/object_dictionary.rb +210 -0
  39. data/lib/xcodeproj/project/object_list.rb +223 -0
  40. data/lib/xcodeproj/project/project_helper.rb +341 -0
  41. data/lib/xcodeproj/project/uuid_generator.rb +132 -0
  42. data/lib/xcodeproj/project.rb +874 -0
  43. data/lib/xcodeproj/scheme/abstract_scheme_action.rb +100 -0
  44. data/lib/xcodeproj/scheme/analyze_action.rb +19 -0
  45. data/lib/xcodeproj/scheme/archive_action.rb +59 -0
  46. data/lib/xcodeproj/scheme/build_action.rb +298 -0
  47. data/lib/xcodeproj/scheme/buildable_product_runnable.rb +55 -0
  48. data/lib/xcodeproj/scheme/buildable_reference.rb +129 -0
  49. data/lib/xcodeproj/scheme/command_line_arguments.rb +162 -0
  50. data/lib/xcodeproj/scheme/environment_variables.rb +170 -0
  51. data/lib/xcodeproj/scheme/execution_action.rb +86 -0
  52. data/lib/xcodeproj/scheme/launch_action.rb +179 -0
  53. data/lib/xcodeproj/scheme/location_scenario_reference.rb +49 -0
  54. data/lib/xcodeproj/scheme/macro_expansion.rb +34 -0
  55. data/lib/xcodeproj/scheme/profile_action.rb +57 -0
  56. data/lib/xcodeproj/scheme/remote_runnable.rb +92 -0
  57. data/lib/xcodeproj/scheme/send_email_action_content.rb +84 -0
  58. data/lib/xcodeproj/scheme/shell_script_action_content.rb +77 -0
  59. data/lib/xcodeproj/scheme/test_action.rb +394 -0
  60. data/lib/xcodeproj/scheme/xml_element_wrapper.rb +82 -0
  61. data/lib/xcodeproj/scheme.rb +375 -0
  62. data/lib/xcodeproj/user_interface.rb +22 -0
  63. data/lib/xcodeproj/workspace/file_reference.rb +79 -0
  64. data/lib/xcodeproj/workspace/group_reference.rb +67 -0
  65. data/lib/xcodeproj/workspace/reference.rb +40 -0
  66. data/lib/xcodeproj/workspace.rb +277 -0
  67. data/lib/xcodeproj/xcodebuild_helper.rb +108 -0
  68. data/lib/xcodeproj.rb +29 -0
  69. metadata +208 -0
@@ -0,0 +1,522 @@
1
+ module Xcodeproj
2
+ class Project
3
+ module Object
4
+ # This class represents an attribute of {AbstractObject} subclasses.
5
+ # Attributes are created by the {AbstractObject} DSL methods and allow to
6
+ # mirror the underlying attributes of the xcodeproj document model.
7
+ #
8
+ # Attributes provide support for runtime type checking. They also allow
9
+ # {AbstractObject} initialization and serialization to plist.
10
+ #
11
+ # @todo Add support for a list of required values so objects can be
12
+ # validated before serialization ?
13
+ #
14
+ class AbstractObjectAttribute
15
+ # @return [Symbol] the type of the attribute. It can be `:simple`,
16
+ # `:to_one`, `:to_many`.
17
+ #
18
+ attr_reader :type
19
+
20
+ # @return [Symbol] the name of the attribute.
21
+ #
22
+ attr_reader :name
23
+
24
+ # @return [Class] the class that owns the attribute.
25
+ #
26
+ attr_accessor :owner
27
+
28
+ # Creates a new attribute with the given type and name.
29
+ #
30
+ # Attributes are expected to be instantiated only by the
31
+ # {AbstractObject} DSL methods.
32
+ #
33
+ # @param [Symbol] type
34
+ # the type of the attribute.
35
+ #
36
+ # @param [Symbol] name
37
+ # the name of the attribute.
38
+ #
39
+ # @param [Class] owner
40
+ # the class that owns the attribute.
41
+ #
42
+ def initialize(type, name, owner)
43
+ @type = type
44
+ @name = name
45
+ @owner = owner
46
+ end
47
+
48
+ # @return [String] The name of the attribute in camel case.
49
+ #
50
+ # @example
51
+ # attribute.new(:simple, :project_root)
52
+ # attribute.plist_name #=> projectRoot
53
+ #
54
+ def plist_name
55
+ @plist_name ||= CaseConverter.convert_to_plist(name, :lower)
56
+ end
57
+
58
+ # @return [Array<Class>] the list of the classes accepted by the
59
+ # attribute.
60
+ #
61
+ attr_accessor :classes
62
+
63
+ # @return [{Symbol, Array<Class>}] the list of the classes accepted by
64
+ # each key for attributes which store a dictionary.
65
+ #
66
+ attr_accessor :classes_by_key
67
+
68
+ # @return [String, Array, Hash] the default value, if any, for simple
69
+ # attributes.
70
+ #
71
+ attr_accessor :default_value
72
+
73
+ # Convenience method that returns the value of this attribute for a
74
+ # given object.
75
+ #
76
+ # @param [AbstractObject] object
77
+ # the object for which the value of this attribute is requested.
78
+ #
79
+ # @return [String, Array, Hash, AbstractObject, ObjectList]
80
+ # the value.
81
+ #
82
+ def get_value(object)
83
+ object.send(name)
84
+ end
85
+
86
+ # Convenience method that sets the value of this attribute for a
87
+ # given object. It makes sense only for `:simple` or `:to_one`
88
+ # attributes.
89
+ #
90
+ # @raise It the type of this attribute is `:to_many`.
91
+ #
92
+ # @param [AbstractObject] object
93
+ # the object for which to set the value.
94
+ #
95
+ # @param [String, Hash, Array, AbstractObject] new_value
96
+ # the value to set for the attribute.
97
+ #
98
+ # @return [void]
99
+ #
100
+ def set_value(object, new_value)
101
+ if type == :to_many
102
+ raise '[Xcodeproj] Set value called for a to-many attribute'
103
+ end
104
+ object.send("#{name}=", new_value)
105
+ end
106
+
107
+ # Convenience method that sets the value of this attribute for a given
108
+ # object to the default (if any). It makes sense only for `:simple`
109
+ # attributes.
110
+ #
111
+ # @param [AbstractObject] object
112
+ # the object for which to set the default value.
113
+ #
114
+ # @note It is extremely important to duplicate the default values
115
+ # otherwise kittens cry!
116
+ #
117
+ # @return [void]
118
+ #
119
+ def set_default(object)
120
+ unless type == :simple
121
+ raise "[Xcodeproj] Set value called for a #{type} attribute"
122
+ end
123
+ set_value(object, default_value.dup) if default_value
124
+ end
125
+
126
+ # Checks that a given value is compatible with the attribute.
127
+ #
128
+ # This method powers the runtime type checking of the {AbstractObject}
129
+ # and is used its by synthesised methods.
130
+ #
131
+ # @raise If the class of the value is not compatible with the attribute.
132
+ #
133
+ # @return [void]
134
+ #
135
+ def validate_value(object)
136
+ return unless object
137
+ acceptable = classes.find { |klass| object.class == klass || object.class < klass }
138
+ if type == :simple
139
+ raise "[Xcodeproj] Type checking error: got `#{object.class}` " \
140
+ "for attribute: #{inspect}" unless acceptable
141
+ else
142
+ raise "[Xcodeproj] Type checking error: got `#{object.isa}` for " \
143
+ "attribute: #{inspect}" unless acceptable
144
+ end
145
+ end
146
+
147
+ # Checks that a given value is compatible with a key for attributes
148
+ # which store references by key.
149
+ #
150
+ # This method is used by the #{ObjectDictionary} class.
151
+ #
152
+ # @raise If the class of the value is not compatible with the given
153
+ # key.
154
+ #
155
+ def validate_value_for_key(object, key)
156
+ unless type == :references_by_keys
157
+ raise '[Xcodeproj] This method should be called only for ' \
158
+ 'attributes of type `references_by_keys`'
159
+ end
160
+
161
+ unless classes_by_key.keys.include?(key)
162
+ raise "[Xcodeproj] unsupported key `#{key}` " \
163
+ "(accepted `#{classes_by_key.keys}`) for attribute `#{inspect}`"
164
+ end
165
+
166
+ return unless object
167
+ classes = Array(classes_by_key[key])
168
+ acceptable = classes.find { |klass| object.class == klass || object.class < klass }
169
+ unless acceptable
170
+ raise "[Xcodeproj] Type checking error: got `#{object.isa}` " \
171
+ "for key `#{key}` (which accepts `#{classes}`) of " \
172
+ "attribute: `#{inspect}`"
173
+ end
174
+ end
175
+
176
+ # @return [String] A string suitable for debugging the object.
177
+ #
178
+ def inspect
179
+ if type == :simple
180
+ "Attribute `#{plist_name}` (type: `#{type}`, classes: " \
181
+ "`#{classes}`, owner class: `#{owner.isa}`)"
182
+ else
183
+ "Attribute `#{plist_name}` (type: `#{type}`, classes: " \
184
+ "`#{classes.map(&:isa)}`, owner class: `#{owner.isa}`)"
185
+ end
186
+ end
187
+ end
188
+
189
+ class AbstractObject
190
+ # The {AbstractObject} DSL methods allow to specify with fidelity the
191
+ # underlying model of the xcodeproj document format. {AbstractObject}
192
+ # subclasses should specify their attributes through the following
193
+ # methods:
194
+ #
195
+ # - `{AbstractObject.attribute}`
196
+ # - `{AbstractObject.has_one}`
197
+ # - `{AbstractObject.has_many}`
198
+ #
199
+ # @note The subclasses should not interfere with the methods
200
+ # synthesised by the DSL and should only implement helpers in top
201
+ # of them.
202
+ #
203
+ # @note Attributes are typed and are validated at runtime.
204
+ #
205
+ class << self
206
+ # @return [Array<AbstractObjectAttribute>] the attributes associated
207
+ # with the class.
208
+ #
209
+ # @note It includes the attributes defined in the superclass and the
210
+ # list is cleaned for duplicates. Subclasses should not duplicate
211
+ # an attribute of the superclass but for the method implementation
212
+ # they will duplicate them.
213
+ #
214
+ # @visibility private
215
+ #
216
+ def attributes
217
+ unless @full_attributes
218
+ attributes = @attributes || []
219
+ if superclass.respond_to?(:attributes)
220
+ super_attributes = superclass.attributes
221
+ else
222
+ super_attributes = []
223
+ end
224
+ # The uniqueness of the attributes is very important because the
225
+ # initialization from plist deletes the values from the
226
+ # dictionary.
227
+ @full_attributes = attributes.concat(super_attributes).uniq
228
+ end
229
+ @full_attributes
230
+ end
231
+
232
+ # @return [Array<AbstractObjectAttribute>] the simple attributes
233
+ # associated with with the class.
234
+ #
235
+ # @visibility private
236
+ #
237
+ def simple_attributes
238
+ @simple_attributes ||= attributes.select { |a| a.type == :simple }
239
+ end
240
+
241
+ # @return [Array<AbstractObjectAttribute>] the attributes
242
+ # representing a to one relationship associated with with the
243
+ # class.
244
+ #
245
+ # @visibility private
246
+ #
247
+ def to_one_attributes
248
+ @to_one_attributes ||= attributes.select { |a| a.type == :to_one }
249
+ end
250
+
251
+ # @return [Array<AbstractObjectAttribute>] the attributes
252
+ # representing a to many relationship associated with with the
253
+ # class.
254
+ #
255
+ # @visibility private
256
+ #
257
+ def to_many_attributes
258
+ @to_many_attributes ||= attributes.select { |a| a.type == :to_many }
259
+ end
260
+
261
+ # @visibility private
262
+ #
263
+ def references_by_keys_attributes
264
+ @references_by_keys_attributes ||= attributes.select { |a| a.type == :references_by_keys }
265
+ end
266
+
267
+ private
268
+
269
+ # Defines a new simple attribute and synthesises the corresponding
270
+ # methods.
271
+ #
272
+ # @note Simple attributes are directly stored in a hash. They can
273
+ # contain only a string, array of strings or a hash containing
274
+ # strings and thus they are not affected by reference counting.
275
+ # Clients can access the hash directly through the
276
+ # {AbstractObject#simple_attributes_hash} method.
277
+ #
278
+ # @param [Symbol] name
279
+ # the name of the attribute.
280
+ #
281
+ # @param [Class] klass
282
+ # the accepted {Class} for the values of the attribute.
283
+ #
284
+ # @param [String, Array<String>, Hash{String=>String}] default_value
285
+ # the default value for new objects.
286
+ #
287
+ # @example
288
+ # attribute :project_root
289
+ # #=> leads to the creation of the following methods
290
+ #
291
+ # def project_root
292
+ # @simple_attributes_hash[projectRoot]
293
+ # end
294
+ #
295
+ # def project_root=(value)
296
+ # attribute.validate_value(value)
297
+ # @simple_attributes_hash[projectRoot] = value
298
+ # end
299
+ #
300
+ # @macro [attach] attribute
301
+ # @!attribute [rw] $1
302
+ #
303
+ def attribute(name, klass, default_value = nil)
304
+ attrb = AbstractObjectAttribute.new(:simple, name, self)
305
+ attrb.classes = [klass]
306
+ attrb.default_value = default_value
307
+ add_attribute(attrb)
308
+
309
+ define_method(attrb.name) do
310
+ @simple_attributes_hash ||= {}
311
+ @simple_attributes_hash[attrb.plist_name]
312
+ end
313
+
314
+ define_method("#{attrb.name}=") do |value|
315
+ @simple_attributes_hash ||= {}
316
+ attrb.validate_value(value)
317
+
318
+ existing = @simple_attributes_hash[attrb.plist_name]
319
+ if existing.is_a?(Hash) && value.is_a?(Hash)
320
+ return value if existing.keys == value.keys && existing == value
321
+ elsif existing == value
322
+ return value
323
+ end
324
+ mark_project_as_dirty!
325
+ @simple_attributes_hash[attrb.plist_name] = value
326
+ end
327
+ end
328
+
329
+ # rubocop:disable Style/PredicateName
330
+
331
+ # Defines a new relationship to a single and synthesises the
332
+ # corresponding methods.
333
+ #
334
+ # @note The synthesised setter takes care of handling reference
335
+ # counting directly.
336
+ #
337
+ # @param [String] singular_name
338
+ # the name of the relationship.
339
+ #
340
+ # @param [Class, Array<Class>] isas
341
+ # the list of the classes corresponding to the accepted isas for
342
+ # this relationship.
343
+ #
344
+ # @macro [attach] has_one
345
+ # @!attribute [rw] $1
346
+ #
347
+ def has_one(singular_name, isas)
348
+ isas = [isas] unless isas.is_a?(Array)
349
+ attrb = AbstractObjectAttribute.new(:to_one, singular_name, self)
350
+ attrb.classes = isas
351
+ add_attribute(attrb)
352
+
353
+ attr_reader(attrb.name)
354
+ # 1.9.2 fix, see https://github.com/CocoaPods/Xcodeproj/issues/40.
355
+ public(attrb.name)
356
+
357
+ variable_name = :"@#{attrb.name}"
358
+ define_method("#{attrb.name}=") do |value|
359
+ attrb.validate_value(value)
360
+
361
+ previous_value = send(attrb.name)
362
+ return value if previous_value == value
363
+ mark_project_as_dirty!
364
+ previous_value.remove_referrer(self) if previous_value
365
+ instance_variable_set(variable_name, value)
366
+ value.add_referrer(self) if value
367
+ end
368
+ end
369
+
370
+ # Defines a new ordered relationship to many.
371
+ #
372
+ # @note This attribute only generates the reader method. Clients are
373
+ # not supposed to create {ObjectList} objects which are created
374
+ # by the methods synthesised by this attribute on demand.
375
+ # Clients, however can mutate the list according to its
376
+ # interface. The list is responsible to manage the reference
377
+ # counting for its values.
378
+ #
379
+ # @param [String] plural_name
380
+ # the name of the relationship.
381
+ #
382
+ # @param [Class, Array<Class>] isas
383
+ # the list of the classes corresponding to the accepted isas for
384
+ # this relationship.
385
+ #
386
+ # @macro [attach] has_many
387
+ # @!attribute [r] $1
388
+ #
389
+ def has_many(plural_name, isas)
390
+ isas = [isas] unless isas.is_a?(Array)
391
+
392
+ attrb = AbstractObjectAttribute.new(:to_many, plural_name, self)
393
+ attrb.classes = isas
394
+ add_attribute(attrb)
395
+
396
+ variable_name = :"@#{attrb.name}"
397
+ define_method(attrb.name) do
398
+ # Here we are in the context of the instance
399
+ list = instance_variable_get(variable_name)
400
+ unless list
401
+ list = ObjectList.new(attrb, self)
402
+ instance_variable_set(variable_name, list)
403
+ end
404
+ list
405
+ end
406
+ end
407
+
408
+ # Defines a new ordered relationship to many.
409
+ #
410
+ # @note This attribute only generates the reader method. Clients are
411
+ # not supposed to create {ObjectList} objects which are created
412
+ # by the methods synthesised by this attribute on demand.
413
+ # Clients, however can mutate the list according to its
414
+ # interface. The list is responsible to manage the reference
415
+ # counting for its values.
416
+ #
417
+ # @param [String] plural_name
418
+ # the name of the relationship.
419
+ #
420
+ # @param [{Symbol, Array<Class>}] classes_by_key
421
+ # the list of the classes corresponding to the accepted isas for
422
+ # this relationship.
423
+ #
424
+ # @macro [attach] has_many
425
+ # @!attribute [r] $1
426
+ #
427
+ def has_many_references_by_keys(plural_name, classes_by_key)
428
+ attrb = AbstractObjectAttribute.new(:references_by_keys, plural_name, self)
429
+ attrb.classes = classes_by_key.values
430
+ attrb.classes_by_key = classes_by_key
431
+ add_attribute(attrb)
432
+
433
+ variable_name = :"@#{attrb.name}"
434
+ define_method(attrb.name) do
435
+ # Here we are in the context of the instance
436
+ list = instance_variable_get(variable_name)
437
+ unless list
438
+ list = ObjectList.new(attrb, self)
439
+ instance_variable_set(variable_name, list)
440
+ end
441
+ list
442
+ end
443
+ end
444
+
445
+ # rubocop:enable Style/PredicateName
446
+
447
+ protected
448
+
449
+ # Adds an attribute to the list of attributes of the class.
450
+ #
451
+ # @note This method is intended to be invoked only by the
452
+ # {AbstractObject} meta programming methods
453
+ #
454
+ # @return [void]
455
+ #
456
+ def add_attribute(attribute)
457
+ unless attribute.classes
458
+ raise "[Xcodeproj] BUG - missing classes for #{attribute.inspect}"
459
+ end
460
+
461
+ unless attribute.classes.all? { |klass| klass.is_a?(Class) }
462
+ raise "[Xcodeproj] BUG - classes:#{attribute.classes} for #{attribute.inspect}"
463
+ end
464
+
465
+ @attributes ||= []
466
+ @attributes << attribute
467
+ end
468
+ end # AbstractObject << self
469
+
470
+ private
471
+
472
+ # @return [Hash] the simple attributes hash.
473
+ #
474
+ attr_reader :simple_attributes_hash
475
+
476
+ public
477
+
478
+ # @!group xcodeproj format attributes
479
+
480
+ # @return (see AbstractObject.attributes)
481
+ #
482
+ # @visibility private
483
+ #
484
+ def attributes
485
+ self.class.attributes
486
+ end
487
+
488
+ # @return (see AbstractObject.simple_attributes)
489
+ #
490
+ # @visibility private
491
+ #
492
+ def simple_attributes
493
+ self.class.simple_attributes
494
+ end
495
+
496
+ # @return (see AbstractObject.to_one_attributes)
497
+ #
498
+ # @visibility private
499
+ #
500
+ def to_one_attributes
501
+ self.class.to_one_attributes
502
+ end
503
+
504
+ # @return (see AbstractObject.to_many_attributes)
505
+ #
506
+ # @visibility private
507
+ #
508
+ def to_many_attributes
509
+ self.class.to_many_attributes
510
+ end
511
+
512
+ # @return (see AbstractObject.to_many_attributes)
513
+ #
514
+ # @visibility private
515
+ #
516
+ def references_by_keys_attributes
517
+ self.class.references_by_keys_attributes
518
+ end
519
+ end
520
+ end
521
+ end
522
+ end