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,386 @@
1
+ # frozen_string_literal: true
2
+ require 'shellwords'
3
+ require 'xcodeproj/config/other_linker_flags_parser'
4
+
5
+ module Xcodeproj
6
+ # This class holds the data for a Xcode build settings file (xcconfig) and
7
+ # provides support for serialization.
8
+ #
9
+ class Config
10
+ require 'set'
11
+
12
+ KEY_VALUE_PATTERN = /
13
+ (
14
+ [^=\[]+ # Any char, but not an assignment operator
15
+ # or subscript (non-greedy)
16
+ (?: # One or multiple conditional subscripts
17
+ \[
18
+ [^\]]* # The subscript key
19
+ (?:
20
+ = # The subscript comparison operator
21
+ [^\]]* # The subscript value
22
+ )?
23
+ \]
24
+ )*
25
+ )
26
+ \s* # Whitespaces after the key (needed because subscripts
27
+ # always end with ']')
28
+ = # The assignment operator
29
+ (.*) # The value
30
+ /x
31
+ private_constant :KEY_VALUE_PATTERN
32
+
33
+ INHERITED = %w($(inherited) ${inherited}).freeze
34
+ private_constant :INHERITED
35
+
36
+ INHERITED_REGEXP = Regexp.union(INHERITED)
37
+ private_constant :INHERITED_REGEXP
38
+
39
+ # @return [Hash{String => String}] The attributes of the settings file
40
+ # excluding frameworks, weak_framework and libraries.
41
+ #
42
+ attr_accessor :attributes
43
+
44
+ # @return [Hash{Symbol => Set<String>}] The other linker flags by key.
45
+ # Xcodeproj handles them in a dedicated way to prevent duplication
46
+ # of the libraries and of the frameworks.
47
+ #
48
+ attr_accessor :other_linker_flags
49
+
50
+ # @return [Array] The list of the configuration files included by this
51
+ # configuration file (`#include "SomeConfig"`).
52
+ #
53
+ attr_accessor :includes
54
+
55
+ # @param [Hash, File, String] xcconfig_hash_or_file
56
+ # The initial data.
57
+ #
58
+ def initialize(xcconfig_hash_or_file = {})
59
+ @attributes = {}
60
+ @includes = []
61
+ @other_linker_flags = {}
62
+ [:simple, :frameworks, :weak_frameworks, :libraries, :arg_files, :force_load].each do |key|
63
+ @other_linker_flags[key] = Set.new
64
+ end
65
+ merge!(extract_hash(xcconfig_hash_or_file))
66
+ end
67
+
68
+ def inspect
69
+ to_hash.inspect
70
+ end
71
+
72
+ def ==(other)
73
+ other.attributes == attributes && other.other_linker_flags == other_linker_flags && other.includes == includes
74
+ end
75
+
76
+ public
77
+
78
+ # @!group Serialization
79
+ #-------------------------------------------------------------------------#
80
+
81
+ # Sorts the internal data by setting name and serializes it in the xcconfig
82
+ # format.
83
+ #
84
+ # @example
85
+ #
86
+ # config = Config.new('PODS_ROOT' => '"$(SRCROOT)/Pods"', 'OTHER_LDFLAGS' => '-lxml2')
87
+ # config.to_s # => "OTHER_LDFLAGS = -lxml2\nPODS_ROOT = \"$(SRCROOT)/Pods\""
88
+ #
89
+ # @return [String] The serialized internal data.
90
+ #
91
+ def to_s(prefix = nil)
92
+ include_lines = includes.map { |path| "#include \"#{normalized_xcconfig_path(path)}\"" }
93
+ settings = to_hash(prefix).sort_by(&:first).map { |k, v| "#{k} = #{v}".strip }
94
+ (include_lines + settings).join("\n") << "\n"
95
+ end
96
+
97
+ # Writes the serialized representation of the internal data to the given
98
+ # path.
99
+ #
100
+ # @param [Pathname] pathname
101
+ # The file where the data should be written to.
102
+ #
103
+ # @return [void]
104
+ #
105
+ def save_as(pathname, prefix = nil)
106
+ if File.exist?(pathname)
107
+ return if Config.new(pathname) == self
108
+ end
109
+
110
+ pathname.open('w') { |file| file << to_s(prefix) }
111
+ end
112
+
113
+ # The hash representation of the xcconfig. The hash includes the
114
+ # frameworks, the weak frameworks, the libraries and the simple other
115
+ # linker flags in the `Other Linker Flags` (`OTHER_LDFLAGS`).
116
+ #
117
+ # @note All the values are sorted to have a consistent output in Ruby
118
+ # 1.8.7.
119
+ #
120
+ # @return [Hash] The hash representation
121
+ #
122
+ def to_hash(prefix = nil)
123
+ list = []
124
+ list += other_linker_flags[:simple].to_a.sort
125
+ modifiers = {
126
+ :frameworks => '-framework ',
127
+ :weak_frameworks => '-weak_framework ',
128
+ :libraries => '-l',
129
+ :arg_files => '@',
130
+ :force_load => '-force_load',
131
+ }
132
+ [:libraries, :frameworks, :weak_frameworks, :arg_files, :force_load].each do |key|
133
+ modifier = modifiers[key]
134
+ sorted = other_linker_flags[key].to_a.sort
135
+ if key == :force_load
136
+ list += sorted.map { |l| %(#{modifier} #{l}) }
137
+ else
138
+ list += sorted.map { |l| %(#{modifier}"#{l}") }
139
+ end
140
+ end
141
+
142
+ result = attributes.dup
143
+ result['OTHER_LDFLAGS'] = list.join(' ') unless list.empty?
144
+ result.reject! { |_, v| INHERITED.any? { |i| i == v.to_s.strip } }
145
+
146
+ result = @includes.map do |incl|
147
+ path = File.expand_path(incl, @filepath.dirname)
148
+ if File.readable? path
149
+ Xcodeproj::Config.new(path).to_hash
150
+ else
151
+ {}
152
+ end
153
+ end.inject(&:merge).merge(result) unless @filepath.nil? || @includes.empty?
154
+
155
+ if prefix
156
+ Hash[result.map { |k, v| [prefix + k, v] }]
157
+ else
158
+ result
159
+ end
160
+ end
161
+
162
+ alias_method :to_h, :to_hash
163
+
164
+ # @return [Set<String>] The list of the frameworks required by this
165
+ # settings file.
166
+ #
167
+ def frameworks
168
+ other_linker_flags[:frameworks]
169
+ end
170
+
171
+ # @return [Set<String>] The list of the *weak* frameworks required by
172
+ # this settings file.
173
+ #
174
+ def weak_frameworks
175
+ other_linker_flags[:weak_frameworks]
176
+ end
177
+
178
+ # @return [Set<String>] The list of the libraries required by this
179
+ # settings file.
180
+ #
181
+ def libraries
182
+ other_linker_flags[:libraries]
183
+ end
184
+
185
+ # @return [Set<String>] The list of the arg files required by this
186
+ # settings file.
187
+ #
188
+ def arg_files
189
+ other_linker_flags[:arg_files]
190
+ end
191
+
192
+ public
193
+
194
+ # @!group Merging
195
+ #-------------------------------------------------------------------------#
196
+
197
+ # Merges the given xcconfig representation in the receiver.
198
+ #
199
+ # @example
200
+ #
201
+ # config = Config.new('PODS_ROOT' => '"$(SRCROOT)/Pods"', 'OTHER_LDFLAGS' => '-lxml2')
202
+ # config.merge!('OTHER_LDFLAGS' => '-lz', 'HEADER_SEARCH_PATHS' => '"$(PODS_ROOT)/Headers"')
203
+ # config.to_hash # => { 'PODS_ROOT' => '"$(SRCROOT)/Pods"', 'OTHER_LDFLAGS' => '-lxml2 -lz', 'HEADER_SEARCH_PATHS' => '"$(PODS_ROOT)/Headers"' }
204
+ #
205
+ # @note If a key in the given hash already exists in the internal data
206
+ # then its value is appended.
207
+ #
208
+ # @param [Hash, Config] config
209
+ # The xcconfig representation to merge.
210
+ #
211
+ # @todo The logic to normalize an hash should be extracted and the
212
+ # initializer should not call this method.
213
+ #
214
+ # @return [void]
215
+ #
216
+ def merge!(xcconfig)
217
+ if xcconfig.is_a? Config
218
+ merge_attributes!(xcconfig.attributes)
219
+ other_linker_flags.keys.each do |key|
220
+ other_linker_flags[key].merge(xcconfig.other_linker_flags[key])
221
+ end
222
+ else
223
+ merge_attributes!(xcconfig.to_hash)
224
+ if flags = attributes.delete('OTHER_LDFLAGS')
225
+ flags_by_key = OtherLinkerFlagsParser.parse(flags)
226
+ other_linker_flags.keys.each do |key|
227
+ other_linker_flags[key].merge(flags_by_key[key])
228
+ end
229
+ end
230
+ end
231
+ end
232
+ alias_method :<<, :merge!
233
+
234
+ # Creates a new #{Config} with the data of the receiver merged with the
235
+ # given xcconfig representation.
236
+ #
237
+ # @param [Hash, Config] config
238
+ # The xcconfig representation to merge.
239
+ #
240
+ # @return [Config] the new xcconfig.
241
+ #
242
+ def merge(config)
243
+ dup.tap { |x| x.merge!(config) }
244
+ end
245
+
246
+ # @return [Config] A copy of the receiver.
247
+ #
248
+ def dup
249
+ Xcodeproj::Config.new(to_hash.dup)
250
+ end
251
+
252
+ #-------------------------------------------------------------------------#
253
+
254
+ private
255
+
256
+ # @!group Private Helpers
257
+
258
+ # Returns a hash from the given argument reading it from disk if necessary.
259
+ #
260
+ # @param [String, Pathname, Hash] argument
261
+ # The source from where the hash should be extracted.
262
+ #
263
+ # @return [Hash]
264
+ #
265
+ def extract_hash(argument)
266
+ return argument if argument.is_a?(Hash)
267
+ if argument.respond_to? :read
268
+ @filepath = Pathname.new(argument.to_path)
269
+ hash_from_file_content(argument.read)
270
+ elsif File.readable?(argument.to_s)
271
+ @filepath = Pathname.new(argument.to_s)
272
+ hash_from_file_content(File.read(argument))
273
+ else
274
+ argument
275
+ end
276
+ end
277
+
278
+ # Returns a hash from the string representation of an Xcconfig file.
279
+ #
280
+ # @param [String] string
281
+ # The string representation of an xcconfig file.
282
+ #
283
+ # @return [Hash] the hash containing the xcconfig data.
284
+ #
285
+ def hash_from_file_content(string)
286
+ hash = {}
287
+ string.split("\n").each do |line|
288
+ uncommented_line = strip_comment(line)
289
+ if include = extract_include(uncommented_line)
290
+ @includes.push normalized_xcconfig_path(include)
291
+ else
292
+ key, value = extract_key_value(uncommented_line)
293
+ next unless key
294
+ value.gsub!(INHERITED_REGEXP) { |m| hash.fetch(key, m) }
295
+ hash[key] = value
296
+ end
297
+ end
298
+ hash
299
+ end
300
+
301
+ # Merges the given attributes hash while ensuring values are not duplicated.
302
+ #
303
+ # @param [Hash] attributes
304
+ # The attributes hash to merge into @attributes.
305
+ #
306
+ # @return [void]
307
+ #
308
+ def merge_attributes!(attributes)
309
+ @attributes.merge!(attributes) do |_, v1, v2|
310
+ v1 = v1.strip
311
+ v2 = v2.strip
312
+ v1_split = v1.shellsplit
313
+ v2_split = v2.shellsplit
314
+ if (v2_split - v1_split).empty? || v1_split.first(v2_split.size) == v2_split
315
+ v1
316
+ elsif v2_split.first(v1_split.size) == v1_split
317
+ v2
318
+ else
319
+ "#{v1} #{v2}"
320
+ end
321
+ end
322
+ end
323
+
324
+ # Strips the comments from a line of an xcconfig string.
325
+ #
326
+ # @param [String] line
327
+ # the line to process.
328
+ #
329
+ # @return [String] the uncommented line.
330
+ #
331
+ def strip_comment(line)
332
+ line.partition('//').first
333
+ end
334
+
335
+ # Returns the file included by a line of an xcconfig string if present.
336
+ #
337
+ # @param [String] line
338
+ # the line to process.
339
+ #
340
+ # @return [String] the included file.
341
+ # @return [Nil] if no include was found in the line.
342
+ #
343
+ def extract_include(line)
344
+ regexp = /#include\s*"(.+)"/
345
+ match = line.match(regexp)
346
+ match[1] if match
347
+ end
348
+
349
+ # Returns the key and the value described by the given line of an xcconfig.
350
+ #
351
+ # @param [String] line
352
+ # the line to process.
353
+ #
354
+ # @return [Array] A tuple where the first entry is the key and the second
355
+ # entry is the value.
356
+ #
357
+ def extract_key_value(line)
358
+ match = line.match(KEY_VALUE_PATTERN)
359
+ if match
360
+ key = match[1]
361
+ value = match[2]
362
+ [key.strip, value.strip]
363
+ else
364
+ []
365
+ end
366
+ end
367
+
368
+ # Normalizes the given path to an xcconfing file to be used in includes,
369
+ # appending the extension if necessary.
370
+ #
371
+ # @param [String] path
372
+ # The path of the file which will be included in the xcconfig.
373
+ #
374
+ # @return [String] The normalized path.
375
+ #
376
+ def normalized_xcconfig_path(path)
377
+ if File.extname(path) == '.xcconfig'
378
+ path
379
+ else
380
+ "#{path}.xcconfig"
381
+ end
382
+ end
383
+
384
+ #-------------------------------------------------------------------------#
385
+ end
386
+ end