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,239 @@
1
+ module Xcodeproj
2
+ # Computes the recursive diff of Hashes, Array and other objects.
3
+ #
4
+ # Useful to compare two projects. Inspired from
5
+ # 'active_support/core_ext/hash/diff'.
6
+ #
7
+ # @example
8
+ # h1 = { :common => 'value', :changed => 'v1' }
9
+ # h2 = { :common => 'value', :changed => 'v2', :addition => 'new_value' }
10
+ # h1.recursive_diff(h2) == {
11
+ # :changed => {
12
+ # :self => 'v1',
13
+ # :other => 'v2'
14
+ # },
15
+ # :addition => {
16
+ # :self => nil,
17
+ # :other => 'new_value'
18
+ # }
19
+ # } #=> true
20
+ #
21
+ #
22
+ #
23
+ #
24
+ module Differ
25
+ # Computes the recursive difference of two given values.
26
+ #
27
+ # @param [Object] value_1
28
+ # The first value to compare.
29
+ #
30
+ # @param [Object] value_2
31
+ # The second value to compare.
32
+ #
33
+ # @param [Object] key_1
34
+ # The key for the diff of value_1.
35
+ #
36
+ # @param [Object] key_2
37
+ # The key for the diff of value_2.
38
+ #
39
+ # @param [Object] id_key
40
+ # The key used to identify correspondent hashes in an array.
41
+ #
42
+ # @return [Hash] The diff
43
+ # @return [Nil] if the given values are equal.
44
+ #
45
+ def self.diff(value_1, value_2, options = {})
46
+ options[:key_1] ||= 'value_1'
47
+ options[:key_2] ||= 'value_2'
48
+ options[:id_key] ||= nil
49
+
50
+ method = if value_1.class == value_2.class
51
+ case value_1
52
+ when Hash then :hash_diff
53
+ when Array then :array_diff
54
+ else :generic_diff
55
+ end
56
+ else
57
+ :generic_diff
58
+ end
59
+ send(method, value_1, value_2, options)
60
+ end
61
+
62
+ # Optimized for reducing the noise from the tree hash of projects
63
+ #
64
+ def self.project_diff(project_1, project_2, key_1 = 'project_1', key_2 = 'project_2')
65
+ project_1 = project_1.to_tree_hash unless project_1.is_a?(Hash)
66
+ project_2 = project_2.to_tree_hash unless project_2.is_a?(Hash)
67
+ options = {
68
+ :key_1 => key_1,
69
+ :key_2 => key_2,
70
+ :id_key => 'displayName',
71
+ }
72
+ diff(project_1, project_2, options)
73
+ end
74
+
75
+ #-------------------------------------------------------------------------#
76
+
77
+ public
78
+
79
+ # @!group Type specific handlers
80
+
81
+ # Computes the recursive difference of two hashes.
82
+ #
83
+ # @see diff
84
+ #
85
+ def self.hash_diff(value_1, value_2, options)
86
+ ensure_class(value_1, Hash)
87
+ ensure_class(value_2, Hash)
88
+ return nil if value_1 == value_2
89
+
90
+ result = {}
91
+ all_keys = (value_1.keys + value_2.keys).uniq
92
+ all_keys.each do |key|
93
+ key_value_1 = value_1[key]
94
+ key_value_2 = value_2[key]
95
+ diff = diff(key_value_1, key_value_2, options)
96
+ if diff
97
+ result[key] = diff if diff
98
+ end
99
+ end
100
+ if result.empty?
101
+ nil
102
+ else
103
+ result
104
+ end
105
+ end
106
+
107
+ # Returns the recursive diff of two arrays.
108
+ #
109
+ # @see diff
110
+ #
111
+ def self.array_diff(value_1, value_2, options)
112
+ ensure_class(value_1, Array)
113
+ ensure_class(value_2, Array)
114
+ return nil if value_1 == value_2
115
+
116
+ new_objects_value_1 = (value_1 - value_2)
117
+ new_objects_value_2 = (value_2 - value_1)
118
+ return nil if value_1.empty? && value_2.empty?
119
+
120
+ matched_diff = {}
121
+ if id_key = options[:id_key]
122
+ matched_value_1 = []
123
+ matched_value_2 = []
124
+ new_objects_value_1.each do |entry_value_1|
125
+ if entry_value_1.is_a?(Hash)
126
+ id_value = entry_value_1[id_key]
127
+ entry_value_2 = new_objects_value_2.find do |entry|
128
+ entry[id_key] == id_value
129
+ end
130
+ if entry_value_2
131
+ matched_value_1 << entry_value_1
132
+ matched_value_2 << entry_value_2
133
+ diff = diff(entry_value_1, entry_value_2, options)
134
+ matched_diff[id_value] = diff if diff
135
+ end
136
+ end
137
+ end
138
+
139
+ new_objects_value_1 -= matched_value_1
140
+ new_objects_value_2 -= matched_value_2
141
+ end
142
+
143
+ if new_objects_value_1.empty? && new_objects_value_2.empty?
144
+ if matched_diff.empty?
145
+ nil
146
+ else
147
+ matched_diff
148
+ end
149
+ else
150
+ result = {}
151
+ result[options[:key_1]] = new_objects_value_1 unless new_objects_value_1.empty?
152
+ result[options[:key_2]] = new_objects_value_2 unless new_objects_value_2.empty?
153
+ result[:diff] = matched_diff unless matched_diff.empty?
154
+ result
155
+ end
156
+ end
157
+
158
+ # Returns the diff of two generic objects.
159
+ #
160
+ # @see diff
161
+ #
162
+ def self.generic_diff(value_1, value_2, options)
163
+ return nil if value_1 == value_2
164
+
165
+ {
166
+ options[:key_1] => value_1,
167
+ options[:key_2] => value_2,
168
+ }
169
+ end
170
+
171
+ #-------------------------------------------------------------------------#
172
+
173
+ public
174
+
175
+ # @!group Cleaning
176
+
177
+ # Returns a copy of the hash where the given key is removed recursively.
178
+ #
179
+ # @param [Hash] hash
180
+ # The hash to clean
181
+ #
182
+ # @param [Object] key
183
+ # The key to remove.
184
+ #
185
+ # @return [Hash] A copy of the hash without the key.
186
+ #
187
+ def self.clean_hash(hash, key)
188
+ new_hash = hash.dup
189
+ self.clean_hash!(new_hash, key)
190
+ new_hash
191
+ end
192
+
193
+ # Recursively cleans a key from the given hash.
194
+ #
195
+ # @param [Hash] hash
196
+ # The hash to clean
197
+ #
198
+ # @param [Object] key
199
+ # The key to remove.
200
+ #
201
+ # @return [void]
202
+ #
203
+ def self.clean_hash!(hash, key)
204
+ hash.delete(key)
205
+ hash.each do |_, value|
206
+ case value
207
+ when Hash
208
+ clean_hash!(value, key)
209
+ when Array
210
+ value.each { |entry| clean_hash!(entry, key) if entry.is_a?(Hash) }
211
+ end
212
+ end
213
+ end
214
+
215
+ #-------------------------------------------------------------------------#
216
+
217
+ private
218
+
219
+ # @! Helpers
220
+
221
+ # Ensures that the given object belongs to the given class.
222
+ #
223
+ # @param [Object] object
224
+ # The object to check.
225
+ #
226
+ # @param [Class] klass
227
+ # the expected class of the object.
228
+ #
229
+ # @raise If the object doesn't belong to the given class.
230
+ #
231
+ # @return [void]
232
+ #
233
+ def self.ensure_class(object, klass)
234
+ raise "Wrong type `#{object.inspect}`" unless object.is_a?(klass)
235
+ end
236
+
237
+ #-------------------------------------------------------------------------#
238
+ end
239
+ end
@@ -0,0 +1,5 @@
1
+ module Xcodeproj
2
+ # The version of the xcodeproj gem.
3
+ #
4
+ VERSION = '1.21.1'.freeze unless defined? Xcodeproj::VERSION
5
+ end
@@ -0,0 +1,30 @@
1
+ module Xcodeproj
2
+ module Helper
3
+ class TargetDiff
4
+ attr_reader :project, :target1, :target2
5
+
6
+ def initialize(project, target1_name, target2_name)
7
+ @project = project
8
+ unless @target1 = @project.targets.find { |target| target.name == target1_name }
9
+ raise ArgumentError, "Target 1 by name `#{target1_name}' not found in the project."
10
+ end
11
+ unless @target2 = @project.targets.find { |target| target.name == target2_name }
12
+ raise ArgumentError, "Target 1 by name `#{target2_name}' not found in the project."
13
+ end
14
+ end
15
+
16
+ # @return [Array<PBXBuildFile>] A list of source files (that will be
17
+ # compiled) which are in ‘target 2’ but not in ‘target 1’. The
18
+ # list is sorted by file path.
19
+ #
20
+ def new_source_build_files
21
+ new = @target2.source_build_phase.files.reject do |target2_build_file|
22
+ @target1.source_build_phase.files.any? do |target1_build_file|
23
+ target1_build_file.file_ref.path == target2_build_file.file_ref.path
24
+ end
25
+ end
26
+ new.sort_by { |build_file| build_file.file_ref.path }
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,94 @@
1
+ autoload :Nanaimo, 'nanaimo'
2
+ autoload :CFPropertyList, 'cfpropertylist'
3
+
4
+ module Xcodeproj
5
+ # Provides support for loading and serializing property list files.
6
+ #
7
+ module Plist
8
+ # @return [Hash] Returns the native objects loaded from a property list
9
+ # file.
10
+ #
11
+ # @param [#to_s] path
12
+ # The path of the file.
13
+ #
14
+ def self.read_from_path(path)
15
+ path = path.to_s
16
+ unless File.exist?(path)
17
+ raise Informative, "The plist file at path `#{path}` doesn't exist."
18
+ end
19
+ contents = File.read(path)
20
+ if file_in_conflict?(contents)
21
+ raise Informative, "The file `#{path}` is in a merge conflict."
22
+ end
23
+ case Nanaimo::Reader.plist_type(contents)
24
+ when :xml, :binary
25
+ CFPropertyList.native_types(CFPropertyList::List.new(:data => contents).value)
26
+ else
27
+ Nanaimo::Reader.new(contents).parse!.as_ruby
28
+ end
29
+ end
30
+
31
+ # Serializes a hash as an XML property list file.
32
+ #
33
+ # @param [#to_hash] hash
34
+ # The hash to store.
35
+ #
36
+ # @param [#to_s] path
37
+ # The path of the file.
38
+ #
39
+ def self.write_to_path(hash, path)
40
+ if hash.respond_to?(:to_hash)
41
+ hash = hash.to_hash
42
+ else
43
+ raise TypeError, "The given `#{hash.inspect}` must respond " \
44
+ "to #to_hash'."
45
+ end
46
+
47
+ unless path.is_a?(String) || path.is_a?(Pathname)
48
+ raise TypeError, "The given `#{path}` must be a string or 'pathname'."
49
+ end
50
+ path = path.to_s
51
+ raise IOError, 'Empty path.' if path.empty?
52
+
53
+ File.open(path, 'w') do |f|
54
+ plist = Nanaimo::Plist.new(hash, :xml)
55
+ Nanaimo::Writer::XMLWriter.new(plist, :pretty => true, :output => f, :strict => false).write
56
+ end
57
+ end
58
+
59
+ # The known modules that can serialize plists.
60
+ #
61
+ KNOWN_IMPLEMENTATIONS = []
62
+
63
+ class << self
64
+ # @deprecated This method will be removed in 2.0
65
+ #
66
+ # @return [Nil]
67
+ #
68
+ attr_accessor :implementation
69
+ end
70
+
71
+ # @deprecated This method will be removed in 2.0
72
+ #
73
+ # @return [Nil]
74
+ #
75
+ def self.autoload_implementation
76
+ end
77
+
78
+ # @return [Bool] Checks whether there are merge conflicts in the file.
79
+ #
80
+ # @param [#to_s] contents
81
+ # The contents of the file.
82
+ #
83
+ def self.file_in_conflict?(contents)
84
+ conflict_regex = /
85
+ ^<{7}(?!<) # Exactly 7 left arrows at the beginning of the line
86
+ [\w\W]* # Anything
87
+ ^={7}(?!=) # Exactly 7 equality symbols at the beginning of the line
88
+ [\w\W]* # Anything
89
+ ^>{7}(?!>) # Exactly 7 right arrows at the beginning of the line
90
+ /xm
91
+ contents.match(conflict_regex)
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,90 @@
1
+ module Xcodeproj
2
+ class Project
3
+ module Object
4
+ # Converts between camel case names used in the xcodeproj plist files
5
+ # and the ruby symbols used to represent them.
6
+ #
7
+ module CaseConverter
8
+ # @return [String] The plist equivalent of the given Ruby name.
9
+ #
10
+ # @param [Symbol, String] name
11
+ # The name to convert
12
+ #
13
+ # @param [Symbol, Nil] type
14
+ # The type of conversion. Pass `nil` for normal camel case and
15
+ # `:lower` for camel case starting with a lower case letter.
16
+ #
17
+ # @example
18
+ # CaseConverter.convert_to_plist(:project_ref) #=> ProjectRef
19
+ #
20
+ def self.convert_to_plist(name, type = nil)
21
+ case name
22
+ when :remote_global_id_string
23
+ 'remoteGlobalIDString'
24
+ else
25
+ if type == :lower
26
+ cache = plist_cache[:lower] ||= {}
27
+ cache[name] ||= camelize(name, :uppercase_first_letter => false)
28
+ else
29
+ cache = plist_cache[:normal] ||= {}
30
+ cache[name] ||= camelize(name)
31
+ end
32
+ end
33
+ end
34
+
35
+ # The following two methods are taken from activesupport,
36
+ # https://github.com/rails/rails/blob/v5.0.2/activesupport/lib/active_support/inflector/methods.rb
37
+ # all credit for them goes to the original authors.
38
+ #
39
+ # The code is used under the MIT license.
40
+
41
+ def self.camelize(term, uppercase_first_letter: true)
42
+ string = term.to_s
43
+ string = if uppercase_first_letter
44
+ string.sub(/^[a-z\d]*/, &:capitalize)
45
+ else
46
+ string.sub(/^(?:(?=a)b(?=\b|[A-Z_])|\w)/, &:downcase)
47
+ end
48
+ string.gsub!(%r{(?:_|(/))([a-z\d]*)}i) { "#{Regexp.last_match(1)}#{Regexp.last_match(2).capitalize}" }
49
+ string.gsub!('/'.freeze, '::'.freeze)
50
+ string
51
+ end
52
+ private_class_method :camelize
53
+
54
+ def self.underscore(camel_cased_word)
55
+ return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/
56
+ word = camel_cased_word.to_s.gsub('::'.freeze, '/'.freeze)
57
+ word.gsub!(/(?:(?<=([A-Za-z\d]))|\b)((?=a)b)(?=\b|[^a-z])/) { "#{Regexp.last_match(1) && '_'.freeze}#{Regexp.last_match(2).downcase}" }
58
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'.freeze)
59
+ word.gsub!(/([a-z\d])([A-Z])/, '\1_\2'.freeze)
60
+ word.tr!('-'.freeze, '_'.freeze)
61
+ word.downcase!
62
+ word
63
+ end
64
+ private_class_method :underscore
65
+
66
+ # @return [Symbol] The Ruby equivalent of the given plist name.
67
+ #
68
+ # @param [String] name
69
+ # The name to convert
70
+ #
71
+ # @example
72
+ # CaseConverter.convert_to_ruby('ProjectRef') #=> :project_ref
73
+ #
74
+ def self.convert_to_ruby(name)
75
+ underscore(name.to_s).to_sym
76
+ end
77
+
78
+ # @return [Hash] A cache for the conversion to the Plist format.
79
+ #
80
+ # @note A cache is used because this operation is performed for each
81
+ # attribute of the project when it is saved and caching it has
82
+ # an important performance benefit.
83
+ #
84
+ def self.plist_cache
85
+ @plist_cache ||= {}
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end