cocoapods-dykit 0.5.2 → 0.5.3
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 +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
|