cocoapods-dykit 0.5.2 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/pod/command.rb +2 -0
- data/lib/pod/command/dyinstall.rb +51 -0
- data/lib/pod/command/dyupdate.rb +106 -0
- data/lib/pod/command/fmwk.rb +4 -0
- data/lib/pod/command/lib/dylint.rb +1 -0
- data/lib/pod/gem_version.rb +1 -1
- data/lib/pod/installer.rb +715 -0
- data/lib/pod/installer/analyzer.rb +934 -0
- data/lib/pod/installer/analyzer/analysis_result.rb +57 -0
- data/lib/pod/installer/analyzer/locking_dependency_analyzer.rb +95 -0
- data/lib/pod/installer/analyzer/pod_variant.rb +68 -0
- data/lib/pod/installer/analyzer/pod_variant_set.rb +157 -0
- data/lib/pod/installer/analyzer/podfile_dependency_cache.rb +54 -0
- data/lib/pod/installer/analyzer/sandbox_analyzer.rb +251 -0
- data/lib/pod/installer/analyzer/specs_state.rb +84 -0
- data/lib/pod/installer/analyzer/target_inspection_result.rb +45 -0
- data/lib/pod/installer/analyzer/target_inspector.rb +254 -0
- data/lib/pod/installer/installation_options.rb +158 -0
- data/lib/pod/installer/pod_source_installer.rb +214 -0
- data/lib/pod/installer/pod_source_preparer.rb +77 -0
- data/lib/pod/installer/podfile_validator.rb +139 -0
- data/lib/pod/installer/post_install_hooks_context.rb +107 -0
- data/lib/pod/installer/pre_install_hooks_context.rb +42 -0
- data/lib/pod/installer/source_provider_hooks_context.rb +32 -0
- data/lib/pod/installer/user_project_integrator.rb +253 -0
- data/lib/pod/installer/user_project_integrator/target_integrator.rb +462 -0
- data/lib/pod/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +146 -0
- data/lib/pod/installer/xcode.rb +8 -0
- data/lib/pod/installer/xcode/pods_project_generator.rb +353 -0
- data/lib/pod/installer/xcode/pods_project_generator/aggregate_target_installer.rb +172 -0
- data/lib/pod/installer/xcode/pods_project_generator/file_references_installer.rb +367 -0
- data/lib/pod/installer/xcode/pods_project_generator/pod_target_installer.rb +718 -0
- data/lib/pod/installer/xcode/pods_project_generator/pod_target_integrator.rb +111 -0
- data/lib/pod/installer/xcode/pods_project_generator/target_installer.rb +265 -0
- data/lib/pod/installer/xcode/target_validator.rb +141 -0
- data/lib/pod/resolver.rb +632 -0
- metadata +34 -2
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'active_support/core_ext/string/strip'
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class DyInstaller
|
5
|
+
# Controller class responsible of installing the activated specifications
|
6
|
+
# of a single Pod.
|
7
|
+
#
|
8
|
+
# @note This class needs to consider all the activated specs of a Pod.
|
9
|
+
#
|
10
|
+
class PodSourceInstaller
|
11
|
+
# @return [Sandbox] The installation target.
|
12
|
+
#
|
13
|
+
attr_reader :sandbox
|
14
|
+
|
15
|
+
# @return [Hash{Symbol=>Array}] The specifications that need to be
|
16
|
+
# installed grouped by platform.
|
17
|
+
#
|
18
|
+
attr_reader :specs_by_platform
|
19
|
+
|
20
|
+
# @return [Boolean] Whether the installer is allowed to touch the cache.
|
21
|
+
#
|
22
|
+
attr_reader :can_cache
|
23
|
+
alias_method :can_cache?, :can_cache
|
24
|
+
|
25
|
+
# Initialize a new instance
|
26
|
+
#
|
27
|
+
# @param [Sandbox] sandbox @see sandbox
|
28
|
+
# @param [Hash{Symbol=>Array}] specs_by_platform @see specs_by_platform
|
29
|
+
# @param [Boolean] can_cache @see can_cache
|
30
|
+
#
|
31
|
+
def initialize(sandbox, specs_by_platform, can_cache: true)
|
32
|
+
@sandbox = sandbox
|
33
|
+
@specs_by_platform = specs_by_platform
|
34
|
+
@can_cache = can_cache
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [String] A string suitable for debugging.
|
38
|
+
#
|
39
|
+
def inspect
|
40
|
+
"<#{self.class} sandbox=#{sandbox.root} pod=#{root_spec.name}"
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [String] The name of the pod this installer is installing.
|
44
|
+
#
|
45
|
+
def name
|
46
|
+
root_spec.name
|
47
|
+
end
|
48
|
+
|
49
|
+
#-----------------------------------------------------------------------#
|
50
|
+
|
51
|
+
public
|
52
|
+
|
53
|
+
# @!group Installation
|
54
|
+
|
55
|
+
# Creates the target in the Pods project and the relative support files.
|
56
|
+
#
|
57
|
+
# @return [void]
|
58
|
+
#
|
59
|
+
def install!
|
60
|
+
download_source unless predownloaded? || local?
|
61
|
+
PodSourcePreparer.new(root_spec, root).prepare! if local?
|
62
|
+
end
|
63
|
+
|
64
|
+
# Cleans the installations if appropriate.
|
65
|
+
#
|
66
|
+
# @todo As the pre install hooks need to run before cleaning this
|
67
|
+
# method should be refactored.
|
68
|
+
#
|
69
|
+
# @return [void]
|
70
|
+
#
|
71
|
+
def clean!
|
72
|
+
clean_installation unless local?
|
73
|
+
end
|
74
|
+
|
75
|
+
# Locks the source files if appropriate.
|
76
|
+
#
|
77
|
+
# @todo As the pre install hooks need to run before cleaning this
|
78
|
+
# method should be refactored.
|
79
|
+
#
|
80
|
+
# @return [void]
|
81
|
+
#
|
82
|
+
def lock_files!(file_accessors)
|
83
|
+
return if local?
|
84
|
+
each_source_file(file_accessors) do |source_file|
|
85
|
+
FileUtils.chmod('u-w', source_file)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Unlocks the source files if appropriate.
|
90
|
+
#
|
91
|
+
# @todo As the pre install hooks need to run before cleaning this
|
92
|
+
# method should be refactored.
|
93
|
+
#
|
94
|
+
# @return [void]
|
95
|
+
#
|
96
|
+
def unlock_files!(file_accessors)
|
97
|
+
return if local?
|
98
|
+
each_source_file(file_accessors) do |source_file|
|
99
|
+
FileUtils.chmod('u+w', source_file)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# @return [Hash] @see Downloader#checkout_options
|
104
|
+
#
|
105
|
+
attr_reader :specific_source
|
106
|
+
|
107
|
+
#-----------------------------------------------------------------------#
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
# @!group Installation Steps
|
112
|
+
|
113
|
+
# Downloads the source of the Pod. It also stores the specific options
|
114
|
+
# needed to recreate the same exact installation if needed in
|
115
|
+
# `#specific_source`.
|
116
|
+
#
|
117
|
+
# @return [void]
|
118
|
+
#
|
119
|
+
def download_source
|
120
|
+
verify_source_is_secure(root_spec)
|
121
|
+
download_result = Downloader.download(download_request, root, :can_cache => can_cache?)
|
122
|
+
|
123
|
+
if (@specific_source = download_result.checkout_options) && specific_source != root_spec.source
|
124
|
+
sandbox.store_checkout_source(root_spec.name, specific_source)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Verify the source of the spec is secure, which is used to
|
129
|
+
# show a warning to the user if that isn't the case
|
130
|
+
# This method doesn't verify all protocols, but currently
|
131
|
+
# only prohibits unencrypted http:// connections
|
132
|
+
#
|
133
|
+
def verify_source_is_secure(root_spec)
|
134
|
+
return if root_spec.source.nil? || root_spec.source[:http].nil?
|
135
|
+
http_source = URI(root_spec.source[:http])
|
136
|
+
return if http_source.scheme == 'https' || http_source.scheme == 'file'
|
137
|
+
UI.warn "'#{root_spec.name}' uses the unencrypted http protocol to transfer the Pod. " \
|
138
|
+
'Please be sure you\'re in a safe network with only trusted hosts in there. ' \
|
139
|
+
'Please reach out to the library author to notify them of this security issue.'
|
140
|
+
end
|
141
|
+
|
142
|
+
def download_request
|
143
|
+
Downloader::Request.new(
|
144
|
+
:spec => root_spec,
|
145
|
+
:released => released?,
|
146
|
+
)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Removes all the files not needed for the installation according to the
|
150
|
+
# specs by platform.
|
151
|
+
#
|
152
|
+
# @return [void]
|
153
|
+
#
|
154
|
+
def clean_installation
|
155
|
+
cleaner = Sandbox::PodDirCleaner.new(root, specs_by_platform)
|
156
|
+
cleaner.clean!
|
157
|
+
end
|
158
|
+
|
159
|
+
#-----------------------------------------------------------------------#
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
# @!group Convenience methods.
|
164
|
+
|
165
|
+
# @return [Array<Specifications>] the specification of the Pod used in
|
166
|
+
# this installation.
|
167
|
+
#
|
168
|
+
def specs
|
169
|
+
specs_by_platform.values.flatten
|
170
|
+
end
|
171
|
+
|
172
|
+
# @return [Specification] the root specification of the Pod.
|
173
|
+
#
|
174
|
+
def root_spec
|
175
|
+
specs.first.root
|
176
|
+
end
|
177
|
+
|
178
|
+
# @return [Pathname] the folder where the source of the Pod is located.
|
179
|
+
#
|
180
|
+
def root
|
181
|
+
sandbox.pod_dir(root_spec.name)
|
182
|
+
end
|
183
|
+
|
184
|
+
# @return [Boolean] whether the source has been pre downloaded in the
|
185
|
+
# resolution process to retrieve its podspec.
|
186
|
+
#
|
187
|
+
def predownloaded?
|
188
|
+
sandbox.predownloaded_pods.include?(root_spec.name)
|
189
|
+
end
|
190
|
+
|
191
|
+
# @return [Boolean] whether the pod uses the local option and thus
|
192
|
+
# CocoaPods should not interfere with the files of the user.
|
193
|
+
#
|
194
|
+
def local?
|
195
|
+
sandbox.local?(root_spec.name)
|
196
|
+
end
|
197
|
+
|
198
|
+
def released?
|
199
|
+
!local? && !predownloaded? && sandbox.specification(root_spec.name) != root_spec
|
200
|
+
end
|
201
|
+
|
202
|
+
def each_source_file(file_accessors, &blk)
|
203
|
+
file_accessors.each do |file_accessor|
|
204
|
+
file_accessor.source_files.each do |source_file|
|
205
|
+
next unless source_file.exist?
|
206
|
+
blk[source_file]
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
#-----------------------------------------------------------------------#
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Pod
|
2
|
+
class DyInstaller
|
3
|
+
# Controller class responsible of executing the prepare command
|
4
|
+
# of a single Pod.
|
5
|
+
#
|
6
|
+
class PodSourcePreparer
|
7
|
+
# @return [Specification] the root specification of the Pod.
|
8
|
+
#
|
9
|
+
attr_reader :spec
|
10
|
+
|
11
|
+
# @return [Pathname] the folder where the source of the Pod is located.
|
12
|
+
#
|
13
|
+
attr_reader :path
|
14
|
+
|
15
|
+
# Initialize a new instance
|
16
|
+
#
|
17
|
+
# @param [Specification] spec the root specification of the Pod.
|
18
|
+
# @param [Pathname] path the folder where the source of the Pod is located.
|
19
|
+
#
|
20
|
+
def initialize(spec, path)
|
21
|
+
raise "Given spec isn't a root spec, but must be." unless spec.root?
|
22
|
+
@spec = spec
|
23
|
+
@path = path
|
24
|
+
end
|
25
|
+
|
26
|
+
#-----------------------------------------------------------------------#
|
27
|
+
|
28
|
+
public
|
29
|
+
|
30
|
+
# @!group Preparation
|
31
|
+
|
32
|
+
# Executes the prepare command if there is one.
|
33
|
+
#
|
34
|
+
# @return [void]
|
35
|
+
#
|
36
|
+
def prepare!
|
37
|
+
run_prepare_command
|
38
|
+
end
|
39
|
+
|
40
|
+
#-----------------------------------------------------------------------#
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# @!group Preparation Steps
|
45
|
+
|
46
|
+
extend Executable
|
47
|
+
executable :bash
|
48
|
+
|
49
|
+
# Runs the prepare command bash script of the spec.
|
50
|
+
#
|
51
|
+
# @note Unsets the `CDPATH` env variable before running the
|
52
|
+
# shell script to avoid issues with relative paths
|
53
|
+
# (issue #1694).
|
54
|
+
#
|
55
|
+
# @return [void]
|
56
|
+
#
|
57
|
+
def run_prepare_command
|
58
|
+
return unless spec.prepare_command
|
59
|
+
UI.section(' > Running prepare command', '', 1) do
|
60
|
+
Dir.chdir(path) do
|
61
|
+
begin
|
62
|
+
ENV.delete('CDPATH')
|
63
|
+
ENV['COCOAPODS_VERSION'] = Pod::VERSION
|
64
|
+
prepare_command = spec.prepare_command.strip_heredoc.chomp
|
65
|
+
full_command = "\nset -e\n" + prepare_command
|
66
|
+
bash!('-c', full_command)
|
67
|
+
ensure
|
68
|
+
ENV.delete('COCOAPODS_VERSION')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
#-----------------------------------------------------------------------#
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
module Pod
|
2
|
+
class DyInstaller
|
3
|
+
# Validate the podfile before installing to catch errors and
|
4
|
+
# problems
|
5
|
+
#
|
6
|
+
class PodfileValidator
|
7
|
+
# @return [Podfile] The podfile being validated
|
8
|
+
#
|
9
|
+
attr_reader :podfile
|
10
|
+
|
11
|
+
# @return [Array<String>] any errors that have occured during the validation
|
12
|
+
#
|
13
|
+
attr_reader :errors
|
14
|
+
|
15
|
+
# @return [Array<String>] any warnings that have occured during the validation
|
16
|
+
#
|
17
|
+
attr_reader :warnings
|
18
|
+
|
19
|
+
# Initialize a new instance
|
20
|
+
#
|
21
|
+
# @param [Podfile] podfile
|
22
|
+
# The podfile to validate
|
23
|
+
#
|
24
|
+
# @param [Analyzer::PodfileDependencyCache] podfile_dependency_cache
|
25
|
+
# An (optional) cache of all the dependencies in the podfile
|
26
|
+
#
|
27
|
+
def initialize(podfile, podfile_dependency_cache = Analyzer::PodfileDependencyCache.from_podfile(podfile))
|
28
|
+
@podfile = podfile
|
29
|
+
@podfile_dependency_cache = podfile_dependency_cache
|
30
|
+
@errors = []
|
31
|
+
@warnings = []
|
32
|
+
@validated = false
|
33
|
+
end
|
34
|
+
|
35
|
+
# Validate the podfile
|
36
|
+
# Errors are added to the errors array
|
37
|
+
#
|
38
|
+
def validate
|
39
|
+
validate_pod_directives
|
40
|
+
validate_no_abstract_only_pods!
|
41
|
+
validate_dependencies_are_present!
|
42
|
+
validate_no_duplicate_targets!
|
43
|
+
|
44
|
+
@validated = true
|
45
|
+
end
|
46
|
+
|
47
|
+
# Wether the podfile is valid is not
|
48
|
+
# NOTE: Will execute `validate` if the podfile
|
49
|
+
# has not yet been validated
|
50
|
+
#
|
51
|
+
def valid?
|
52
|
+
validate unless @validated
|
53
|
+
|
54
|
+
@validated && errors.empty?
|
55
|
+
end
|
56
|
+
|
57
|
+
# A message describing any errors in the
|
58
|
+
# validation
|
59
|
+
#
|
60
|
+
def message
|
61
|
+
errors.join("\n")
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def add_error(error)
|
67
|
+
errors << error
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_warning(warning)
|
71
|
+
warnings << warning
|
72
|
+
end
|
73
|
+
|
74
|
+
def validate_pod_directives
|
75
|
+
@podfile_dependency_cache.podfile_dependencies.each do |dependency|
|
76
|
+
validate_conflicting_external_sources!(dependency)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def validate_conflicting_external_sources!(dependency)
|
81
|
+
external_source = dependency.external_source
|
82
|
+
return false if external_source.nil?
|
83
|
+
|
84
|
+
available_downloaders = Downloader.downloader_class_by_key.keys
|
85
|
+
specified_downloaders = external_source.select { |key| available_downloaders.include?(key) }
|
86
|
+
if specified_downloaders.size > 1
|
87
|
+
add_error "The dependency `#{dependency.name}` specifies more than one download strategy(#{specified_downloaders.keys.join(',')})." \
|
88
|
+
'Only one is allowed'
|
89
|
+
end
|
90
|
+
|
91
|
+
pod_spec_or_path = external_source[:podspec].present? || external_source[:path].present?
|
92
|
+
if pod_spec_or_path && specified_downloaders.size > 0
|
93
|
+
add_error "The dependency `#{dependency.name}` specifies `podspec` or `path` in combination with other" \
|
94
|
+
' download strategies. This is not allowed'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Warns the user if the podfile is empty.
|
99
|
+
#
|
100
|
+
# @note The workspace is created in any case and all the user projects
|
101
|
+
# are added to it, however the projects are not integrated as
|
102
|
+
# there is no way to discern between target definitions which are
|
103
|
+
# empty and target definitions which just serve the purpose to
|
104
|
+
# wrap other ones. This is not an issue because empty target
|
105
|
+
# definitions generate empty libraries.
|
106
|
+
#
|
107
|
+
# @return [void]
|
108
|
+
#
|
109
|
+
def validate_dependencies_are_present!
|
110
|
+
if @podfile_dependency_cache.target_definition_list.all?(&:empty?)
|
111
|
+
add_warning 'The Podfile does not contain any dependencies.'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Verifies that no dependencies in the Podfile will end up not being built
|
116
|
+
# at all. In other words, all dependencies _must_ belong to a non-abstract
|
117
|
+
# target, or be inherited by a target where `inheritance == complete`.
|
118
|
+
#
|
119
|
+
def validate_no_abstract_only_pods!
|
120
|
+
all_dependencies = @podfile_dependency_cache.podfile_dependencies
|
121
|
+
concrete_dependencies = @podfile_dependency_cache.target_definition_list.reject(&:abstract?).flat_map { |td| @podfile_dependency_cache.target_definition_dependencies(td) }
|
122
|
+
abstract_only_dependencies = all_dependencies - concrete_dependencies
|
123
|
+
abstract_only_dependencies.each do |dep|
|
124
|
+
add_error "The dependency `#{dep}` is not used in any concrete target."
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def validate_no_duplicate_targets!
|
129
|
+
@podfile_dependency_cache.target_definition_list.group_by { |td| [td.name, td.user_project_path] }.
|
130
|
+
each do |(name, project), definitions|
|
131
|
+
next unless definitions.size > 1
|
132
|
+
error = "The target `#{name}` is declared twice"
|
133
|
+
error << " for the project `#{project}`" if project
|
134
|
+
add_error(error << '.')
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Pod
|
2
|
+
class DyInstaller
|
3
|
+
# Context object designed to be used with the HooksManager which describes
|
4
|
+
# the context of the installer.
|
5
|
+
#
|
6
|
+
class PostInstallHooksContext
|
7
|
+
# @return [String] The path to the sandbox root (`Pods` directory).
|
8
|
+
#
|
9
|
+
attr_accessor :sandbox_root
|
10
|
+
|
11
|
+
# @return [Project] The Pods Xcode project.
|
12
|
+
#
|
13
|
+
attr_accessor :pods_project
|
14
|
+
|
15
|
+
# @return [Sandbox] The Sandbox for the project.
|
16
|
+
#
|
17
|
+
attr_accessor :sandbox
|
18
|
+
|
19
|
+
# @return [Array<UmbrellaTargetDescription>] The list of
|
20
|
+
# the CocoaPods umbrella targets generated by the installer.
|
21
|
+
#
|
22
|
+
attr_accessor :umbrella_targets
|
23
|
+
|
24
|
+
# @return [PostInstallHooksContext] Convenience class generator method
|
25
|
+
#
|
26
|
+
# @param [Sandbox] sandbox
|
27
|
+
# The sandbox
|
28
|
+
#
|
29
|
+
# @param [Array<AggregateTarget>] aggregate_targets
|
30
|
+
# The aggregate targets, which will been presented by an adequate
|
31
|
+
# {UmbrellaTargetDescription} in the generated context.
|
32
|
+
#
|
33
|
+
# @return [HooksContext] Convenience class method to generate the
|
34
|
+
# static context.
|
35
|
+
#
|
36
|
+
def self.generate(sandbox, aggregate_targets)
|
37
|
+
umbrella_targets_descriptions = []
|
38
|
+
aggregate_targets.each do |umbrella|
|
39
|
+
desc = UmbrellaTargetDescription.new
|
40
|
+
desc.user_project = umbrella.user_project
|
41
|
+
desc.user_targets = umbrella.user_targets
|
42
|
+
desc.specs = umbrella.specs
|
43
|
+
desc.platform_name = umbrella.platform.name
|
44
|
+
desc.platform_deployment_target = umbrella.platform.deployment_target.to_s
|
45
|
+
desc.cocoapods_target_label = umbrella.label
|
46
|
+
umbrella_targets_descriptions << desc
|
47
|
+
end
|
48
|
+
|
49
|
+
result = new
|
50
|
+
result.sandbox_root = sandbox.root.to_s
|
51
|
+
result.pods_project = sandbox.project
|
52
|
+
result.sandbox = sandbox
|
53
|
+
result.umbrella_targets = umbrella_targets_descriptions
|
54
|
+
result
|
55
|
+
end
|
56
|
+
|
57
|
+
# Pure data class which describes and umbrella target.
|
58
|
+
#
|
59
|
+
class UmbrellaTargetDescription
|
60
|
+
# @return [Xcodeproj::Project] The user project into which this target
|
61
|
+
# is integrated.
|
62
|
+
#
|
63
|
+
attr_accessor :user_project
|
64
|
+
|
65
|
+
# @return [String] The path of the user project
|
66
|
+
# integrated by this target.
|
67
|
+
#
|
68
|
+
def user_project_path
|
69
|
+
user_project.path if user_project
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [Array<PBXNativeTarget>]
|
73
|
+
# The list of user targets integrated by this umbrella target.
|
74
|
+
#
|
75
|
+
attr_accessor :user_targets
|
76
|
+
|
77
|
+
# @return [Array<String>] The list of the UUIDs of the
|
78
|
+
# user targets integrated by this umbrella
|
79
|
+
# target. They can be used to find the
|
80
|
+
# targets opening the project They can be used
|
81
|
+
# to find the targets opening the project with
|
82
|
+
# Xcodeproj.
|
83
|
+
#
|
84
|
+
def user_target_uuids
|
85
|
+
user_targets.map(&:uuid)
|
86
|
+
end
|
87
|
+
|
88
|
+
# @return [Array<Specification>] The list of the
|
89
|
+
# specifications of the target.
|
90
|
+
#
|
91
|
+
attr_accessor :specs
|
92
|
+
|
93
|
+
# @return [Symbol] The platform (either `:ios`, `:watchos`, `:tvos`, or `:osx`).
|
94
|
+
#
|
95
|
+
attr_accessor :platform_name
|
96
|
+
|
97
|
+
# @return [String] The deployment target.
|
98
|
+
#
|
99
|
+
attr_accessor :platform_deployment_target
|
100
|
+
|
101
|
+
# @return [String] The label for the target.
|
102
|
+
#
|
103
|
+
attr_accessor :cocoapods_target_label
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|