cocoapods-square-stable 0.19.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|