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.
@@ -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
@@ -1,6 +1,6 @@
1
1
  module Pod
2
2
  # The version of the cocoapods command line tool.
3
3
  #
4
- VERSION = '0.31.1' unless defined? Pod::VERSION
4
+ VERSION = '0.32.0' unless defined? Pod::VERSION
5
5
  end
6
6
 
@@ -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.each do |file_accessor|
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
- if prefix_header_contents = file_accessor.spec_consumer.prefix_header_contents
59
- result << prefix_header_contents
60
- result << "\n"
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
@@ -64,11 +64,12 @@ module Pod
64
64
  @lockfile = lockfile
65
65
  end
66
66
 
67
- # @return [Bool] Whether the installer is in update mode. In update mode
68
- # the contents of the Lockfile are not taken into account for
69
- # deciding what Pods to install.
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 :update_mode
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.update_mode = update_mode
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
- UI.titled_section("Installing #{spec}".green, title_options) do
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
- @pods_project.add_pod_group(pod_name, path, local)
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
- @update_mode = false
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
- attr_accessor :update_mode
98
- alias_method :update_mode?, :update_mode
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.map do |pod|
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
- if update_mode?
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, lockfile)
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