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,341 @@
1
+ module Xcodeproj
2
+ class Project
3
+ module ProjectHelper
4
+ include Object
5
+
6
+ # @!group Targets
7
+
8
+ #-----------------------------------------------------------------------#
9
+
10
+ # Creates a new target and adds it to the project.
11
+ #
12
+ # The target is configured for the given platform and its file reference it
13
+ # is added to the {products_group}.
14
+ #
15
+ # The target is pre-populated with common build settings, and the
16
+ # appropriate Framework according to the platform is added to to its
17
+ # Frameworks phase.
18
+ #
19
+ # @param [Project] project
20
+ # the project to which the target should be added.
21
+ #
22
+ # @param [Symbol] type
23
+ # the type of target. Can be `:application`, `:dynamic_library`,
24
+ # `framework` or `:static_library`.
25
+ #
26
+ # @param [String] name
27
+ # the name of the target product.
28
+ #
29
+ # @param [Symbol] platform
30
+ # the platform of the target. Can be `:ios` or `:osx`.
31
+ #
32
+ # @param [String] deployment_target
33
+ # the deployment target for the platform.
34
+ #
35
+ # @param [PBXGroup] product_group
36
+ # the product group, where to add to a file reference of the
37
+ # created target.
38
+ #
39
+ # @param [Symbol] language
40
+ # the primary language of the target, can be `:objc` or `:swift`.
41
+ #
42
+ # @return [PBXNativeTarget] the target.
43
+ #
44
+ def self.new_target(project, type, name, platform, deployment_target, product_group, language, product_basename)
45
+ # Target
46
+ target = project.new(PBXNativeTarget)
47
+ project.targets << target
48
+ target.name = name
49
+ target.product_name = product_basename
50
+ target.product_type = Constants::PRODUCT_TYPE_UTI[type]
51
+ target.build_configuration_list = configuration_list(project, platform, deployment_target, type, language)
52
+
53
+ # Product
54
+ product = product_group.new_product_ref_for_target(target.product_name, type)
55
+ target.product_reference = product
56
+
57
+ # Build phases
58
+ build_phases_for_target_type(type).each { |phase| target.build_phases << project.new(phase) }
59
+
60
+ # Frameworks
61
+ unless type == :static_library
62
+ framework_name = (platform == :osx) ? 'Cocoa' : 'Foundation'
63
+ target.add_system_framework(framework_name)
64
+ end
65
+
66
+ target
67
+ end
68
+
69
+ # Creates a new resource bundles target and adds it to the project.
70
+ #
71
+ # The target is configured for the given platform and its file reference it
72
+ # is added to the {products_group}.
73
+ #
74
+ # The target is pre-populated with common build settings
75
+ #
76
+ # @param [Project] project
77
+ # the project to which the target should be added.
78
+ #
79
+ # @param [String] name
80
+ # the name of the resources bundle.
81
+ #
82
+ # @param [Symbol] platform
83
+ # the platform of the resources bundle. Can be `:ios` or `:osx`.
84
+ #
85
+ # @param [PBXGroup] product_group
86
+ # the product group, where to add to a file reference of the
87
+ # created target.
88
+ #
89
+ # @return [PBXNativeTarget] the target.
90
+ #
91
+ def self.new_resources_bundle(project, name, platform, product_group, product_basename)
92
+ # Target
93
+ target = project.new(PBXNativeTarget)
94
+ project.targets << target
95
+ target.name = name
96
+ target.product_name = product_basename
97
+ target.product_type = Constants::PRODUCT_TYPE_UTI[:bundle]
98
+
99
+ # Configuration List
100
+ cl = project.new(XCConfigurationList)
101
+ cl.default_configuration_is_visible = '0'
102
+ cl.default_configuration_name = 'Release'
103
+ release_conf = project.new(XCBuildConfiguration)
104
+ release_conf.name = 'Release'
105
+ release_conf.build_settings = common_build_settings(nil, platform, nil, target.product_type)
106
+ debug_conf = project.new(XCBuildConfiguration)
107
+ debug_conf.name = 'Debug'
108
+ debug_conf.build_settings = common_build_settings(nil, platform, nil, target.product_type)
109
+ cl.build_configurations << release_conf
110
+ cl.build_configurations << debug_conf
111
+ target.build_configuration_list = cl
112
+
113
+ # Product
114
+ product = product_group.new_bundle(target.product_name)
115
+ target.product_reference = product
116
+
117
+ # Build phases
118
+ build_phases_for_target_type(:bundle).each { |phase| target.build_phases << project.new(phase) }
119
+
120
+ target
121
+ end
122
+
123
+ # Creates a new aggregate target and adds it to the project.
124
+ #
125
+ # The target is configured for the given platform.
126
+ #
127
+ # @param [Project] project
128
+ # the project to which the target should be added.
129
+ #
130
+ # @param [String] name
131
+ # the name of the aggregate target.
132
+ #
133
+ # @param [Symbol] platform
134
+ # the platform of the aggregate target. Can be `:ios` or `:osx`.
135
+ #
136
+ # @param [String] deployment_target
137
+ # the deployment target for the platform.
138
+ #
139
+ # @return [PBXAggregateTarget] the target.
140
+ #
141
+ def self.new_aggregate_target(project, name, platform, deployment_target)
142
+ target = project.new(PBXAggregateTarget)
143
+ project.targets << target
144
+ target.name = name
145
+ target.build_configuration_list = configuration_list(project, platform, deployment_target)
146
+ target
147
+ end
148
+
149
+ # Creates a new legacy target and adds it to the project.
150
+ #
151
+ # The target is configured for the given platform.
152
+ #
153
+ # @param [Project] project
154
+ # the project to which the target should be added.
155
+ #
156
+ # @param [String] name
157
+ # the name of the aggregate target.
158
+ #
159
+ # @param [String] build_tool_path
160
+ # the build tool path to use for this target.
161
+ #
162
+ # @param [String] build_arguments_string
163
+ # the build arguments string to use for this target.
164
+ #
165
+ # @param [String] build_working_directory
166
+ # the build working directory to use for this target.
167
+ #
168
+ # @param [String] pass_build_settings_in_environment
169
+ # whether to pass build settings in the environment during execution of this target.
170
+ #
171
+ # @return [PBXLegacyTarget] the target.
172
+ #
173
+ def self.new_legacy_target(project, name, build_tool_path = '/usr/bin/make', build_arguments_string = '$(ACTION)',
174
+ build_working_directory = nil, pass_build_settings_in_environment = '1')
175
+ target = project.new(PBXLegacyTarget)
176
+ project.targets << target
177
+ target.name = name
178
+ target.build_configuration_list = configuration_list(project)
179
+ target.build_tool_path = build_tool_path
180
+ target.build_arguments_string = build_arguments_string
181
+ target.build_working_directory = build_working_directory
182
+ target.pass_build_settings_in_environment = pass_build_settings_in_environment
183
+ target
184
+ end
185
+
186
+ # @!group Private Helpers
187
+
188
+ #-----------------------------------------------------------------------#
189
+
190
+ # Returns a new configuration list, populated with release and debug
191
+ # configurations with common build settings for the given platform.
192
+ #
193
+ # @param [Project] project
194
+ # the project to which the configuration list should be added.
195
+ #
196
+ # @param [Symbol] platform
197
+ # the platform for the configuration list, can be `:ios` or `:osx`.
198
+ #
199
+ # @param [String] deployment_target
200
+ # the deployment target for the platform.
201
+ #
202
+ # @param [Symbol] target_product_type
203
+ # the product type of the target, can be any of `Constants::PRODUCT_TYPE_UTI.values`
204
+ # or `Constants::PRODUCT_TYPE_UTI.keys`.
205
+ #
206
+ # @param [Symbol] language
207
+ # the primary language of the target, can be `:objc` or `:swift`.
208
+ #
209
+ # @return [XCConfigurationList] the generated configuration list.
210
+ #
211
+ def self.configuration_list(project, platform = nil, deployment_target = nil, target_product_type = nil, language = nil)
212
+ cl = project.new(XCConfigurationList)
213
+ cl.default_configuration_is_visible = '0'
214
+ cl.default_configuration_name = 'Release'
215
+
216
+ release_conf = project.new(XCBuildConfiguration)
217
+ release_conf.name = 'Release'
218
+ release_conf.build_settings = common_build_settings(:release, platform, deployment_target, target_product_type, language)
219
+
220
+ debug_conf = project.new(XCBuildConfiguration)
221
+ debug_conf.name = 'Debug'
222
+ debug_conf.build_settings = common_build_settings(:debug, platform, deployment_target, target_product_type, language)
223
+
224
+ cl.build_configurations << release_conf
225
+ cl.build_configurations << debug_conf
226
+
227
+ existing_configurations = cl.build_configurations.map(&:name)
228
+ project.build_configurations.each do |configuration|
229
+ next if existing_configurations.include?(configuration.name)
230
+
231
+ new_config = project.new(XCBuildConfiguration)
232
+ new_config.name = configuration.name
233
+ new_config.build_settings = common_build_settings(configuration.type, platform, deployment_target, target_product_type, language)
234
+ cl.build_configurations << new_config
235
+ end
236
+
237
+ cl
238
+ end
239
+
240
+ # Returns the common build settings for a given platform and configuration
241
+ # name.
242
+ #
243
+ # @param [Symbol] type
244
+ # the type of the build configuration, can be `:release` or
245
+ # `:debug`.
246
+ #
247
+ # @param [Symbol] platform
248
+ # the platform for the build settings, can be `:ios` or `:osx`.
249
+ #
250
+ # @param [String] deployment_target
251
+ # the deployment target for the platform.
252
+ #
253
+ # @param [Symbol] target_product_type
254
+ # the product type of the target, can be any of
255
+ # `Constants::PRODUCT_TYPE_UTI.values`
256
+ # or `Constants::PRODUCT_TYPE_UTI.keys`. Default is :application.
257
+ #
258
+ # @param [Symbol] language
259
+ # the primary language of the target, can be `:objc` or `:swift`.
260
+ #
261
+ # @return [Hash] The common build settings
262
+ #
263
+ def self.common_build_settings(type, platform = nil, deployment_target = nil, target_product_type = nil, language = :objc)
264
+ target_product_type = (Constants::PRODUCT_TYPE_UTI.find { |_, v| v == target_product_type } || [target_product_type || :application])[0]
265
+ common_settings = Constants::COMMON_BUILD_SETTINGS
266
+
267
+ # Use intersecting settings for all key sets as base
268
+ settings = deep_dup(common_settings[:all])
269
+
270
+ # Match further common settings by key sets
271
+ keys = [type, platform, target_product_type, language].compact
272
+ key_combinations = (1..keys.length).flat_map { |n| keys.combination(n).to_a }
273
+ key_combinations.each do |key_combination|
274
+ settings.merge!(deep_dup(common_settings[key_combination] || {}))
275
+ end
276
+
277
+ if deployment_target
278
+ case platform
279
+ when :ios
280
+ settings['IPHONEOS_DEPLOYMENT_TARGET'] = deployment_target
281
+ settings['CLANG_ENABLE_OBJC_WEAK'] = 'NO' if deployment_target < '5'
282
+ when :osx
283
+ settings['MACOSX_DEPLOYMENT_TARGET'] = deployment_target
284
+ settings['CLANG_ENABLE_OBJC_WEAK'] = 'NO' if deployment_target < '10.7'
285
+ when :tvos
286
+ settings['TVOS_DEPLOYMENT_TARGET'] = deployment_target
287
+ when :watchos
288
+ settings['WATCHOS_DEPLOYMENT_TARGET'] = deployment_target
289
+ end
290
+ end
291
+
292
+ settings
293
+ end
294
+
295
+ # Creates a deep copy of the given object
296
+ #
297
+ # @param [Object] object
298
+ # the object to copy.
299
+ #
300
+ # @return [Object] The deep copy of the object.
301
+ #
302
+ def self.deep_dup(object)
303
+ case object
304
+ when Hash
305
+ new_hash = {}
306
+ object.each do |key, value|
307
+ new_hash[key] = deep_dup(value)
308
+ end
309
+ new_hash
310
+ when Array
311
+ object.map { |value| deep_dup(value) }
312
+ else
313
+ object.dup
314
+ end
315
+ end
316
+
317
+ # Returns the build phases, in order, that appear by default
318
+ # on a target of the given type.
319
+ #
320
+ # @param [Symbol] type
321
+ # the name of the target type.
322
+ #
323
+ # @return [Array<String>] The list of build phase class names for the target type.
324
+ #
325
+ def self.build_phases_for_target_type(type)
326
+ case type
327
+ when :static_library, :dynamic_library
328
+ %w(Headers Sources Frameworks)
329
+ when :framework
330
+ %w(Headers Sources Frameworks Resources)
331
+ when :command_line_tool
332
+ %w(Sources Frameworks)
333
+ else
334
+ %w(Sources Frameworks Resources)
335
+ end.map { |phase| "PBX#{phase}BuildPhase" }
336
+ end
337
+
338
+ #-----------------------------------------------------------------------#
339
+ end
340
+ end
341
+ end
@@ -0,0 +1,132 @@
1
+ module Xcodeproj
2
+ class Project
3
+ class UUIDGenerator
4
+ require 'digest'
5
+
6
+ def initialize(projects)
7
+ @projects = Array(projects)
8
+ @paths_by_object = {}
9
+ end
10
+
11
+ def generate!
12
+ generate_all_paths_by_objects(@projects)
13
+
14
+ new_objects_by_project = Hash[@projects.map do |project|
15
+ [project, switch_uuids(project)]
16
+ end]
17
+ all_new_objects_by_project = new_objects_by_project.values.flat_map(&:values)
18
+ all_objects_by_uuid = @projects.map(&:objects_by_uuid).inject(:merge)
19
+ all_objects = @projects.flat_map(&:objects)
20
+ verify_no_duplicates!(all_objects, all_new_objects_by_project)
21
+ @projects.each { |project| fixup_uuid_references(project, all_objects_by_uuid) }
22
+ new_objects_by_project.each do |project, new_objects_by_uuid|
23
+ project.instance_variable_set(:@generated_uuids, project.instance_variable_get(:@available_uuids))
24
+ project.instance_variable_set(:@objects_by_uuid, new_objects_by_uuid)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ UUID_ATTRIBUTES = [:remote_global_id_string, :container_portal, :target_proxy].freeze
31
+
32
+ def verify_no_duplicates!(all_objects, all_new_objects)
33
+ duplicates = all_objects - all_new_objects
34
+ UserInterface.warn "[Xcodeproj] Generated duplicate UUIDs:\n\n" <<
35
+ duplicates.map { |d| "#{d.isa} -- #{@paths_by_object[d]}" }.join("\n") unless duplicates.empty?
36
+ end
37
+
38
+ def fixup_uuid_references(target_project, all_objects_by_uuid)
39
+ fixup = ->(object, attr) do
40
+ if object.respond_to?(attr) && link = all_objects_by_uuid[object.send(attr)]
41
+ object.send(:"#{attr}=", link.uuid)
42
+ end
43
+ end
44
+ target_project.objects.each do |object|
45
+ UUID_ATTRIBUTES.each do |attr|
46
+ fixup[object, attr]
47
+ end
48
+ end
49
+
50
+ if (project_attributes = target_project.root_object.attributes) && project_attributes['TargetAttributes']
51
+ project_attributes['TargetAttributes'] = Hash[project_attributes['TargetAttributes'].map do |target_uuid, attributes|
52
+ if test_target_id = attributes['TestTargetID']
53
+ attributes = attributes.merge('TestTargetID' => all_objects_by_uuid[test_target_id].uuid)
54
+ end
55
+ if target_object = all_objects_by_uuid[target_uuid]
56
+ target_uuid = target_object.uuid
57
+ end
58
+ [target_uuid, attributes]
59
+ end]
60
+ end
61
+ end
62
+
63
+ def generate_all_paths_by_objects(projects)
64
+ projects.each { |project| generate_paths(project.root_object, project.path.basename.to_s) }
65
+ end
66
+
67
+ def generate_paths(object, path = '')
68
+ existing = @paths_by_object[object] || path
69
+ return existing if @paths_by_object.key?(object)
70
+ @paths_by_object[object] = path.size > existing.size ? path : existing
71
+
72
+ object.to_one_attributes.each do |attrb|
73
+ obj = attrb.get_value(object)
74
+ generate_paths(obj, path + '/' << attrb.plist_name) if obj
75
+ end
76
+
77
+ object.to_many_attributes.each do |attrb|
78
+ attrb.get_value(object).each do |o|
79
+ generate_paths(o, path + '/' << attrb.plist_name << "/#{path_component_for_object(o)}")
80
+ end
81
+ end
82
+
83
+ object.references_by_keys_attributes.each do |attrb|
84
+ attrb.get_value(object).each do |dictionary|
85
+ dictionary.each do |key, value|
86
+ generate_paths(value, path + '/' << attrb.plist_name << "/k:#{key}/#{path_component_for_object(value)}")
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ def switch_uuids(project)
93
+ project.mark_dirty!
94
+ project.objects.each_with_object({}) do |object, hash|
95
+ next unless path = @paths_by_object[object]
96
+ uuid = uuid_for_path(path)
97
+ object.instance_variable_set(:@uuid, uuid)
98
+ hash[uuid] = object
99
+ end
100
+ end
101
+
102
+ def uuid_for_path(path)
103
+ Digest::MD5.hexdigest(path).upcase
104
+ end
105
+
106
+ def path_component_for_object(object)
107
+ @path_component_for_object ||= Hash.new do |cache, key|
108
+ component = tree_hash_to_path(key.to_tree_hash)
109
+ component << key.hierarchy_path.to_s if key.respond_to?(:hierarchy_path)
110
+ cache[key] = component
111
+ end
112
+ @path_component_for_object[object]
113
+ end
114
+
115
+ def tree_hash_to_path(object, depth = 4)
116
+ return '|' if depth.zero?
117
+ case object
118
+ when Hash
119
+ object.sort.each_with_object('') do |(key, value), string|
120
+ string << key << ':' << tree_hash_to_path(value, depth - 1) << ','
121
+ end
122
+ when Array
123
+ object.map do |value|
124
+ tree_hash_to_path(value, depth - 1)
125
+ end.join(',')
126
+ else
127
+ object.to_s
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end