Commit e61e6c8c authored by Kyle Fuller's avatar Kyle Fuller

Merge pull request #2725 from CocoaPods/lockfile-checkout-options

[Analyzer] Use specific checkout options from lockfile
parents 9ca5e278 0c218e81
...@@ -14,6 +14,13 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ...@@ -14,6 +14,13 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
[Samuel Giddins](https://github.com/segiddins) [Samuel Giddins](https://github.com/segiddins)
[#532](https://github.com/CocoaPods/CocoaPods/issues/532) [#532](https://github.com/CocoaPods/CocoaPods/issues/532)
* From now on, pods installed directly from their repositories will be recorded
in the `Podfile.lock` file and will be guaranteed to be checked-out using the
same revision on subsequent installations. Examples of this are when using
the `:git`, `:svn`, or `:hg` options in your `Podfile`.
[Samuel Giddins](https://github.com/segiddins)
[#1058](https://github.com/CocoaPods/CocoaPods/issues/1058)
##### Bug Fixes ##### Bug Fixes
* Fix an output formatting issue with various commands like `pod search` * Fix an output formatting issue with various commands like `pod search`
......
GIT GIT
remote: https://github.com/CocoaPods/Core.git remote: https://github.com/CocoaPods/Core.git
revision: 60a486e8141323390dc5ff7f6676cf893a251a48 revision: 320bb0cf36d38f038a6478ad87618dd8bf148ffc
branch: master branch: master
specs: specs:
cocoapods-core (0.35.0.rc2) cocoapods-core (0.35.0.rc2)
...@@ -69,7 +69,7 @@ PATH ...@@ -69,7 +69,7 @@ PATH
GEM GEM
remote: http://rubygems.org/ remote: http://rubygems.org/
specs: specs:
activesupport (4.1.7) activesupport (4.1.8)
i18n (~> 0.6, >= 0.6.9) i18n (~> 0.6, >= 0.6.9)
json (~> 1.7, >= 1.7.7) json (~> 1.7, >= 1.7.7)
minitest (~> 5.1) minitest (~> 5.1)
......
...@@ -13,9 +13,11 @@ module Pod ...@@ -13,9 +13,11 @@ module Pod
# hash. # hash.
# #
def self.from_dependency(dependency, podfile_path) def self.from_dependency(dependency, podfile_path)
name = dependency.root_name from_params(dependency.external_source, dependency, podfile_path)
params = dependency.external_source end
def self.from_params(params, dependency, podfile_path)
name = dependency.root_name
if klass = concrete_class_from_params(params) if klass = concrete_class_from_params(params)
klass.new(name, params, podfile_path) klass.new(name, params, podfile_path)
else else
......
...@@ -465,8 +465,9 @@ module Pod ...@@ -465,8 +465,9 @@ module Pod
# @return [void] # @return [void]
# #
def write_lockfiles def write_lockfiles
# checkout_options = sandbox.checkout_options external_source_pods = podfile.dependencies.select(&:external_source).map(&:root_name).uniq
@lockfile = Lockfile.generate(podfile, analysis_result.specifications) checkout_options = sandbox.checkout_sources.select { |root_name, _| external_source_pods.include? root_name }
@lockfile = Lockfile.generate(podfile, analysis_result.specifications, checkout_options)
UI.message "- Writing Lockfile in #{UI.path config.lockfile_path}" do UI.message "- Writing Lockfile in #{UI.path config.lockfile_path}" do
@lockfile.write_to_disk(config.lockfile_path) @lockfile.write_to_disk(config.lockfile_path)
......
...@@ -53,6 +53,7 @@ module Pod ...@@ -53,6 +53,7 @@ module Pod
@result.podfile_state = generate_podfile_state @result.podfile_state = generate_podfile_state
@locked_dependencies = generate_version_locking_dependencies @locked_dependencies = generate_version_locking_dependencies
store_existing_checkout_options
fetch_external_sources if allow_fetches fetch_external_sources if allow_fetches
@result.specs_by_target = resolve_dependencies @result.specs_by_target = resolve_dependencies
@result.specifications = generate_specifications @result.specifications = generate_specifications
...@@ -264,33 +265,81 @@ module Pod ...@@ -264,33 +265,81 @@ module Pod
# #
def fetch_external_sources def fetch_external_sources
return unless allow_pre_downloads? return unless allow_pre_downloads?
deps_to_fetch = []
deps_to_fetch_if_needed = []
deps_with_external_source = podfile.dependencies.select(&:external_source)
deps_with_different_sources = podfile.dependencies.group_by(&:root_name).select { |_root_name, dependencies| dependencies.map(&:external_source).uniq.count > 1 } verify_no_pods_with_different_sources!
unless dependencies_to_fetch.empty?
UI.section 'Fetching external sources' do
dependencies_to_fetch.sort.each do |dependency|
fetch_external_source(dependency, !pods_to_fetch.include?(dependency.name))
end
end
end
end
def verify_no_pods_with_different_sources!
deps_with_different_sources = podfile.dependencies.group_by(&:root_name).
select { |_root_name, dependencies| dependencies.map(&:external_source).uniq.count > 1 }
deps_with_different_sources.each do |root_name, dependencies| deps_with_different_sources.each do |root_name, dependencies|
raise Informative, "There are multiple dependencies with different sources for `#{root_name}` in #{UI.path podfile.defined_in_file}:\n\n- #{dependencies.map(&:to_s).join("\n- ")}" raise Informative, "There are multiple dependencies with different " \
"sources for `#{root_name}` in #{UI.path podfile.defined_in_file}:" \
"\n\n- #{dependencies.map(&:to_s).join("\n- ")}"
end end
end
if update_mode == :all def fetch_external_source(dependency, use_lockfile_options)
deps_to_fetch = deps_with_external_source checkout_options = lockfile.checkout_options_for_pod_named(dependency.root_name) if lockfile
if checkout_options && use_lockfile_options
source = ExternalSources.from_params(checkout_options, dependency, podfile.defined_in_file)
else else
source = ExternalSources.from_dependency(dependency, podfile.defined_in_file)
end
source.fetch(sandbox)
end
def dependencies_to_fetch
@deps_to_fetch ||= begin
deps_to_fetch = []
deps_to_fetch_if_needed = []
deps_with_external_source = podfile.dependencies.select(&:external_source)
if update_mode == :all
deps_to_fetch = deps_with_external_source
else
deps_to_fetch = deps_with_external_source.select { |dep| pods_to_fetch.include?(dep.name) }
deps_to_fetch_if_needed = deps_with_external_source.select { |dep| result.podfile_state.unchanged.include?(dep.name) }
deps_to_fetch += deps_to_fetch_if_needed.select do |dep|
sandbox.specification(dep.name).nil? ||
!dep.external_source[:local].nil? ||
!dep.external_source[:path].nil? ||
!sandbox.pod_dir(dep.root_name).directory? ||
checkout_requires_update?(dep)
end
end
deps_to_fetch.uniq(&:root_name)
end
end
def checkout_requires_update?(dependency)
return true unless lockfile && sandbox.manifest
locked_checkout_options = lockfile.checkout_options_for_pod_named(dependency.root_name)
sandbox_checkout_options = sandbox.manifest.checkout_options_for_pod_named(dependency.root_name)
locked_checkout_options != sandbox_checkout_options
end
def pods_to_fetch
@pods_to_fetch ||= begin
pods_to_fetch = result.podfile_state.added + result.podfile_state.changed pods_to_fetch = result.podfile_state.added + result.podfile_state.changed
if update_mode == :selected if update_mode == :selected
pods_to_fetch += update[:pods] pods_to_fetch += update[:pods]
end end
deps_to_fetch = deps_with_external_source.select { |dep| pods_to_fetch.include?(dep.name) } pods_to_fetch
deps_to_fetch_if_needed = deps_with_external_source.select { |dep| result.podfile_state.unchanged.include?(dep.name) }
deps_to_fetch += deps_to_fetch_if_needed.select { |dep| sandbox.specification(dep.name).nil? || !dep.external_source[:local].nil? || !dep.external_source[:path].nil? || !sandbox.pod_dir(dep.name).directory? }
end end
end
unless deps_to_fetch.empty? def store_existing_checkout_options
UI.section 'Fetching external sources' do podfile.dependencies.select(&:external_source).each do |dep|
deps_to_fetch.uniq(&:root_name).sort.each do |dependency| if checkout_options = lockfile && lockfile.checkout_options_for_pod_named(dep.root_name)
source = ExternalSources.from_dependency(dependency, podfile.defined_in_file) sandbox.store_checkout_source(dep.root_name, checkout_options)
source.fetch(sandbox)
end
end end
end end
end end
......
...@@ -64,8 +64,12 @@ module Pod ...@@ -64,8 +64,12 @@ module Pod
# @return [Lockfile] the manifest which contains the information about the # @return [Lockfile] the manifest which contains the information about the
# installed pods. # installed pods.
# #
attr_accessor :manifest
def manifest def manifest
Lockfile.from_file(manifest_path) if manifest_path.exist? @manifest ||= begin
Lockfile.from_file(manifest_path) if manifest_path.exist?
end
end end
# @return [Project] the Pods project. # @return [Project] the Pods project.
......
Subproject commit 365a0c8d93de662c019d6dbf3131f65842952357 Subproject commit 1b603f3f9a53c497734ffaf9926416c0582064c2
...@@ -63,7 +63,8 @@ module Pod ...@@ -63,7 +63,8 @@ module Pod
s.version = '1.0' s.version = '1.0'
end, end,
] ]
Lockfile.generate(podfile, specs).write_to_disk(temporary_directory + 'Podfile.lock') external_sources = {}
Lockfile.generate(podfile, specs, external_sources).write_to_disk(temporary_directory + 'Podfile.lock')
end end
it 'for a single missing Pod' do it 'for a single missing Pod' do
......
...@@ -176,6 +176,11 @@ describe_cli 'pod' do ...@@ -176,6 +176,11 @@ describe_cli 'pod' do
behaves_like cli_spec 'install_podfile_callbacks', behaves_like cli_spec 'install_podfile_callbacks',
'install --no-repo-update' 'install --no-repo-update'
end end
describe 'Uses Lockfile checkout options' do
behaves_like cli_spec 'install_using_checkout_options',
'install --no-repo-update'
end
end end
#--------------------------------------# #--------------------------------------#
......
...@@ -26,7 +26,9 @@ require 'bacon' ...@@ -26,7 +26,9 @@ require 'bacon'
require 'mocha-on-bacon' require 'mocha-on-bacon'
require 'pretty_bacon' require 'pretty_bacon'
require 'pathname' require 'pathname'
require 'active_support/core_ext/string/strip' require 'active_support/core_ext/string/strip'
require 'active_support/core_ext/object/deep_dup'
ROOT = Pathname.new(File.expand_path('../../', __FILE__)) ROOT = Pathname.new(File.expand_path('../../', __FILE__))
$:.unshift((ROOT + 'lib').to_s) $:.unshift((ROOT + 'lib').to_s)
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment