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.
- checksums.yaml +7 -0
- data/LICENSE +19 -0
- data/README.md +95 -0
- data/bin/xcodeproj +10 -0
- data/lib/xcodeproj/command/config_dump.rb +91 -0
- data/lib/xcodeproj/command/project_diff.rb +56 -0
- data/lib/xcodeproj/command/show.rb +60 -0
- data/lib/xcodeproj/command/sort.rb +44 -0
- data/lib/xcodeproj/command/target_diff.rb +43 -0
- data/lib/xcodeproj/command.rb +63 -0
- data/lib/xcodeproj/config/other_linker_flags_parser.rb +73 -0
- data/lib/xcodeproj/config.rb +386 -0
- data/lib/xcodeproj/constants.rb +465 -0
- data/lib/xcodeproj/differ.rb +239 -0
- data/lib/xcodeproj/gem_version.rb +5 -0
- data/lib/xcodeproj/helper.rb +30 -0
- data/lib/xcodeproj/plist.rb +94 -0
- data/lib/xcodeproj/project/case_converter.rb +90 -0
- data/lib/xcodeproj/project/object/build_configuration.rb +255 -0
- data/lib/xcodeproj/project/object/build_file.rb +84 -0
- data/lib/xcodeproj/project/object/build_phase.rb +369 -0
- data/lib/xcodeproj/project/object/build_rule.rb +109 -0
- data/lib/xcodeproj/project/object/configuration_list.rb +117 -0
- data/lib/xcodeproj/project/object/container_item_proxy.rb +116 -0
- data/lib/xcodeproj/project/object/file_reference.rb +338 -0
- data/lib/xcodeproj/project/object/group.rb +506 -0
- data/lib/xcodeproj/project/object/helpers/build_settings_array_settings_by_object_version.rb +72 -0
- data/lib/xcodeproj/project/object/helpers/file_references_factory.rb +245 -0
- data/lib/xcodeproj/project/object/helpers/groupable_helper.rb +260 -0
- data/lib/xcodeproj/project/object/native_target.rb +751 -0
- data/lib/xcodeproj/project/object/reference_proxy.rb +86 -0
- data/lib/xcodeproj/project/object/root_object.rb +100 -0
- data/lib/xcodeproj/project/object/swift_package_product_dependency.rb +29 -0
- data/lib/xcodeproj/project/object/swift_package_remote_reference.rb +33 -0
- data/lib/xcodeproj/project/object/target_dependency.rb +94 -0
- data/lib/xcodeproj/project/object.rb +534 -0
- data/lib/xcodeproj/project/object_attributes.rb +522 -0
- data/lib/xcodeproj/project/object_dictionary.rb +210 -0
- data/lib/xcodeproj/project/object_list.rb +223 -0
- data/lib/xcodeproj/project/project_helper.rb +341 -0
- data/lib/xcodeproj/project/uuid_generator.rb +132 -0
- data/lib/xcodeproj/project.rb +874 -0
- data/lib/xcodeproj/scheme/abstract_scheme_action.rb +100 -0
- data/lib/xcodeproj/scheme/analyze_action.rb +19 -0
- data/lib/xcodeproj/scheme/archive_action.rb +59 -0
- data/lib/xcodeproj/scheme/build_action.rb +298 -0
- data/lib/xcodeproj/scheme/buildable_product_runnable.rb +55 -0
- data/lib/xcodeproj/scheme/buildable_reference.rb +129 -0
- data/lib/xcodeproj/scheme/command_line_arguments.rb +162 -0
- data/lib/xcodeproj/scheme/environment_variables.rb +170 -0
- data/lib/xcodeproj/scheme/execution_action.rb +86 -0
- data/lib/xcodeproj/scheme/launch_action.rb +179 -0
- data/lib/xcodeproj/scheme/location_scenario_reference.rb +49 -0
- data/lib/xcodeproj/scheme/macro_expansion.rb +34 -0
- data/lib/xcodeproj/scheme/profile_action.rb +57 -0
- data/lib/xcodeproj/scheme/remote_runnable.rb +92 -0
- data/lib/xcodeproj/scheme/send_email_action_content.rb +84 -0
- data/lib/xcodeproj/scheme/shell_script_action_content.rb +77 -0
- data/lib/xcodeproj/scheme/test_action.rb +394 -0
- data/lib/xcodeproj/scheme/xml_element_wrapper.rb +82 -0
- data/lib/xcodeproj/scheme.rb +375 -0
- data/lib/xcodeproj/user_interface.rb +22 -0
- data/lib/xcodeproj/workspace/file_reference.rb +79 -0
- data/lib/xcodeproj/workspace/group_reference.rb +67 -0
- data/lib/xcodeproj/workspace/reference.rb +40 -0
- data/lib/xcodeproj/workspace.rb +277 -0
- data/lib/xcodeproj/xcodebuild_helper.rb +108 -0
- data/lib/xcodeproj.rb +29 -0
- 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
|