Commit 86dce91c authored by Fabio Pelosin's avatar Fabio Pelosin

Merge pull request #1999 from mrackwitz/feature_pod_update

#760: pod update PODS
parents 6e9dbbee 37de587e
......@@ -30,4 +30,14 @@ examples/RelativePathProject/RelativePathProject/RelativePathProject.xcodeproj
coverage/
.coveralls.yml
# IDEs
*.xccheckout
.idea/
# RVM files
/.rvmrc
/.ruby-version
/.ruby-gemset
# Bundler files
/.bundle
......@@ -2,6 +2,20 @@
To install or update CocoaPods see this [guide](http://docs.cocoapods.org/guides/installing_cocoapods.html).
## Master
[CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/master...0.31.1)
[CocoaPods-Core](https://github.com/CocoaPods/Core/compare/master...0.31.1)
##### Enhancements
* Allow to update only a list of given pods with `pod update [POD_NAMES...]`.
[Marius Rackwitz](https://github.com/mrackwitz)
[CocoaPods#760](https://github.com/CocoaPods/CocoaPods/issues/760)
* `pod update` falls back to `pod install` if no Lockfile is present.
[Marius Rackwitz](https://github.com/mrackwitz)
## 0.31.1
[CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.31.1...0.31.0)
[CocoaPods-Core](https://github.com/CocoaPods/Core/compare/0.31.1...0.31.0)
......
......@@ -77,7 +77,7 @@ end
namespace :spec do
def specs(dir)
FileList["spec/#{dir}/*_spec.rb"].shuffle.join(' ')
FileList["spec/#{dir}_spec.rb"].shuffle.join(' ')
end
#--------------------------------------#
......@@ -89,7 +89,7 @@ namespace :spec do
#--------------------------------------#
unit_specs_command = "bundle exec bacon #{specs('unit/**')}"
unit_specs_command = "bundle exec bacon #{specs('unit/**/*')}"
desc "Run the unit specs"
task :unit => :unpack_fixture_tarballs do
......@@ -104,8 +104,9 @@ namespace :spec do
#--------------------------------------#
desc "Run the functional specs"
task :functional => :unpack_fixture_tarballs do
sh "bundle exec bacon #{specs('functional/**')}"
task :functional, [:spec] => :unpack_fixture_tarballs do |t, args|
args.with_defaults(:spec => '**/*')
sh "bundle exec bacon #{specs("functional/#{args[:spec]}")}"
end
#--------------------------------------#
......@@ -130,7 +131,7 @@ namespace :spec do
ENV['GENERATE_COVERAGE'] = 'true'
title 'Running the specs'
sh "bundle exec bacon #{specs('**')}"
sh "bundle exec bacon #{specs('**/*')}"
title 'Running Integration tests'
sh "bundle exec bacon spec/integration.rb"
......@@ -144,7 +145,7 @@ namespace :spec do
desc "Run all specs and build all examples"
task :ci => :unpack_fixture_tarballs do
title 'Running the specs'
sh "bundle exec bacon #{specs('**')}"
sh "bundle exec bacon #{specs('**/*')}"
require 'pathname'
unless Pathname.new(ENV['HOME']+'/.cocoapods/repos/master').exist?
......
......@@ -28,13 +28,15 @@ module Pod
# Runs the installer.
#
# @param [update] whether the installer should be run in update mode.
# @param [Hash, Boolean, nil] update
# Pods that have been requested to be updated or true if all Pods
# should be updated
#
# @return [void]
#
def run_install_with_update(update)
installer = Installer.new(config.sandbox, config.podfile, config.lockfile)
installer.update_mode = update
installer.update = update
installer.install!
end
end
......@@ -76,10 +78,40 @@ module Pod
self.summary = 'Update outdated project dependencies'
self.description = <<-DESC
Updates the Pods identified by the specified POD_NAMES. If no POD_NAMES are
specified it updates all the Pods ignoring the contents of the Podfile.lock.
This command is reserved to the update of dependencies and pod install should
be used to install changes to the Podfile.
DESC
self.arguments = '[POD_NAMES...]'
def initialize(argv)
@pods = argv.arguments! unless argv.arguments.empty?
super
end
def run
verify_podfile_exists!
verify_lockfile_exists!
run_install_with_update(true)
if @pods
verify_lockfile_exists!
# Check if all given pods are installed
missing_pods = @pods.select { |pod| !config.lockfile.pod_names.include?(pod) }
if missing_pods.length > 0
raise Informative, (missing_pods.length > 1 \
? "Pods %s are not installed and cannot be updated" \
: "Pod %s is not installed and cannot be updated"
) % missing_pods.map { |p| "`#{p}'" }.join(', ')
end
run_install_with_update(:pods => @pods)
else
UI.puts "Update all pods".yellow unless @pods
run_install_with_update(true)
end
end
end
......
......@@ -64,11 +64,12 @@ module Pod
@lockfile = lockfile
end
# @return [Bool] Whether the installer is in update mode. In update mode
# the contents of the Lockfile are not taken into account for
# deciding what Pods to install.
# @return [Hash, Boolean, nil] Pods that have been requested to be
# updated or true if all Pods should be updated.
# If all Pods should been updated the contents of the Lockfile are
# not taken into account for deciding what Pods to install.
#
attr_accessor :update_mode
attr_accessor :update
# Installs the Pods.
#
......@@ -169,7 +170,7 @@ module Pod
end
analyzer = Analyzer.new(sandbox, podfile, lockfile)
analyzer.update_mode = update_mode
analyzer.update = update
@analysis_result = analyzer.analyze
@aggregate_targets = analyzer.result.targets
end
......
......@@ -33,7 +33,7 @@ module Pod
@podfile = podfile
@lockfile = lockfile
@update_mode = false
@update = false
@allow_pre_downloads = true
@archs_by_target_def = {}
end
......@@ -91,11 +91,30 @@ module Pod
# @!group Configuration
# @return [Hash, Boolean, nil] Pods that have been requested to be
# updated or true if all Pods should be updated
#
attr_accessor :update
# @return [Bool] Whether the version of the dependencies which did non
# change in the Podfile should be locked.
#
attr_accessor :update_mode
alias_method :update_mode?, :update_mode
def update_mode?
!!update
end
# @return [Symbol] Whether and how the dependencies in the Podfile
# should be updated.
#
def update_mode
if !update
:none
elsif update == true
:all
elsif update[:pods] != nil
:selected
end
end
# @return [Bool] Whether the analysis allows pre-downloads and thus
# modifications to the sandbox.
......@@ -219,10 +238,15 @@ module Pod
# that prevent the resolver to update a Pod.
#
def generate_version_locking_dependencies
if update_mode?
if update_mode == :all
[]
else
result.podfile_state.unchanged.map do |pod|
locking_pods = result.podfile_state.unchanged
if update_mode == :selected
# If selected Pods should been updated, filter them out of the list
locking_pods = locking_pods.select { |pod| !update[:pods].include?(pod) }
end
locking_pods.map do |pod|
lockfile.dependency_to_lock_pod_named(pod)
end
end
......@@ -252,10 +276,14 @@ module Pod
deps_to_fetch = []
deps_to_fetch_if_needed = []
deps_with_external_source = podfile.dependencies.select { |dep| dep.external_source }
if update_mode?
if update_mode == :all
deps_to_fetch = deps_with_external_source
else
pods_to_fetch = result.podfile_state.added + result.podfile_state.changed
if update_mode == :selected
pods_to_fetch += update[:pods]
end
deps_to_fetch = deps_with_external_source.select { |dep| pods_to_fetch.include?(dep.root_name) }
deps_to_fetch_if_needed = deps_with_external_source.select { |dep| result.podfile_state.unchanged.include?(dep.root_name) }
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
def generate_sandbox_state
sandbox_state = nil
UI.section "Comparing resolved specification to the sandbox manifest" do
sandbox_analyzer = SandboxAnalyzer.new(sandbox, result.specifications, update_mode, lockfile)
sandbox_analyzer = SandboxAnalyzer.new(sandbox, result.specifications, update_mode?, lockfile)
sandbox_state = sandbox_analyzer.analyze
sandbox_state.print
end
......
Subproject commit 57b7ab8a5ae08a2e3b93972ee14ce2d7f674c08e
Subproject commit d0378da111a5368a28c019e57e4a9f3d3d8e9d94
......@@ -34,13 +34,54 @@ module Pod
it "tells the user that no Lockfile was found in the current working dir" do
file = temporary_directory + 'Podfile'
File.open(file, 'w') {|f| f.write('platform :ios') }
File.open(file, 'w') do |f|
f.puts('platform :ios')
f.puts('pod "Reachability"')
end
Dir.chdir(temporary_directory) do
exception = lambda { run_command('update','--no-repo-update') }.should.raise Informative
exception = lambda { run_command('update', 'Reachability', '--no-repo-update') }.should.raise Informative
exception.message.should.include "No `Podfile.lock' found in the current working directory"
end
end
describe "tells the user that the Pods cannot be updated unless they are installed" do
extend SpecHelper::TemporaryRepos
before do
file = temporary_directory + 'Podfile'
File.open(file, 'w') do |f|
f.puts('platform :ios')
f.puts('pod "BananaLib", "1.0"')
end
podfile = Podfile.new do
platform :ios
pod 'BananaLib', '1.0'
end
specs = [
Specification.new do |s|
s.name = 'BananaLib'
s.version = '1.0'
end
]
Lockfile.generate(podfile, specs).write_to_disk(temporary_directory + 'Podfile.lock')
end
it "for a single missing Pod" do
Dir.chdir(temporary_directory) do
exception = lambda { run_command('update', 'Reachability', '--no-repo-update') }.should.raise Informative
exception.message.should.include "Pod `Reachability' is not installed and cannot be updated"
end
end
it "for multiple missing Pods" do
Dir.chdir(temporary_directory) do
exception = lambda { run_command('update', 'Reachability', 'BananaLib2', '--no-repo-update') }.should.raise Informative
exception.message.should.include "Pods `Reachability', `BananaLib2' are not installed and cannot be updated"
end
end
end
end
#---------------------------------------------------------------------------#
......
......@@ -370,7 +370,11 @@ describe "Integration" do
describe "Pod update" do
describe "Updates an existing installation" do
check "update --no-repo-update", "update"
check "update --no-repo-update", "update_all"
end
describe "Updates a selected Pod in an existing installation" do
check "update Reachability --no-repo-update", "update_selected"
end
end
......
......@@ -95,14 +95,14 @@ module Pod
it "considers changed a Pod whose specification is in head mode if in update mode" do
@sandbox.stubs(:head_pod?).returns(true)
@analyzer.stubs(:update_mode).returns(true)
@analyzer.stubs(:update_mode?).returns(true)
@analyzer.send(:pod_changed?, 'BananaLib').should == true
end
it "doesn't consider changed a Pod whose specification is in head mode if not in update mode" do
@sandbox.stubs(:head_pod?).returns(true)
@analyzer.stubs(:sandbox_head_version?).returns(true)
@analyzer.stubs(:update_mode).returns(false)
@analyzer.stubs(:update_mode?).returns(false)
@analyzer.send(:pod_changed?, 'BananaLib').should == false
end
......
......@@ -117,7 +117,7 @@ module Pod
end
it "does not lock the dependencies in update mode" do
@analyzer.update_mode = true
@analyzer.update = true
@analyzer.analyze
@analyzer.send(:locked_dependencies).map(&:to_s).should == []
end
......
......@@ -113,8 +113,8 @@ module Pod
end
it "configures the analyzer to use update mode if appropriate" do
@installer.update_mode = true
Installer::Analyzer.any_instance.expects(:update_mode=).with(true)
@installer.update = true
Installer::Analyzer.any_instance.expects(:update=).with(true)
@installer.send(:analyze)
@installer.aggregate_targets.map(&:name).sort.should == ['Pods']
@installer.pod_targets.map(&:name).sort.should == ['Pods-JSONKit']
......
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