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,255 @@
1
+ module Xcodeproj
2
+ class Project
3
+ module Object
4
+ # Encapsulates the information a specific build configuration referenced
5
+ # by a {XCConfigurationList} which in turn might be referenced by a
6
+ # {PBXProject} or a {PBXNativeTarget}.
7
+ #
8
+ class XCBuildConfiguration < AbstractObject
9
+ MUTUAL_RECURSION_SENTINEL = 'xcodeproj.mutual_recursion_sentinel'.freeze
10
+
11
+ private_constant :MUTUAL_RECURSION_SENTINEL
12
+
13
+ # @!group Attributes
14
+
15
+ # @return [String] the name of the configuration.
16
+ #
17
+ attribute :name, String
18
+
19
+ # @return [Hash] the build settings to use for building the target.
20
+ #
21
+ attribute :build_settings, Hash, {}
22
+
23
+ # @return [PBXFileReference] an optional file reference to a
24
+ # configuration file (`.xcconfig`).
25
+ #
26
+ has_one :base_configuration_reference, PBXFileReference
27
+
28
+ public
29
+
30
+ # @!group AbstractObject Hooks
31
+ #---------------------------------------------------------------------#
32
+
33
+ # @return [Hash{String => Hash}] A hash suitable to display the object
34
+ # to the user.
35
+ #
36
+ def pretty_print
37
+ data = {}
38
+ data['Build Settings'] = sorted_build_settings
39
+ if base_configuration_reference
40
+ data['Base Configuration'] = base_configuration_reference.pretty_print
41
+ end
42
+ { name => data }
43
+ end
44
+
45
+ def to_hash_as(method = :to_hash)
46
+ super.tap do |hash|
47
+ normalize_array_settings(hash['buildSettings'])
48
+ end
49
+ end
50
+
51
+ # Sorts the build settings. Valid only in Ruby > 1.9.2 because in
52
+ # previous versions the hash are not sorted.
53
+ #
54
+ # @return [void]
55
+ #
56
+ def sort(_options = nil)
57
+ self.build_settings = sorted_build_settings
58
+ end
59
+
60
+ # @return [Boolean] Whether this configuration is configured for
61
+ # debugging.
62
+ #
63
+ def debug?
64
+ gcc_preprocessor_definitions = resolve_build_setting('GCC_PREPROCESSOR_DEFINITIONS')
65
+ gcc_preprocessor_definitions && gcc_preprocessor_definitions.include?('DEBUG=1')
66
+ end
67
+
68
+ # @return [Symbol] The symbolic type of this configuration, either
69
+ # `:debug` or `:release`.
70
+ #
71
+ def type
72
+ debug? ? :debug : :release
73
+ end
74
+
75
+ # @!group Helpers
76
+ #---------------------------------------------------------------------#
77
+
78
+ # Gets the value for the given build setting considering any configuration
79
+ # file present and resolving inheritance between them. It also takes in
80
+ # consideration environment variables.
81
+ #
82
+ # @param [String] key
83
+ # the key of the build setting.
84
+ #
85
+ # @param [PBXNativeTarget] root_target
86
+ # use this to resolve complete recursion between project and targets.
87
+ #
88
+ # @param [String] previous_key
89
+ # use this to resolve complete recursion between different build settings.
90
+ #
91
+ # @return [String] The value of the build setting
92
+ #
93
+ def resolve_build_setting(key, root_target = nil, previous_key = nil)
94
+ setting = build_settings[key]
95
+ setting = resolve_variable_substitution(key, setting, root_target, previous_key)
96
+
97
+ config_setting = config[key]
98
+ config_setting = resolve_variable_substitution(key, config_setting, root_target, previous_key)
99
+
100
+ project_setting = project.build_configuration_list[name]
101
+ project_setting = nil if equal?(project_setting)
102
+ project_setting &&= project_setting.resolve_build_setting(key, root_target)
103
+
104
+ defaults = {
105
+ 'CONFIGURATION' => name,
106
+ 'SRCROOT' => project.project_dir.to_s,
107
+ }
108
+
109
+ # if previous_key is nil, it means that we're back at the first call, so we can replace our sentinel string
110
+ # used to prevent recursion with nil
111
+ if previous_key.nil? && setting == MUTUAL_RECURSION_SENTINEL
112
+ setting = nil
113
+ end
114
+
115
+ [defaults[key], project_setting, config_setting, setting, ENV[key]].compact.reduce(nil) do |inherited, value|
116
+ expand_build_setting(value, inherited)
117
+ end
118
+ end
119
+
120
+ #---------------------------------------------------------------------#
121
+
122
+ private
123
+
124
+ VARIABLE_NAME_PATTERN =
125
+ '( # capture block
126
+ [_a-zA-Z0-9]+? # non-greedy lookup for everything contained in this list
127
+ )'.freeze
128
+ private_constant :VARIABLE_NAME_PATTERN
129
+
130
+ CAPTURE_VARIABLE_IN_BUILD_CONFIG = /
131
+ \$ # matches dollar sign literally
132
+ (?: # non-capturing group
133
+ [{] # matches a single character on this list
134
+ #{VARIABLE_NAME_PATTERN}
135
+ [}] # matches a single character on this list
136
+ | # or
137
+ [(] # matches a single character on this list
138
+ #{VARIABLE_NAME_PATTERN}
139
+ [)] # matches a single character on this list
140
+ )
141
+ /x
142
+ private_constant :CAPTURE_VARIABLE_IN_BUILD_CONFIG
143
+
144
+ def expand_build_setting(build_setting_value, config_value)
145
+ if build_setting_value.is_a?(Array) && config_value.is_a?(String)
146
+ config_value = split_build_setting_array_to_string(config_value)
147
+ elsif build_setting_value.is_a?(String) && config_value.is_a?(Array)
148
+ build_setting_value = split_build_setting_array_to_string(build_setting_value)
149
+ end
150
+
151
+ default = build_setting_value.is_a?(String) ? '' : []
152
+ inherited = config_value || default
153
+
154
+ return build_setting_value.gsub(Regexp.union(Constants::INHERITED_KEYWORDS), inherited) if build_setting_value.is_a? String
155
+ build_setting_value.flat_map { |value| Constants::INHERITED_KEYWORDS.include?(value) ? inherited : value }
156
+ end
157
+
158
+ def resolve_variable_substitution(key, value, root_target, previous_key = nil)
159
+ case value
160
+ when Array
161
+ return value.map { |v| resolve_variable_substitution(key, v, root_target) }
162
+ when nil
163
+ return
164
+ when String
165
+ # we know how to resolve strings!
166
+ nil
167
+ else
168
+ raise ArgumentError, "Settings values can only be nil, string, or array, got #{value.inspect} for #{key}"
169
+ end
170
+
171
+ unless variable_match_data = value.match(CAPTURE_VARIABLE_IN_BUILD_CONFIG)
172
+ # no variables left, return the value unchanged
173
+ return value
174
+ end
175
+ variable_reference, variable = *variable_match_data.values_at(0, 1, 2).compact
176
+
177
+ case variable
178
+ when 'inherited'
179
+ # this is handled separately, after resolving all other variable references
180
+ value
181
+ when key
182
+ # to prevent infinite recursion
183
+ nil
184
+ when previous_key
185
+ # to prevent infinite recursion; we don't return nil as for the self recursion because it needs to be
186
+ # distinguished outside this method too
187
+ MUTUAL_RECURSION_SENTINEL
188
+ else
189
+ configuration_to_resolve_against = root_target ? root_target.build_configuration_list[name] : self
190
+ resolved_value_for_variable = configuration_to_resolve_against.resolve_build_setting(variable, root_target, key) || ''
191
+
192
+ # we use this sentinel string instead of nil, because, otherwise, it would be swallowed by the default empty
193
+ # string from the preceding line, and we want to distinguish between mutual recursion and other cases
194
+ if resolved_value_for_variable == MUTUAL_RECURSION_SENTINEL
195
+ return MUTUAL_RECURSION_SENTINEL
196
+ end
197
+
198
+ value = value.gsub(variable_reference, resolved_value_for_variable)
199
+ resolve_variable_substitution(key, value, root_target)
200
+ end
201
+ end
202
+
203
+ def sorted_build_settings
204
+ sorted = {}
205
+ build_settings.keys.sort.each do |key|
206
+ sorted[key] = build_settings[key]
207
+ end
208
+ sorted
209
+ end
210
+
211
+ def normalize_array_settings(settings)
212
+ return unless settings
213
+
214
+ array_settings = BuildSettingsArraySettingsByObjectVersion[project.object_version]
215
+
216
+ settings.keys.each do |key|
217
+ next unless value = settings[key]
218
+ stripped_key = key.sub(/\[[^\]]+\]$/, '')
219
+ case value
220
+ when String
221
+ next unless array_settings.include?(stripped_key)
222
+ array_value = split_build_setting_array_to_string(value)
223
+ next unless array_value.size > 1
224
+ settings[key] = array_value
225
+ when Array
226
+ next if value.size > 1 && array_settings.include?(stripped_key)
227
+ settings[key] = value.join(' ')
228
+ end
229
+ end
230
+ end
231
+
232
+ def split_build_setting_array_to_string(string)
233
+ regexp = / *((['"]?).*?[^\\]\2)(?=( |\z))/
234
+ string.scan(regexp).map(&:first)
235
+ end
236
+
237
+ def config
238
+ return {} unless base_configuration_reference
239
+ @config ||=
240
+ if base_configuration_reference.real_path.exist?
241
+ Xcodeproj::Config.new(base_configuration_reference.real_path).to_hash.tap do |hash|
242
+ normalize_array_settings(hash)
243
+ end
244
+ else
245
+ {}
246
+ end
247
+ end
248
+
249
+ #---------------------------------------------------------------------#
250
+ end
251
+ end
252
+ end
253
+ end
254
+
255
+ require 'xcodeproj/project/object/helpers/build_settings_array_settings_by_object_version'
@@ -0,0 +1,84 @@
1
+ module Xcodeproj
2
+ class Project
3
+ module Object
4
+ # Contains the information about the build settings of a file used by an
5
+ # {AbstractBuildPhase}.
6
+ #
7
+ class PBXBuildFile < AbstractObject
8
+ # @!group Attributes
9
+
10
+ # @return [Hash] the list of build settings for this file.
11
+ #
12
+ # @note The contents of this array depend on the phase of the build
13
+ # file.
14
+ #
15
+ # For PBXHeadersBuildPhase is `{ "ATTRIBUTES" => [:value] }`
16
+ # where `:value` can be `Public`, `Private`, or nil
17
+ # (Protected).
18
+ #
19
+ attribute :settings, Hash
20
+
21
+ # @return [PBXFileReference] the file to build.
22
+ #
23
+ # @todo I think that is possible to add any kind of group (for
24
+ # example folders linked to a path).
25
+ #
26
+ has_one :file_ref, [
27
+ PBXFileReference,
28
+ PBXGroup,
29
+ PBXVariantGroup,
30
+ XCVersionGroup,
31
+ PBXReferenceProxy,
32
+ ]
33
+
34
+ # @return [XCSwiftPackageProductDependency] the Swift Package file to build.
35
+ #
36
+ has_one :product_ref, XCSwiftPackageProductDependency
37
+
38
+ # @return [String] the platform filter for this build file.
39
+ #
40
+ attribute :platform_filter, String
41
+
42
+ # @return [Array<String>] the platform filters for this build file.
43
+ #
44
+ attribute :platform_filters, Array
45
+
46
+ #---------------------------------------------------------------------#
47
+
48
+ public
49
+
50
+ # @!group AbstractObject Hooks
51
+
52
+ # @return [String] A name suitable for displaying the object to the
53
+ # user.
54
+ #
55
+ def display_name
56
+ if product_ref
57
+ product_ref.display_name
58
+ elsif file_ref
59
+ file_ref.display_name
60
+ else
61
+ super
62
+ end
63
+ end
64
+
65
+ # @return [Hash{String => Hash}, String] A hash suitable to display the
66
+ # object to the user.
67
+ #
68
+ def pretty_print
69
+ if settings.nil? || settings.empty?
70
+ display_name
71
+ else
72
+ { display_name => settings }
73
+ end
74
+ end
75
+
76
+ def ascii_plist_annotation
77
+ " #{display_name} in #{GroupableHelper.parent(self).display_name} "
78
+ end
79
+
80
+ #---------------------------------------------------------------------#
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,369 @@
1
+ module Xcodeproj
2
+ class Project
3
+ module Object
4
+ # @abstract
5
+ #
6
+ # This class is abstract and it doesn't appear in the project document.
7
+ #
8
+ class AbstractBuildPhase < AbstractObject
9
+ # @!group Attributes
10
+
11
+ # @return [ObjectList<PBXBuildFile>] the files processed by this build
12
+ # configuration.
13
+ #
14
+ has_many :files, PBXBuildFile
15
+
16
+ # @return [String] some kind of magic number which usually is
17
+ # '2147483647' (can be also `8` and `12` in
18
+ # PBXCopyFilesBuildPhase, one of the masks is
19
+ # run_only_for_deployment_postprocessing).
20
+ #
21
+ attribute :build_action_mask, String, '2147483647'
22
+
23
+ # @return [String] whether or not this should only be processed before
24
+ # deployment. Can be either '0', or '1'.
25
+ #
26
+ # @note This option is exposed in Xcode in the UI of
27
+ # PBXCopyFilesBuildPhase as `Copy only when installing` or in
28
+ # PBXShellScriptBuildPhase as `Run script only when
29
+ # installing`.
30
+ #
31
+ attribute :run_only_for_deployment_postprocessing, String, '0'
32
+
33
+ # @return [String] whether or not this run script will be forced to
34
+ # run even on incremental builds. Can be either '1', or
35
+ # missing. By default this option is disabled in Xcode.
36
+ #
37
+ # @note This setting is exposed in Xcode in the UI of
38
+ # PBXShellScriptBuildPhase as `Based on
39
+ # dependency analysis` (selected by default).
40
+ #
41
+ attribute :always_out_of_date, String
42
+
43
+ # @return [String] Comments associated with this build phase.
44
+ #
45
+ # @note This is apparently no longer used by Xcode.
46
+ #
47
+ attribute :comments, String
48
+
49
+ #--------------------------------------#
50
+
51
+ public
52
+
53
+ # @!group Helpers
54
+
55
+ # @return [Array<PBXFileReference>] the list of all the files
56
+ # referenced by this build phase.
57
+ #
58
+ def files_references
59
+ files.map(&:file_ref)
60
+ end
61
+
62
+ # @return [Array<String>] The display name of the build files.
63
+ #
64
+ def file_display_names
65
+ files.map(&:display_name)
66
+ end
67
+
68
+ # @return [PBXBuildFile] the first build file associated with the given
69
+ # file reference if one exists.
70
+ #
71
+ def build_file(file_ref)
72
+ (file_ref.referrers & files).first
73
+ end
74
+
75
+ # Returns whether a build file for the given file reference exists.
76
+ #
77
+ # @param [PBXFileReference] file_ref
78
+ #
79
+ # @return [Bool] whether the reference is already present.
80
+ #
81
+ def include?(file_ref)
82
+ !build_file(file_ref).nil?
83
+ end
84
+
85
+ # Adds a new build file, initialized with the given file reference, to
86
+ # the phase.
87
+ #
88
+ # @param [PBXFileReference] file_ref
89
+ # The file reference that should be added to the build phase.
90
+ #
91
+ # @return [PBXBuildFile] the build file generated.
92
+ #
93
+ def add_file_reference(file_ref, avoid_duplicates = false)
94
+ if avoid_duplicates && existing = build_file(file_ref)
95
+ existing
96
+ else
97
+ build_file = project.new(PBXBuildFile)
98
+ build_file.file_ref = file_ref
99
+ files << build_file
100
+ build_file
101
+ end
102
+ end
103
+
104
+ # Removes the build file associated with the given file reference from
105
+ # the phase.
106
+ #
107
+ # @param [PBXFileReference] file_ref
108
+ # The file to remove
109
+ #
110
+ # @return [void]
111
+ #
112
+ def remove_file_reference(file_ref)
113
+ build_file = files.find { |bf| bf.file_ref == file_ref }
114
+ remove_build_file(build_file) if build_file
115
+ end
116
+
117
+ # Removes a build file from the phase and clears its relationship to
118
+ # the file reference.
119
+ #
120
+ # @param [PBXBuildFile] build_file the file to remove
121
+ #
122
+ # @return [void]
123
+ #
124
+ def remove_build_file(build_file)
125
+ build_file.file_ref = nil
126
+ build_file.remove_from_project
127
+ end
128
+
129
+ # Removes all the build files from the phase and clears their
130
+ # relationship to the file reference.
131
+ #
132
+ # @return [void]
133
+ #
134
+ def clear
135
+ files.objects.each do |bf|
136
+ remove_build_file(bf)
137
+ end
138
+ end
139
+ alias_method :clear_build_files, :clear
140
+
141
+ def display_name
142
+ super.gsub(/BuildPhase$/, '')
143
+ end
144
+
145
+ def ascii_plist_annotation
146
+ " #{display_name} "
147
+ end
148
+
149
+ # Sorts the build files of the phase according to the display
150
+ # name or the path.
151
+ #
152
+ # @param [Hash] _options
153
+ # Not used.
154
+ #
155
+ # @return [void]
156
+ #
157
+ def sort(_options = nil)
158
+ files.sort! do |x, y|
159
+ result = File.basename(x.display_name.downcase, '.*') <=> File.basename(y.display_name.downcase, '.*')
160
+ if result.zero?
161
+ result = File.extname(x.display_name.downcase) <=> File.extname(y.display_name.downcase)
162
+ if result.zero? && x.file_ref.respond_to?(:full_path) && y.file_ref.respond_to?(:full_path)
163
+ result = x.file_ref.full_path.to_s.downcase <=> y.file_ref.full_path.to_s.downcase
164
+ end
165
+ end
166
+ result
167
+ end
168
+ end
169
+ end
170
+
171
+ #-----------------------------------------------------------------------#
172
+
173
+ # The phase responsible of copying headers. Known as `Copy Headers` in
174
+ # the UI.
175
+ #
176
+ # @note This phase can appear only once in a target.
177
+ #
178
+ class PBXHeadersBuildPhase < AbstractBuildPhase
179
+ end
180
+
181
+ #-----------------------------------------------------------------------#
182
+
183
+ # The phase responsible of compiling the files. Known as `Compile
184
+ # Sources` in the UI.
185
+ #
186
+ # @note This phase can appear only once in a target.
187
+ #
188
+ class PBXSourcesBuildPhase < AbstractBuildPhase
189
+ end
190
+
191
+ #-----------------------------------------------------------------------#
192
+
193
+ # The phase responsible on linking with frameworks. Known as `Link Binary
194
+ # With Libraries` in the UI.
195
+ #
196
+ # @note This phase can appear only once in a target.
197
+ #
198
+ class PBXFrameworksBuildPhase < AbstractBuildPhase
199
+ end
200
+
201
+ #-----------------------------------------------------------------------#
202
+
203
+ # The resources build phase apparently is a specialized copy build phase
204
+ # for resources. Known as `Copy Bundle Resources` in the UI. It is
205
+ # unclear if this is the only one capable of optimizing PNG.
206
+ #
207
+ # @note This phase can appear only once in a target.
208
+ #
209
+ class PBXResourcesBuildPhase < AbstractBuildPhase
210
+ end
211
+
212
+ #-----------------------------------------------------------------------#
213
+
214
+ # Phase that copies the files to the bundle of the target (aka `Copy
215
+ # Files`).
216
+ #
217
+ # @note This phase can appear multiple times in a target.
218
+ #
219
+ class PBXCopyFilesBuildPhase < AbstractBuildPhase
220
+ # @!group Attributes
221
+
222
+ # @return [String] the name of the build phase.
223
+ #
224
+ attribute :name, String
225
+
226
+ # @return [String] the subpath of `dst_subfolder_spec` where this file
227
+ # should be copied to.
228
+ #
229
+ # @note Can accept environment variables like `$(PRODUCT_NAME)`.
230
+ #
231
+ attribute :dst_path, String, ''
232
+
233
+ # @return [String] the path (destination) where the files should be
234
+ # copied to.
235
+ #
236
+ attribute :dst_subfolder_spec, String, Constants::COPY_FILES_BUILD_PHASE_DESTINATIONS[:resources]
237
+
238
+ # @return [Hash{String => Hash}] A hash suitable to display the build
239
+ # phase to the user.
240
+ #
241
+ def pretty_print
242
+ {
243
+ display_name => {
244
+ 'Destination Path' => dst_path,
245
+ 'Destination Subfolder' => Constants::COPY_FILES_BUILD_PHASE_DESTINATIONS.key(dst_subfolder_spec).to_s,
246
+ 'Files' => files.map(&:pretty_print),
247
+ },
248
+ }
249
+ end
250
+
251
+ # Alias method for #dst_subfolder_spec=, which accepts symbol values
252
+ # instead of numeric string values.
253
+ #
254
+ # @param [Symbol] value
255
+ # one of `COPY_FILES_BUILD_PHASE_DESTINATIONS.keys`
256
+ #
257
+ # @raise [StandardError] if value is not a valid known key
258
+ #
259
+ def symbol_dst_subfolder_spec=(value)
260
+ numeric_value = Constants::COPY_FILES_BUILD_PHASE_DESTINATIONS[value]
261
+ raise "[Xcodeproj] Value checking error: got `#{value.inspect}` for" \
262
+ ' attribute: dst_subfolder_spec' if numeric_value.nil?
263
+ self.dst_subfolder_spec = numeric_value
264
+ end
265
+
266
+ # Alias method for #dst_subfolder_spec, which returns symbol values
267
+ # instead of numeric string values.
268
+ #
269
+ # @return [Symbol]
270
+ #
271
+ def symbol_dst_subfolder_spec
272
+ key = Constants::COPY_FILES_BUILD_PHASE_DESTINATIONS.find { |_, num| num == dst_subfolder_spec }
273
+ key ? key.first : nil
274
+ end
275
+ end
276
+
277
+ #-----------------------------------------------------------------------#
278
+
279
+ # A phase responsible of running a shell script (aka `Run Script`).
280
+ #
281
+ # @note This phase can appear multiple times in a target.
282
+ #
283
+ class PBXShellScriptBuildPhase < AbstractBuildPhase
284
+ # @!group Attributes
285
+
286
+ # @return [String] the name of the build phase.
287
+ #
288
+ attribute :name, String
289
+
290
+ # @return [Array<String>] an array of the paths to pass to the script.
291
+ #
292
+ # @example
293
+ # "$(SRCROOT)/myfile"
294
+ #
295
+ attribute :input_paths, Array, []
296
+
297
+ # @return [Array<String>] an array of input file list paths of the script.
298
+ #
299
+ # @example
300
+ # "$(SRCROOT)/newInputFile.xcfilelist"
301
+ #
302
+ attribute :input_file_list_paths, Array, []
303
+
304
+ # @return [Array<String>] an array of output paths of the script.
305
+ #
306
+ # @example
307
+ # "$(DERIVED_FILE_DIR)/myfile"
308
+ #
309
+ attribute :output_paths, Array, []
310
+
311
+ # @return [Array<String>] an array of output file list paths of the script.
312
+ #
313
+ # @example
314
+ # "$(SRCROOT)/newOutputFile.xcfilelist"
315
+ #
316
+ attribute :output_file_list_paths, Array, []
317
+
318
+ # @return [String] the path to the script interpreter.
319
+ #
320
+ # @note Defaults to `/bin/sh`.
321
+ #
322
+ attribute :shell_path, String, '/bin/sh'
323
+
324
+ # @return [String] the actual script to perform.
325
+ #
326
+ # @note Defaults to a comment string.
327
+ #
328
+ attribute :shell_script, String, "# Type a script or drag a script file from your workspace to insert its path.\n"
329
+
330
+ # @return [String] whether or not the ENV variables should be shown in
331
+ # the build log.
332
+ #
333
+ attribute :show_env_vars_in_log, String
334
+
335
+ # @return [String] the discovered dependency file to use.
336
+ #
337
+ attribute :dependency_file, String
338
+
339
+ # @return [Hash{String => Hash}] A hash suitable to display the build
340
+ # phase to the user.
341
+ #
342
+ def pretty_print
343
+ {
344
+ display_name => {
345
+ 'Input File List Paths' => input_file_list_paths || [],
346
+ 'Input Paths' => input_paths || [],
347
+ 'Output File List Paths' => output_file_list_paths || [],
348
+ 'Output Paths' => output_paths || [],
349
+ 'Shell Path' => shell_path,
350
+ 'Shell Script' => shell_script,
351
+ },
352
+ }
353
+ end
354
+ end
355
+
356
+ #-----------------------------------------------------------------------#
357
+
358
+ # Apparently a build phase named `Build Carbon Resources` (Observed for
359
+ # kernel extensions targets).
360
+ #
361
+ # @note This phase can appear multiple times in a target.
362
+ #
363
+ class PBXRezBuildPhase < AbstractBuildPhase
364
+ end
365
+
366
+ #-----------------------------------------------------------------------#
367
+ end
368
+ end
369
+ end