cocoapods 0.31.1 → 0.32.0
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/CHANGELOG.md +97 -0
- data/lib/cocoapods.rb +0 -21
- data/lib/cocoapods/command.rb +3 -0
- data/lib/cocoapods/command/lib.rb +8 -3
- data/lib/cocoapods/command/project.rb +36 -4
- data/lib/cocoapods/command/spec.rb +1 -1
- data/lib/cocoapods/external_sources.rb +18 -363
- data/lib/cocoapods/external_sources/abstract_external_source.rb +139 -0
- data/lib/cocoapods/external_sources/downloader_source.rb +32 -0
- data/lib/cocoapods/external_sources/path_source.rb +58 -0
- data/lib/cocoapods/external_sources/podspec_source.rb +45 -0
- data/lib/cocoapods/gem_version.rb +1 -1
- data/lib/cocoapods/generator/prefix_header.rb +14 -5
- data/lib/cocoapods/installer.rb +16 -8
- data/lib/cocoapods/installer/analyzer.rb +35 -7
- data/lib/cocoapods/sandbox.rb +17 -2
- data/lib/cocoapods/validator.rb +46 -8
- metadata +56 -18
@@ -0,0 +1,139 @@
|
|
1
|
+
module Pod
|
2
|
+
module ExternalSources
|
3
|
+
|
4
|
+
# Abstract class that defines the common behaviour of external sources.
|
5
|
+
#
|
6
|
+
class AbstractExternalSource
|
7
|
+
|
8
|
+
# @return [String] the name of the Pod described by this external source.
|
9
|
+
#
|
10
|
+
attr_reader :name
|
11
|
+
|
12
|
+
# @return [Hash{Symbol => String}] the hash representation of the
|
13
|
+
# external source.
|
14
|
+
#
|
15
|
+
attr_reader :params
|
16
|
+
|
17
|
+
# @return [String] the path where the podfile is defined to resolve
|
18
|
+
# relative paths.
|
19
|
+
#
|
20
|
+
attr_reader :podfile_path
|
21
|
+
|
22
|
+
# @param [String] name @see name
|
23
|
+
# @param [Hash] params @see params
|
24
|
+
# @param [String] podfile_path @see podfile_path
|
25
|
+
#
|
26
|
+
def initialize(name, params, podfile_path)
|
27
|
+
@name = name
|
28
|
+
@params = params
|
29
|
+
@podfile_path = podfile_path
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Bool] whether an external source source is equal to another
|
33
|
+
# according to the {#name} and to the {#params}.
|
34
|
+
#
|
35
|
+
def ==(other)
|
36
|
+
return false if other.nil?
|
37
|
+
name == other.name && params == other.params
|
38
|
+
end
|
39
|
+
|
40
|
+
public
|
41
|
+
|
42
|
+
# @!group Subclasses hooks
|
43
|
+
|
44
|
+
# Fetches the external source from the remote according to the params.
|
45
|
+
#
|
46
|
+
# @param [Sandbox] sandbox
|
47
|
+
# the sandbox where the specification should be stored.
|
48
|
+
#
|
49
|
+
# @return [void]
|
50
|
+
#
|
51
|
+
def fetch(sandbox)
|
52
|
+
raise "Abstract method"
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [String] a string representation of the source suitable for UI.
|
56
|
+
#
|
57
|
+
def description
|
58
|
+
raise "Abstract method"
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
# @return [String] The uri of the podspec appending the name of the file
|
64
|
+
# and expanding it if necessary.
|
65
|
+
#
|
66
|
+
# @note If the declared path is expanded only if the represents a path
|
67
|
+
# relative to the file system.
|
68
|
+
#
|
69
|
+
def normalized_podspec_path(declared_path)
|
70
|
+
if File.extname(declared_path) == '.podspec'
|
71
|
+
path_with_ext = declared_path
|
72
|
+
else
|
73
|
+
path_with_ext = "#{declared_path}/#{name}.podspec"
|
74
|
+
end
|
75
|
+
podfile_dir = File.dirname(podfile_path || '')
|
76
|
+
File.expand_path(path_with_ext, podfile_dir)
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
# @! Subclasses helpers
|
82
|
+
|
83
|
+
# Pre-downloads a Pod passing the options to the downloader and informing
|
84
|
+
# the sandbox.
|
85
|
+
#
|
86
|
+
# @param [Sandbox] sandbox
|
87
|
+
# The sandbox where the Pod should be downloaded.
|
88
|
+
#
|
89
|
+
# @note To prevent a double download of the repository the pod is
|
90
|
+
# marked as pre-downloaded indicating to the installer that only
|
91
|
+
# clean operations are needed.
|
92
|
+
#
|
93
|
+
# @todo The downloader configuration is the same of the
|
94
|
+
# #{PodSourceInstaller} and it needs to be kept in sync.
|
95
|
+
#
|
96
|
+
# @return [void]
|
97
|
+
#
|
98
|
+
def pre_download(sandbox)
|
99
|
+
title = "Pre-downloading: `#{name}` #{description}"
|
100
|
+
UI.titled_section(title, { :verbose_prefix => "-> " }) do
|
101
|
+
target = sandbox.root + name
|
102
|
+
target.rmtree if target.exist?
|
103
|
+
downloader = Config.instance.downloader(target, params)
|
104
|
+
downloader.download
|
105
|
+
store_podspec(sandbox, target + "#{name}.podspec")
|
106
|
+
sandbox.store_pre_downloaded_pod(name)
|
107
|
+
if downloader.options_specific?
|
108
|
+
source = params
|
109
|
+
else
|
110
|
+
source = downloader.checkout_options
|
111
|
+
end
|
112
|
+
sandbox.store_checkout_source(name, source)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Stores the podspec in the sandbox and marks it as from an external
|
117
|
+
# source.
|
118
|
+
#
|
119
|
+
# @param [Sandbox] sandbox
|
120
|
+
# The sandbox where the specification should be stored.
|
121
|
+
#
|
122
|
+
# @param [Pathname, String] spec
|
123
|
+
# The path of the specification or its contents.
|
124
|
+
#
|
125
|
+
# @note All the concrete implementations of #{fetch} should invoke this
|
126
|
+
# method.
|
127
|
+
#
|
128
|
+
# @note The sandbox ensures that the podspec exists and that the names
|
129
|
+
# match.
|
130
|
+
#
|
131
|
+
# @return [void]
|
132
|
+
#
|
133
|
+
def store_podspec(sandbox, spec)
|
134
|
+
sandbox.store_podspec(name, spec, true)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Pod
|
2
|
+
module ExternalSources
|
3
|
+
|
4
|
+
# Provides support for fetching a specification file from a source handled
|
5
|
+
# by the downloader. Supports all the options of the downloader
|
6
|
+
#
|
7
|
+
# @note The podspec must be in the root of the repository and should have a
|
8
|
+
# name matching the one of the dependency.
|
9
|
+
#
|
10
|
+
class DownloaderSource < AbstractExternalSource
|
11
|
+
|
12
|
+
# @see AbstractExternalSource#fetch
|
13
|
+
#
|
14
|
+
def fetch(sandbox)
|
15
|
+
pre_download(sandbox)
|
16
|
+
end
|
17
|
+
|
18
|
+
# @see AbstractExternalSource#description
|
19
|
+
#
|
20
|
+
def description
|
21
|
+
strategy = Downloader.strategy_from_options(params)
|
22
|
+
options = params.dup
|
23
|
+
url = options.delete(strategy)
|
24
|
+
result = "from `#{url}`"
|
25
|
+
options.each do |key, value|
|
26
|
+
result << ", #{key} `#{value}`"
|
27
|
+
end
|
28
|
+
result
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Pod
|
2
|
+
module ExternalSources
|
3
|
+
|
4
|
+
# Provides support for fetching a specification file from a path local to
|
5
|
+
# the machine running the installation.
|
6
|
+
#
|
7
|
+
# Works with the {LocalPod::LocalSourcedPod} class.
|
8
|
+
#
|
9
|
+
class PathSource < AbstractExternalSource
|
10
|
+
|
11
|
+
# @see AbstractExternalSource#fetch
|
12
|
+
#
|
13
|
+
def fetch(sandbox)
|
14
|
+
title = "Fetching podspec for `#{name}` #{description}"
|
15
|
+
UI.titled_section(title, { :verbose_prefix => "-> " }) do
|
16
|
+
podspec = podspec_path
|
17
|
+
unless podspec.exist?
|
18
|
+
raise Informative, "No podspec found for `#{name}` in " \
|
19
|
+
"`#{declared_path}`"
|
20
|
+
end
|
21
|
+
store_podspec(sandbox, podspec)
|
22
|
+
is_absolute = absolute?(podspec)
|
23
|
+
sandbox.store_local_path(name, podspec.dirname, is_absolute)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @see AbstractExternalSource#description
|
28
|
+
#
|
29
|
+
def description
|
30
|
+
"from `#{params[:path] || params[:local]}`"
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# @!group Helpers
|
36
|
+
|
37
|
+
# @return [String] The path as declared by the user.
|
38
|
+
#
|
39
|
+
def declared_path
|
40
|
+
result = params[:path] || params[:local]
|
41
|
+
result.to_s if result
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [Pathname] The absolute path of the podspec.
|
45
|
+
#
|
46
|
+
def podspec_path
|
47
|
+
Pathname(normalized_podspec_path(declared_path))
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Bool]
|
51
|
+
#
|
52
|
+
def absolute?(path)
|
53
|
+
Pathname(path).absolute? || path.to_s.start_with?('~')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Pod
|
2
|
+
module ExternalSources
|
3
|
+
|
4
|
+
# Provides support for fetching a specification file from an URL. Can be
|
5
|
+
# http, file, etc.
|
6
|
+
#
|
7
|
+
class PodspecSource < AbstractExternalSource
|
8
|
+
|
9
|
+
# @see AbstractExternalSource#fetch
|
10
|
+
#
|
11
|
+
def fetch(sandbox)
|
12
|
+
title = "Fetching podspec for `#{name}` #{description}"
|
13
|
+
UI.titled_section(title, { :verbose_prefix => "-> " }) do
|
14
|
+
require 'open-uri'
|
15
|
+
open(podspec_uri) { |io| store_podspec(sandbox, io.read) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# @see AbstractExternalSource#description
|
20
|
+
#
|
21
|
+
def description
|
22
|
+
"from `#{params[:podspec]}`"
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# @!group Helpers
|
28
|
+
|
29
|
+
# @return [String] The uri of the podspec appending the name of the file
|
30
|
+
# and expanding it if necessary.
|
31
|
+
#
|
32
|
+
# @note If the declared path is expanded only if the represents a path
|
33
|
+
# relative to the file system.
|
34
|
+
#
|
35
|
+
def podspec_uri
|
36
|
+
declared_path = params[:podspec].to_s
|
37
|
+
if declared_path.match(%r{^.+://})
|
38
|
+
declared_path
|
39
|
+
else
|
40
|
+
normalized_podspec_path(declared_path)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -40,9 +40,12 @@ module Pod
|
|
40
40
|
# added to the top of the prefix header. For OS X `Cocoa/Cocoa.h`
|
41
41
|
# is imported.
|
42
42
|
#
|
43
|
+
# @note Only unique prefix_header_contents are added to the prefix header.
|
44
|
+
#
|
43
45
|
# @return [String]
|
44
46
|
#
|
45
47
|
# @todo Subspecs can specify prefix header information too.
|
48
|
+
# @todo Check to see if we have a similar duplication issue with file_accessor.prefix_header.
|
46
49
|
#
|
47
50
|
def generate
|
48
51
|
result = "#ifdef __OBJC__\n"
|
@@ -53,12 +56,18 @@ module Pod
|
|
53
56
|
result << %|\n#import "#{import}"|
|
54
57
|
end
|
55
58
|
|
56
|
-
file_accessors.
|
59
|
+
unique_prefix_header_contents = file_accessors.collect do |file_accessor|
|
60
|
+
file_accessor.spec_consumer.prefix_header_contents
|
61
|
+
end.compact.uniq
|
62
|
+
|
63
|
+
result << "\n"
|
64
|
+
|
65
|
+
unique_prefix_header_contents.each do |prefix_header_contents|
|
66
|
+
result << prefix_header_contents
|
57
67
|
result << "\n"
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
end
|
68
|
+
end
|
69
|
+
|
70
|
+
file_accessors.each do |file_accessor|
|
62
71
|
if prefix_header = file_accessor.prefix_header
|
63
72
|
result << Pathname(prefix_header).read
|
64
73
|
end
|
data/lib/cocoapods/installer.rb
CHANGED
@@ -64,11 +64,12 @@ module Pod
|
|
64
64
|
@lockfile = lockfile
|
65
65
|
end
|
66
66
|
|
67
|
-
# @return [
|
68
|
-
#
|
69
|
-
#
|
67
|
+
# @return [Hash, Boolean, nil] Pods that have been requested to be
|
68
|
+
# updated or true if all Pods should be updated.
|
69
|
+
# If all Pods should been updated the contents of the Lockfile are
|
70
|
+
# not taken into account for deciding what Pods to install.
|
70
71
|
#
|
71
|
-
attr_accessor :
|
72
|
+
attr_accessor :update
|
72
73
|
|
73
74
|
# Installs the Pods.
|
74
75
|
#
|
@@ -169,7 +170,7 @@ module Pod
|
|
169
170
|
end
|
170
171
|
|
171
172
|
analyzer = Analyzer.new(sandbox, podfile, lockfile)
|
172
|
-
analyzer.
|
173
|
+
analyzer.update = update
|
173
174
|
@analysis_result = analyzer.analyze
|
174
175
|
@aggregate_targets = analyzer.result.targets
|
175
176
|
end
|
@@ -235,7 +236,13 @@ module Pod
|
|
235
236
|
title_options = { :verbose_prefix => "-> ".green }
|
236
237
|
root_specs.sort_by(&:name).each do |spec|
|
237
238
|
if pods_to_install.include?(spec.name)
|
238
|
-
|
239
|
+
if sandbox_state.changed.include?(spec.name) && sandbox.manifest
|
240
|
+
previous = sandbox.manifest.version(spec.name)
|
241
|
+
title = "Installing #{spec.name} #{spec.version} (was #{previous})"
|
242
|
+
else
|
243
|
+
title = "Installing #{spec}"
|
244
|
+
end
|
245
|
+
UI.titled_section(title.green, title_options) do
|
239
246
|
install_source_of_pod(spec.name)
|
240
247
|
end
|
241
248
|
else
|
@@ -295,9 +302,10 @@ module Pod
|
|
295
302
|
|
296
303
|
pod_names = pod_targets.map(&:pod_name).uniq
|
297
304
|
pod_names.each do |pod_name|
|
298
|
-
path = sandbox.pod_dir(pod_name)
|
299
305
|
local = sandbox.local?(pod_name)
|
300
|
-
|
306
|
+
path = sandbox.pod_dir(pod_name)
|
307
|
+
was_absolute = sandbox.local_path_was_absolute?(pod_name)
|
308
|
+
@pods_project.add_pod_group(pod_name, path, local, was_absolute)
|
301
309
|
end
|
302
310
|
|
303
311
|
if config.podfile_path
|
@@ -33,7 +33,7 @@ module Pod
|
|
33
33
|
@podfile = podfile
|
34
34
|
@lockfile = lockfile
|
35
35
|
|
36
|
-
@
|
36
|
+
@update = false
|
37
37
|
@allow_pre_downloads = true
|
38
38
|
@archs_by_target_def = {}
|
39
39
|
end
|
@@ -91,11 +91,30 @@ module Pod
|
|
91
91
|
|
92
92
|
# @!group Configuration
|
93
93
|
|
94
|
+
# @return [Hash, Boolean, nil] Pods that have been requested to be
|
95
|
+
# updated or true if all Pods should be updated
|
96
|
+
#
|
97
|
+
attr_accessor :update
|
98
|
+
|
94
99
|
# @return [Bool] Whether the version of the dependencies which did non
|
95
100
|
# change in the Podfile should be locked.
|
96
101
|
#
|
97
|
-
|
98
|
-
|
102
|
+
def update_mode?
|
103
|
+
!!update
|
104
|
+
end
|
105
|
+
|
106
|
+
# @return [Symbol] Whether and how the dependencies in the Podfile
|
107
|
+
# should be updated.
|
108
|
+
#
|
109
|
+
def update_mode
|
110
|
+
if !update
|
111
|
+
:none
|
112
|
+
elsif update == true
|
113
|
+
:all
|
114
|
+
elsif update[:pods] != nil
|
115
|
+
:selected
|
116
|
+
end
|
117
|
+
end
|
99
118
|
|
100
119
|
# @return [Bool] Whether the analysis allows pre-downloads and thus
|
101
120
|
# modifications to the sandbox.
|
@@ -219,10 +238,15 @@ module Pod
|
|
219
238
|
# that prevent the resolver to update a Pod.
|
220
239
|
#
|
221
240
|
def generate_version_locking_dependencies
|
222
|
-
if update_mode
|
241
|
+
if update_mode == :all
|
223
242
|
[]
|
224
243
|
else
|
225
|
-
result.podfile_state.unchanged
|
244
|
+
locking_pods = result.podfile_state.unchanged
|
245
|
+
if update_mode == :selected
|
246
|
+
# If selected Pods should been updated, filter them out of the list
|
247
|
+
locking_pods = locking_pods.select { |pod| !update[:pods].include?(pod) }
|
248
|
+
end
|
249
|
+
locking_pods.map do |pod|
|
226
250
|
lockfile.dependency_to_lock_pod_named(pod)
|
227
251
|
end
|
228
252
|
end
|
@@ -252,10 +276,14 @@ module Pod
|
|
252
276
|
deps_to_fetch = []
|
253
277
|
deps_to_fetch_if_needed = []
|
254
278
|
deps_with_external_source = podfile.dependencies.select { |dep| dep.external_source }
|
255
|
-
|
279
|
+
|
280
|
+
if update_mode == :all
|
256
281
|
deps_to_fetch = deps_with_external_source
|
257
282
|
else
|
258
283
|
pods_to_fetch = result.podfile_state.added + result.podfile_state.changed
|
284
|
+
if update_mode == :selected
|
285
|
+
pods_to_fetch += update[:pods]
|
286
|
+
end
|
259
287
|
deps_to_fetch = deps_with_external_source.select { |dep| pods_to_fetch.include?(dep.root_name) }
|
260
288
|
deps_to_fetch_if_needed = deps_with_external_source.select { |dep| result.podfile_state.unchanged.include?(dep.root_name) }
|
261
289
|
deps_to_fetch += deps_to_fetch_if_needed.select { |dep| sandbox.specification(dep.root_name).nil? || !dep.external_source[:local].nil? || !dep.external_source[:path].nil? }
|
@@ -316,7 +344,7 @@ module Pod
|
|
316
344
|
def generate_sandbox_state
|
317
345
|
sandbox_state = nil
|
318
346
|
UI.section "Comparing resolved specification to the sandbox manifest" do
|
319
|
-
sandbox_analyzer = SandboxAnalyzer.new(sandbox, result.specifications, update_mode
|
347
|
+
sandbox_analyzer = SandboxAnalyzer.new(sandbox, result.specifications, update_mode?, lockfile)
|
320
348
|
sandbox_state = sandbox_analyzer.analyze
|
321
349
|
sandbox_state.print
|
322
350
|
end
|