cocoapods-square-stable 0.19.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 +7 -0
- data/CHANGELOG.md +1296 -0
- data/LICENSE +20 -0
- data/README.md +94 -0
- data/bin/pod +16 -0
- data/bin/sandbox-pod +120 -0
- data/lib/cocoapods.rb +77 -0
- data/lib/cocoapods/command.rb +116 -0
- data/lib/cocoapods/command/help.rb +23 -0
- data/lib/cocoapods/command/inter_process_communication.rb +178 -0
- data/lib/cocoapods/command/list.rb +77 -0
- data/lib/cocoapods/command/outdated.rb +56 -0
- data/lib/cocoapods/command/podfile_info.rb +91 -0
- data/lib/cocoapods/command/project.rb +88 -0
- data/lib/cocoapods/command/push.rb +172 -0
- data/lib/cocoapods/command/repo.rb +145 -0
- data/lib/cocoapods/command/search.rb +61 -0
- data/lib/cocoapods/command/setup.rb +134 -0
- data/lib/cocoapods/command/spec.rb +590 -0
- data/lib/cocoapods/config.rb +231 -0
- data/lib/cocoapods/downloader.rb +59 -0
- data/lib/cocoapods/executable.rb +118 -0
- data/lib/cocoapods/external_sources.rb +363 -0
- data/lib/cocoapods/file_list.rb +36 -0
- data/lib/cocoapods/gem_version.rb +7 -0
- data/lib/cocoapods/generator/acknowledgements.rb +107 -0
- data/lib/cocoapods/generator/acknowledgements/markdown.rb +40 -0
- data/lib/cocoapods/generator/acknowledgements/plist.rb +64 -0
- data/lib/cocoapods/generator/bridge_support.rb +22 -0
- data/lib/cocoapods/generator/copy_resources_script.rb +54 -0
- data/lib/cocoapods/generator/dummy_source.rb +22 -0
- data/lib/cocoapods/generator/prefix_header.rb +82 -0
- data/lib/cocoapods/generator/target_environment_header.rb +86 -0
- data/lib/cocoapods/generator/xcconfig.rb +185 -0
- data/lib/cocoapods/hooks/installer_representation.rb +134 -0
- data/lib/cocoapods/hooks/library_representation.rb +94 -0
- data/lib/cocoapods/hooks/pod_representation.rb +74 -0
- data/lib/cocoapods/installer.rb +571 -0
- data/lib/cocoapods/installer/analyzer.rb +559 -0
- data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +253 -0
- data/lib/cocoapods/installer/file_references_installer.rb +179 -0
- data/lib/cocoapods/installer/pod_source_installer.rb +248 -0
- data/lib/cocoapods/installer/target_installer.rb +379 -0
- data/lib/cocoapods/installer/user_project_integrator.rb +180 -0
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +224 -0
- data/lib/cocoapods/library.rb +202 -0
- data/lib/cocoapods/open_uri.rb +24 -0
- data/lib/cocoapods/project.rb +209 -0
- data/lib/cocoapods/resolver.rb +212 -0
- data/lib/cocoapods/sandbox.rb +343 -0
- data/lib/cocoapods/sandbox/file_accessor.rb +217 -0
- data/lib/cocoapods/sandbox/headers_store.rb +96 -0
- data/lib/cocoapods/sandbox/path_list.rb +208 -0
- data/lib/cocoapods/sources_manager.rb +276 -0
- data/lib/cocoapods/user_interface.rb +304 -0
- data/lib/cocoapods/user_interface/error_report.rb +101 -0
- data/lib/cocoapods/validator.rb +350 -0
- metadata +238 -0
@@ -0,0 +1,253 @@
|
|
1
|
+
module Pod
|
2
|
+
class Installer
|
3
|
+
class Analyzer
|
4
|
+
|
5
|
+
# Analyze the sandbox to detect which Pods should be removed, and which
|
6
|
+
# ones should be reinstalled.
|
7
|
+
#
|
8
|
+
# The logic is the following:
|
9
|
+
#
|
10
|
+
# Added
|
11
|
+
# - If not present in the sandbox lockfile.
|
12
|
+
# - The directory of the Pod doesn't exits.
|
13
|
+
#
|
14
|
+
# Changed
|
15
|
+
# - The version of the Pod changed.
|
16
|
+
# - The SHA of the specification file changed.
|
17
|
+
# - The specific installed (sub)specs of the same Pod changed.
|
18
|
+
# - The specification is in head mode or from an external source and the
|
19
|
+
# installation process is in update mode.
|
20
|
+
# - The directory of the Pod is empty.
|
21
|
+
# - The Pod has been pre-downloaded.
|
22
|
+
#
|
23
|
+
# Removed
|
24
|
+
# - If a specification is present in the lockfile but not in the resolved
|
25
|
+
# specs.
|
26
|
+
#
|
27
|
+
# Unchanged
|
28
|
+
# - If none of the above conditions match.
|
29
|
+
#
|
30
|
+
class SandboxAnalyzer
|
31
|
+
|
32
|
+
# @return [Sandbox] The sandbox to analyze.
|
33
|
+
#
|
34
|
+
attr_reader :sandbox
|
35
|
+
|
36
|
+
# @return [Array<Specifications>] The specifications returned by the
|
37
|
+
# resolver.
|
38
|
+
#
|
39
|
+
attr_reader :specs
|
40
|
+
|
41
|
+
# @return [Bool] Whether the installation is performed in update mode.
|
42
|
+
#
|
43
|
+
attr_reader :update_mode
|
44
|
+
|
45
|
+
# @return [Lockfile] The lockfile of the installation as a fall-back if
|
46
|
+
# there is no sandbox manifest. This is indented as a temporary
|
47
|
+
# solution to prevent the full re-installation from users which
|
48
|
+
# are upgrading from CP < 0.17.
|
49
|
+
#
|
50
|
+
# @todo Remove for CP 0.18.
|
51
|
+
#
|
52
|
+
attr_reader :lockfile
|
53
|
+
|
54
|
+
# @param [Sandbox] sandbox @see sandbox
|
55
|
+
# @param [Array<Specifications>] specs @see specs
|
56
|
+
# @param [Bool] update_mode @see update_mode
|
57
|
+
# @param [Lockfile] lockfile @see lockfile
|
58
|
+
#
|
59
|
+
def initialize(sandbox, specs, update_mode, lockfile = nil)
|
60
|
+
@sandbox = sandbox
|
61
|
+
@specs = specs
|
62
|
+
@update_mode = update_mode
|
63
|
+
@lockfile = lockfile
|
64
|
+
end
|
65
|
+
|
66
|
+
# Performs the analysis to the detect the state of the sandbox respect
|
67
|
+
# to the resolved specifications.
|
68
|
+
#
|
69
|
+
# @return [SpecsState] the state of the sandbox.
|
70
|
+
#
|
71
|
+
def analyze
|
72
|
+
state = SpecsState.new
|
73
|
+
if sandbox_manifest
|
74
|
+
all_names = (resolved_pods + sandbox_pods).uniq.sort
|
75
|
+
all_names.sort.each do |name|
|
76
|
+
state.add_name(name, pod_state(name))
|
77
|
+
end
|
78
|
+
else
|
79
|
+
state.added.concat(resolved_pods)
|
80
|
+
end
|
81
|
+
state
|
82
|
+
end
|
83
|
+
|
84
|
+
#---------------------------------------------------------------------#
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
# @!group Pod state
|
89
|
+
|
90
|
+
# Returns the state of the Pod with the given name.
|
91
|
+
#
|
92
|
+
# @param [String] pod
|
93
|
+
# the name of the Pod.
|
94
|
+
#
|
95
|
+
# @return [Symbol] The state
|
96
|
+
#
|
97
|
+
def pod_state(pod)
|
98
|
+
return :added if pod_added?(pod)
|
99
|
+
return :deleted if pod_deleted?(pod)
|
100
|
+
return :changed if pod_changed?(pod)
|
101
|
+
return :unchanged
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns whether the Pod with the given name should be installed.
|
105
|
+
#
|
106
|
+
# @note A Pod whose folder doesn't exists is considered added.
|
107
|
+
#
|
108
|
+
# @param [String] pod
|
109
|
+
# the name of the Pod.
|
110
|
+
#
|
111
|
+
# @return [Bool] Whether the Pod is added.
|
112
|
+
#
|
113
|
+
def pod_added?(pod)
|
114
|
+
return true if resolved_pods.include?(pod) && !sandbox_pods.include?(pod)
|
115
|
+
return true if !folder_exist?(pod)
|
116
|
+
return false
|
117
|
+
end
|
118
|
+
|
119
|
+
# Returns whether the Pod with the given name should be removed from
|
120
|
+
# the installation.
|
121
|
+
#
|
122
|
+
# @param [String] pod
|
123
|
+
# the name of the Pod.
|
124
|
+
#
|
125
|
+
# @return [Bool] Whether the Pod is deleted.
|
126
|
+
#
|
127
|
+
def pod_deleted?(pod)
|
128
|
+
return true if !resolved_pods.include?(pod) && sandbox_pods.include?(pod)
|
129
|
+
return false
|
130
|
+
end
|
131
|
+
|
132
|
+
# Returns whether the Pod with the given name should be considered
|
133
|
+
# changed and thus should be reinstalled.
|
134
|
+
#
|
135
|
+
# @note In update mode, as there is no way to know if a remote source
|
136
|
+
# hash changed the Pods in head mode and the ones from external
|
137
|
+
# sources are always marked as changed.
|
138
|
+
#
|
139
|
+
# @note A Pod whose folder is empty is considered changed.
|
140
|
+
#
|
141
|
+
# @param [String] pod
|
142
|
+
# the name of the Pod.
|
143
|
+
#
|
144
|
+
# @return [Bool] Whether the Pod is changed.
|
145
|
+
#
|
146
|
+
def pod_changed?(pod)
|
147
|
+
spec = root_spec(pod)
|
148
|
+
return true if spec.version != sandbox_version(pod)
|
149
|
+
return true if spec.checksum != sandbox_checksum(pod)
|
150
|
+
return true if resolved_spec_names(pod) != sandbox_spec_names(pod)
|
151
|
+
return true if sandbox.predownloaded?(pod)
|
152
|
+
return true if folder_empty?(pod)
|
153
|
+
if update_mode
|
154
|
+
return true if spec.version.head?
|
155
|
+
end
|
156
|
+
return false
|
157
|
+
end
|
158
|
+
|
159
|
+
#---------------------------------------------------------------------#
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
# @!group Private helpers
|
164
|
+
|
165
|
+
# @return [Lockfile] The manifest to use for the sandbox.
|
166
|
+
#
|
167
|
+
def sandbox_manifest
|
168
|
+
sandbox.manifest || lockfile
|
169
|
+
end
|
170
|
+
|
171
|
+
#--------------------------------------#
|
172
|
+
|
173
|
+
# @return [Array<String>] The name of the resolved Pods.
|
174
|
+
#
|
175
|
+
def resolved_pods
|
176
|
+
specs.map { |spec| spec.root.name }.uniq
|
177
|
+
end
|
178
|
+
|
179
|
+
# @return [Array<String>] The name of the Pods stored in the sandbox
|
180
|
+
# manifest.
|
181
|
+
#
|
182
|
+
def sandbox_pods
|
183
|
+
sandbox_manifest.pod_names.map { |name| Specification.root_name(name) }.uniq
|
184
|
+
end
|
185
|
+
|
186
|
+
# @return [Array<String>] The name of the resolved specifications
|
187
|
+
# (includes subspecs).
|
188
|
+
#
|
189
|
+
# @param [String] pod
|
190
|
+
# the name of the Pod.
|
191
|
+
#
|
192
|
+
def resolved_spec_names(pod)
|
193
|
+
specs.select { |s| s.root.name == pod }.map(&:name).uniq.sort
|
194
|
+
end
|
195
|
+
|
196
|
+
# @return [Array<String>] The name of the specifications stored in the
|
197
|
+
# sandbox manifest (includes subspecs).
|
198
|
+
#
|
199
|
+
# @param [String] pod
|
200
|
+
# the name of the Pod.
|
201
|
+
#
|
202
|
+
def sandbox_spec_names(pod)
|
203
|
+
sandbox_manifest.pod_names.select { |name| Specification.root_name(name) == pod }.uniq.sort
|
204
|
+
end
|
205
|
+
|
206
|
+
# @return [Specification] The root specification for the Pod with the
|
207
|
+
# given name.
|
208
|
+
#
|
209
|
+
# @param [String] pod
|
210
|
+
# the name of the Pod.
|
211
|
+
#
|
212
|
+
def root_spec(pod)
|
213
|
+
specs.find { |s| s.root.name == pod }.root
|
214
|
+
end
|
215
|
+
|
216
|
+
#--------------------------------------#
|
217
|
+
|
218
|
+
# @return [Version] The version of Pod with the given name stored in
|
219
|
+
# the sandbox.
|
220
|
+
#
|
221
|
+
# @param [String] pod
|
222
|
+
# the name of the Pod.
|
223
|
+
#
|
224
|
+
def sandbox_version(pod)
|
225
|
+
sandbox_manifest.version(pod)
|
226
|
+
end
|
227
|
+
|
228
|
+
# @return [String] The checksum of the specification of the Pod with
|
229
|
+
# the given name stored in the sandbox.
|
230
|
+
#
|
231
|
+
# @param [String] pod
|
232
|
+
# the name of the Pod.
|
233
|
+
#
|
234
|
+
def sandbox_checksum(pod)
|
235
|
+
sandbox_manifest.checksum(pod)
|
236
|
+
end
|
237
|
+
|
238
|
+
#--------------------------------------#
|
239
|
+
|
240
|
+
def folder_exist?(pod)
|
241
|
+
sandbox.pod_dir(pod).exist?
|
242
|
+
end
|
243
|
+
|
244
|
+
def folder_empty?(pod)
|
245
|
+
Dir.glob(sandbox.pod_dir(pod) + '*').empty?
|
246
|
+
end
|
247
|
+
|
248
|
+
#---------------------------------------------------------------------#
|
249
|
+
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
module Pod
|
2
|
+
class Installer
|
3
|
+
|
4
|
+
# Controller class responsible of installing the file references of the
|
5
|
+
# specifications in the Pods project.
|
6
|
+
#
|
7
|
+
class FileReferencesInstaller
|
8
|
+
|
9
|
+
# @return [Sandbox] The sandbox of the installation.
|
10
|
+
#
|
11
|
+
attr_reader :sandbox
|
12
|
+
|
13
|
+
# @return [Array<Library>] The libraries of the installation.
|
14
|
+
#
|
15
|
+
attr_reader :libraries
|
16
|
+
|
17
|
+
# @return [Project] The Pods project.
|
18
|
+
#
|
19
|
+
attr_reader :pods_project
|
20
|
+
|
21
|
+
# @param [Sandbox] sandbox @see sandbox
|
22
|
+
# @param [Array<Library>] libraries @see libraries
|
23
|
+
# @param [Project] libraries @see libraries
|
24
|
+
#
|
25
|
+
def initialize(sandbox, libraries, pods_project)
|
26
|
+
@sandbox = sandbox
|
27
|
+
@libraries = libraries
|
28
|
+
@pods_project = pods_project
|
29
|
+
end
|
30
|
+
|
31
|
+
# Installs the file references.
|
32
|
+
#
|
33
|
+
# @return [void]
|
34
|
+
#
|
35
|
+
def install!
|
36
|
+
refresh_file_accessors
|
37
|
+
add_source_files_references
|
38
|
+
add_resources_references
|
39
|
+
link_headers
|
40
|
+
end
|
41
|
+
|
42
|
+
#-----------------------------------------------------------------------#
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# @!group Installation Steps
|
47
|
+
|
48
|
+
# Reads the file accessors contents from the file system.
|
49
|
+
#
|
50
|
+
# @note The contents of the file accessors are modified by the clean
|
51
|
+
# step of the #{PodSourceInstaller} and by the pre install hooks.
|
52
|
+
#
|
53
|
+
# @return [void]
|
54
|
+
#
|
55
|
+
def refresh_file_accessors
|
56
|
+
file_accessors.each do |fa|
|
57
|
+
fa.path_list.read_file_system
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Adds the source files of the Pods to the Pods project.
|
62
|
+
#
|
63
|
+
# @note The source files are grouped by Pod and in turn by subspec
|
64
|
+
# (recursively).
|
65
|
+
#
|
66
|
+
# @note Pods are generally added to the `Pods` group, however, if they
|
67
|
+
# have a local source they are added to the
|
68
|
+
# `Local Pods` group.
|
69
|
+
#
|
70
|
+
# @return [void]
|
71
|
+
#
|
72
|
+
def add_source_files_references
|
73
|
+
UI.message "- Adding source files to Pods project" do
|
74
|
+
file_accessors.each do |file_accessor|
|
75
|
+
files = file_accessor.source_files
|
76
|
+
spec_name = file_accessor.spec.name
|
77
|
+
local = sandbox.local?(file_accessor.spec.root.name)
|
78
|
+
parent_group = local ? pods_project.local_pods : pods_project.pods
|
79
|
+
pods_project.add_file_references(files, spec_name, parent_group)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Adds the resources of the Pods to the Pods project.
|
85
|
+
#
|
86
|
+
# @note The source files are grouped by Pod and in turn by subspec
|
87
|
+
# (recursively) in the resources group.
|
88
|
+
#
|
89
|
+
# @return [void]
|
90
|
+
#
|
91
|
+
def add_resources_references
|
92
|
+
UI.message "- Adding resources to Pods project" do
|
93
|
+
file_accessors.each do |file_accessor|
|
94
|
+
file_accessor.resources.each do |resources|
|
95
|
+
files = file_accessor.resources
|
96
|
+
spec_name = file_accessor.spec.name
|
97
|
+
parent_group = pods_project.resources
|
98
|
+
pods_project.add_file_references(files, spec_name, parent_group)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Creates the link to the headers of the Pod in the sandbox.
|
105
|
+
#
|
106
|
+
# @return [void]
|
107
|
+
#
|
108
|
+
def link_headers
|
109
|
+
UI.message "- Linking headers" do
|
110
|
+
|
111
|
+
file_accessors.each do |file_accessor|
|
112
|
+
headers_sandbox = Pathname.new(file_accessor.spec.root.name)
|
113
|
+
sandbox.build_headers.add_search_path(headers_sandbox)
|
114
|
+
sandbox.public_headers.add_search_path(headers_sandbox)
|
115
|
+
|
116
|
+
header_mappings(headers_sandbox, file_accessor, file_accessor.headers).each do |namespaced_path, files|
|
117
|
+
sandbox.build_headers.add_files(namespaced_path, files)
|
118
|
+
end
|
119
|
+
|
120
|
+
header_mappings(headers_sandbox, file_accessor, file_accessor.public_headers).each do |namespaced_path, files|
|
121
|
+
sandbox.public_headers.add_files(namespaced_path, files)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
#-----------------------------------------------------------------------#
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
# @!group Private Helpers
|
132
|
+
|
133
|
+
# @return [Array<Sandbox::FileAccessor>] The file accessors for all the
|
134
|
+
# specs platform combinations.
|
135
|
+
#
|
136
|
+
def file_accessors
|
137
|
+
@file_accessors ||= libraries.map(&:file_accessors).flatten.compact
|
138
|
+
end
|
139
|
+
|
140
|
+
# Computes the destination sub-directory in the sandbox
|
141
|
+
#
|
142
|
+
# @param [Pathname] headers_sandbox
|
143
|
+
# The sandbox where the headers links should be stored for this
|
144
|
+
# Pod.
|
145
|
+
#
|
146
|
+
# @param [Specification::Consumer] consumer
|
147
|
+
# The consumer for which the headers need to be linked.
|
148
|
+
#
|
149
|
+
# @param [Array<Pathname>] headers
|
150
|
+
# The absolute paths of the headers which need to be mapped.
|
151
|
+
#
|
152
|
+
# @return [Hash{Pathname => Array<Pathname>}] A hash containing the
|
153
|
+
# headers folders as the keys and the absolute paths of the
|
154
|
+
# header files as the values.
|
155
|
+
#
|
156
|
+
def header_mappings(headers_sandbox, file_accessor, headers)
|
157
|
+
consumer = file_accessor.spec_consumer
|
158
|
+
dir = headers_sandbox
|
159
|
+
dir = dir + consumer.header_dir if consumer.header_dir
|
160
|
+
|
161
|
+
mappings = {}
|
162
|
+
headers.each do |header|
|
163
|
+
sub_dir = dir
|
164
|
+
if consumer.header_mappings_dir
|
165
|
+
header_mappings_dir = file_accessor.path_list.root + consumer.header_mappings_dir
|
166
|
+
relative_path = header.relative_path_from(header_mappings_dir)
|
167
|
+
sub_dir = sub_dir + relative_path.dirname
|
168
|
+
end
|
169
|
+
mappings[sub_dir] ||= []
|
170
|
+
mappings[sub_dir] << header
|
171
|
+
end
|
172
|
+
mappings
|
173
|
+
end
|
174
|
+
|
175
|
+
#-----------------------------------------------------------------------#
|
176
|
+
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,248 @@
|
|
1
|
+
module Pod
|
2
|
+
class Installer
|
3
|
+
|
4
|
+
# Controller class responsible of installing the activated specifications
|
5
|
+
# of a single Pod.
|
6
|
+
#
|
7
|
+
# @note This class needs to consider all the activated specs of a Pod.
|
8
|
+
#
|
9
|
+
class PodSourceInstaller
|
10
|
+
|
11
|
+
# @return [Sandbox]
|
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
|
+
# @param [Sandbox] sandbox @see sandbox
|
21
|
+
# @param [Hash{Symbol=>Array}] specs_by_platform @see specs_by_platform
|
22
|
+
#
|
23
|
+
def initialize(sandbox, specs_by_platform)
|
24
|
+
@sandbox = sandbox
|
25
|
+
@specs_by_platform = specs_by_platform
|
26
|
+
|
27
|
+
@aggressive_cache = false
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String] A string suitable for debugging.
|
31
|
+
#
|
32
|
+
def inspect
|
33
|
+
"<#{self.class} sandbox=#{sandbox.root} pod=#{root_spec.name}"
|
34
|
+
end
|
35
|
+
|
36
|
+
#-----------------------------------------------------------------------#
|
37
|
+
|
38
|
+
public
|
39
|
+
|
40
|
+
# @!group Configuration
|
41
|
+
|
42
|
+
# @return [Bool] whether the downloader should always check against the
|
43
|
+
# remote if issues might be generated (mostly useful to speed up
|
44
|
+
# testing).
|
45
|
+
#
|
46
|
+
# @note This might be removed in future.
|
47
|
+
#
|
48
|
+
attr_accessor :aggressive_cache
|
49
|
+
alias_method :aggressive_cache?, :aggressive_cache
|
50
|
+
|
51
|
+
#-----------------------------------------------------------------------#
|
52
|
+
|
53
|
+
public
|
54
|
+
|
55
|
+
# @!group Installation
|
56
|
+
|
57
|
+
# Creates the target in the Pods project and the relative support files.
|
58
|
+
#
|
59
|
+
# @return [void]
|
60
|
+
#
|
61
|
+
def install!
|
62
|
+
download_source unless predownloaded? || local?
|
63
|
+
end
|
64
|
+
|
65
|
+
# Cleans the installations if appropriate.
|
66
|
+
#
|
67
|
+
# @todo As the pre install hooks need to run before cleaning this
|
68
|
+
# method should be refactored.
|
69
|
+
#
|
70
|
+
# @return [void]
|
71
|
+
#
|
72
|
+
def clean!
|
73
|
+
clean_installation if !local?
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return [Hash]
|
77
|
+
#
|
78
|
+
attr_reader :specific_source
|
79
|
+
|
80
|
+
#-----------------------------------------------------------------------#
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
# @!group Installation Steps
|
85
|
+
|
86
|
+
# Downloads the source of the Pod. It also stores the specific options
|
87
|
+
# needed to recreate the same exact installation if needed in
|
88
|
+
# `#specific_source`.
|
89
|
+
#
|
90
|
+
# @return [void]
|
91
|
+
#
|
92
|
+
def download_source
|
93
|
+
root.rmtree if root.exist?
|
94
|
+
if root_spec.version.head?
|
95
|
+
downloader.download_head
|
96
|
+
@specific_source = downloader.checkout_options
|
97
|
+
else
|
98
|
+
downloader.download
|
99
|
+
unless downloader.options_specific?
|
100
|
+
@specific_source = downloader.checkout_options
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
if specific_source
|
105
|
+
sandbox.store_checkout_source(root_spec.name, specific_source)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Removes all the files not needed for the installation according to the
|
110
|
+
# specs by platform.
|
111
|
+
#
|
112
|
+
# @return [void]
|
113
|
+
#
|
114
|
+
def clean_installation
|
115
|
+
clean_paths.each { |path| FileUtils.rm_rf(path) }
|
116
|
+
end
|
117
|
+
|
118
|
+
#-----------------------------------------------------------------------#
|
119
|
+
|
120
|
+
public
|
121
|
+
|
122
|
+
# @!group Dependencies
|
123
|
+
|
124
|
+
# @return [Downloader] The downloader to use for the retrieving the
|
125
|
+
# source.
|
126
|
+
#
|
127
|
+
def downloader
|
128
|
+
return @downloader if @downloader
|
129
|
+
@downloader = Downloader.for_target(root, root_spec.source.dup)
|
130
|
+
@downloader.cache_root = CACHE_ROOT.to_s
|
131
|
+
@downloader.max_cache_size = MAX_CACHE_SIZE
|
132
|
+
@downloader.aggressive_cache = aggressive_cache?
|
133
|
+
@downloader
|
134
|
+
end
|
135
|
+
|
136
|
+
#-----------------------------------------------------------------------#
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
# @!group Convenience methods.
|
141
|
+
|
142
|
+
# @return [Array<Specifications>] the specification of the Pod used in
|
143
|
+
# this installation.
|
144
|
+
#
|
145
|
+
def specs
|
146
|
+
specs_by_platform.values.flatten
|
147
|
+
end
|
148
|
+
|
149
|
+
# @return [Specification] the root specification of the Pod.
|
150
|
+
#
|
151
|
+
def root_spec
|
152
|
+
specs.first.root
|
153
|
+
end
|
154
|
+
|
155
|
+
# @return [Pathname] the folder where the source of the Pod is located.
|
156
|
+
#
|
157
|
+
def root
|
158
|
+
sandbox.pod_dir(root_spec.name)
|
159
|
+
end
|
160
|
+
|
161
|
+
# @return [Boolean] whether the source has been pre downloaded in the
|
162
|
+
# resolution process to retrieve its podspec.
|
163
|
+
#
|
164
|
+
def predownloaded?
|
165
|
+
sandbox.predownloaded_pods.include?(root_spec.name)
|
166
|
+
end
|
167
|
+
|
168
|
+
# @return [Boolean] whether the pod uses the local option and thus
|
169
|
+
# CocoaPods should not interfere with the files of the user.
|
170
|
+
#
|
171
|
+
def local?
|
172
|
+
sandbox.local?(root_spec.name)
|
173
|
+
end
|
174
|
+
|
175
|
+
#-----------------------------------------------------------------------#
|
176
|
+
|
177
|
+
private
|
178
|
+
|
179
|
+
# @!group Private helpers
|
180
|
+
|
181
|
+
# @return [Array<Sandbox::FileAccessor>] the file accessors for all the
|
182
|
+
# specifications on their respective platform.
|
183
|
+
#
|
184
|
+
def file_accessors
|
185
|
+
return @file_accessors if @file_accessors
|
186
|
+
@file_accessors = []
|
187
|
+
specs_by_platform.each do |platform, specs|
|
188
|
+
specs.each do |spec|
|
189
|
+
@file_accessors << Sandbox::FileAccessor.new(path_list, spec.consumer(platform))
|
190
|
+
end
|
191
|
+
end
|
192
|
+
@file_accessors
|
193
|
+
end
|
194
|
+
|
195
|
+
# @return [Sandbox::PathList] The path list for this Pod.
|
196
|
+
#
|
197
|
+
def path_list
|
198
|
+
@path_list ||= Sandbox::PathList.new(root)
|
199
|
+
end
|
200
|
+
|
201
|
+
# Finds the absolute paths, including hidden ones, of the files
|
202
|
+
# that are not used by the pod and thus can be safely deleted.
|
203
|
+
#
|
204
|
+
# @note Implementation detail: Don't use `Dir#glob` as there is an
|
205
|
+
# unexplained issue (#568, #572 and #602).
|
206
|
+
#
|
207
|
+
# @todo The paths are down-cased for the comparison as issues similar
|
208
|
+
# to #602 lead the files not being matched and so cleaning all
|
209
|
+
# the files. This solution might create side effects.
|
210
|
+
#
|
211
|
+
# @return [Array<Strings>] The paths that can be deleted.
|
212
|
+
#
|
213
|
+
def clean_paths
|
214
|
+
cached_used = used_files
|
215
|
+
glob_options = File::FNM_DOTMATCH | File::FNM_CASEFOLD
|
216
|
+
files = Pathname.glob(root + "**/*", glob_options).map(&:to_s)
|
217
|
+
|
218
|
+
files.reject! do |candidate|
|
219
|
+
candidate = candidate.downcase
|
220
|
+
candidate.end_with?('.', '..') || cached_used.any? do |path|
|
221
|
+
path = path.downcase
|
222
|
+
path.include?(candidate) || candidate.include?(path)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
files
|
226
|
+
end
|
227
|
+
|
228
|
+
# @return [Array<String>] The absolute path of all the files used by the
|
229
|
+
# specifications (according to their platform) of this Pod.
|
230
|
+
#
|
231
|
+
def used_files
|
232
|
+
files = [
|
233
|
+
file_accessors.map(&:source_files),
|
234
|
+
file_accessors.map(&:resources),
|
235
|
+
file_accessors.map(&:preserve_paths),
|
236
|
+
file_accessors.map(&:prefix_header),
|
237
|
+
file_accessors.map(&:readme),
|
238
|
+
file_accessors.map(&:license),
|
239
|
+
]
|
240
|
+
|
241
|
+
files.flatten.compact.map{ |path| path.to_s }.uniq
|
242
|
+
end
|
243
|
+
|
244
|
+
#-----------------------------------------------------------------------#
|
245
|
+
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|