plasmo_xcodeproj 1.21.1

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.
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