Commit 50250b16 authored by Fabio Pelosin's avatar Fabio Pelosin

[Installer] Implement migrator

parent de011ef4
...@@ -87,7 +87,7 @@ module Pod ...@@ -87,7 +87,7 @@ module Pod
# @return [void] # @return [void]
# #
def install! def install!
migrate_installation_if_needed prepare
resolve_dependencies resolve_dependencies
download_dependencies download_dependencies
generate_pods_project generate_pods_project
...@@ -95,10 +95,10 @@ module Pod ...@@ -95,10 +95,10 @@ module Pod
perform_post_install_actions perform_post_install_actions
end end
def migrate_installation_if_needed def prepare
UI.section "Performing existing installation migration" do UI.section "Preparing" do
migrator = Migrator.new(sandbox) sandbox.prepare
migrator.migrate! Migrator.migrate(sandbox)
end end
end end
......
require 'fileutils'
module Pod module Pod
class Installer class Installer
# Migrates installations performed by previous versions of CocoaPods. # Migrates installations performed by previous versions of CocoaPods.
# #
class Migrator class Migrator
class << self
# # Performs the migration.
# #
attr_reader :installation_version # @param [Sandbox] The sandbox which should be migrated.
#
# def migrate(sandbox)
# if sandbox.manifest
attr_reader :sandbox migrate_to_0_34(sandbox) if installation_minor?('0.34', sandbox)
end
#
#
def initialize(sandbox)
@sandbox = sandbox
end
#
#
def migrate!
if sandbox.manifest
migrate_to_0_20 if version_minor('0.20')
end end
end
#-----------------------------------------------------------------------#
private
# @!group Migration Steps # @!group Migration Steps
# TODO: Fix copy resources script # Migrates from CocoaPods versions previous to 0.34.
# TODO: Fix manifest check #
# TODO: Fix xcconfig def migrate_to_0_34(sandbox)
# TODO: Group target support files title_options = { :verbose_prefix => "-> ".green }
# UI.titled_section("Migrating to CocoaPods 0.34".green, title_options) do
def migrate_to_0_20 delete(sandbox.root + 'Headers')
title_options = { :verbose_prefix => "-> ".green } make_path(sandbox.headers_root)
UI.titled_section("Migrating to CocoaPods 0.20".green, title_options) do
mkdir(sandbox.generated_dir_root) sandbox.root.children.each do |child|
mkdir(sandbox.headers_root) relative = child.relative_path_from(sandbox.root)
mkdir(sandbox.sources_root) case relative.to_s
sandbox.root.children.each do |child| when 'Manifest.lock', 'Pods.xcodeproj', 'Sources', 'Headers',
relative = child.relative_path_from(sandbox.root) 'Target Support Files', 'Local Podspecs'
case relative.to_s next
when 'Generated' when 'BuildHeaders', 'PublicHeaders'
next delete(child)
when 'BuildHeaders', 'Headers'
move(child, sandbox.headers_root + relative)
else
if child.directory? && child.extname != '.xcodeproj'
move(child, sandbox.sources_root + relative)
else else
move(child, sandbox.generated_dir_root + relative) if child.directory? && child.extname != '.xcodeproj'
move(child, sandbox.sources_root + relative)
else
delete(child)
end
end end
end end
end end
end end
end
#-----------------------------------------------------------------------# # @!group Private helpers
private def installation_minor?(target_version, sandbox)
sandbox.manifest.cocoapods_version < Version.new(target_version)
# @!group Private helpers end
def version_minor(target_version)
installation_version < Version.new(target_version)
end
def installation_version # Makes a path creating any intermediate directory and printing an UI
sandbox.manifest.cocoapods_version # message.
end #
# @path [#to_s] path
# The path.
#
def make_path(path)
return if path.exist?
UI.message "- Making path #{UI.path(path)}" do
path.mkpath
end
end
def mkdir(path) # Moves a path to another one printing an UI message.
path.mkpath #
end # @path [#to_s] source
# The path to move.
#
# @path [#to_s] destination
# The destination path.
#
def move(source, destination)
return unless source.exist?
make_path(destination.dirname)
UI.message "- Moving #{UI.path(source)} to #{UI.path(destination)}" do
FileUtils.mv(source.to_s, destination.to_s)
end
end
def move(path, new_name) # Deletes a path, including non empty directories, printing an UI
path.rename(new_name) # message.
#
# @path [#to_s] path
# The path.
#
def delete(path)
return unless path.exist?
UI.message "- Deleting #{UI.path(path)}" do
FileUtils.rm_rf(path)
end
end
end end
#-----------------------------------------------------------------------#
end end
end end
end end
...@@ -77,8 +77,8 @@ module Pod ...@@ -77,8 +77,8 @@ module Pod
native_targets_to_integrate.each do |native_target| native_targets_to_integrate.each do |native_target|
phase = native_target.shell_script_build_phases.select { |bp| bp.name == phase_name }.first || phase = native_target.shell_script_build_phases.select { |bp| bp.name == phase_name }.first ||
native_target.new_shell_script_build_phase(phase_name) native_target.new_shell_script_build_phase(phase_name)
path = target.copy_resources_script_relative_path script_path = target.copy_resources_script_relative_path
phase.shell_script = %( "#{path}"\n ) phase.shell_script = %("#{script_path}"\n)
phase.show_env_vars_in_log = '0' phase.show_env_vars_in_log = '0'
end end
end end
......
...@@ -41,14 +41,20 @@ module Pod ...@@ -41,14 +41,20 @@ module Pod
# @todo This can be removed for CocoaPods 1.0 # @todo This can be removed for CocoaPods 1.0
# #
def self.update_from_cocoapods_0_33_1(pod_bundle, targets) def self.update_from_cocoapods_0_33_1(pod_bundle, targets)
sandbox = pod_bundle.sandbox
targets.map(&:project).uniq.each do |project| targets.map(&:project).uniq.each do |project|
path = pod_bundle.xcconfig_relative_path(nil) file_refs = project.files.select do |file_ref|
file_ref = project.files.find { |f| f.path == path } path = file_ref.path.to_s
if file_ref if File.extname(path) == '.xcconfig'
UI.message "- Removing (#{path})" do absolute_path = file_ref.real_path.to_s
absolute_path.start_with?(sandbox.root.to_s) &&
!absolute_path.start_with?(sandbox.target_support_files_root.to_s)
end
end
file_refs.uniq.each do |file_ref|
UI.message "- Removing (#{file_ref.path})" do
file_ref.remove_from_project file_ref.remove_from_project
absolute_path = pod_bundle.xcconfig_path
File.delete(absolute_path) if File.exist?(absolute_path)
end end
end end
end end
......
...@@ -60,9 +60,6 @@ module Pod ...@@ -60,9 +60,6 @@ module Pod
@checkout_sources = {} @checkout_sources = {}
@development_pods = {} @development_pods = {}
@pods_with_absolute_path = [] @pods_with_absolute_path = []
FileUtils.mkdir_p(headers_root)
FileUtils.mkdir_p(sources_root)
FileUtils.mkdir_p(target_support_files_root)
end end
# @return [Lockfile] the manifest which contains the information about the # @return [Lockfile] the manifest which contains the information about the
...@@ -90,6 +87,19 @@ module Pod ...@@ -90,6 +87,19 @@ module Pod
podspe_path.rmtree if podspe_path podspe_path.rmtree if podspe_path
end end
# Prepares the sandbox for a new installation removing any file that will
# be regenerated and ensuring that the directories exists.
#
def prepare
FileUtils.rm_rf(headers_root)
FileUtils.rm_rf(target_support_files_root)
FileUtils.mkdir_p(headers_root)
FileUtils.mkdir_p(sources_root)
FileUtils.mkdir_p(specifications_root)
FileUtils.mkdir_p(target_support_files_root)
end
# @return [String] a string representation suitable for debugging. # @return [String] a string representation suitable for debugging.
# #
def inspect def inspect
...@@ -166,6 +176,13 @@ module Pod ...@@ -166,6 +176,13 @@ module Pod
root + 'Sources' root + 'Sources'
end end
# @return [Pathname] the path for the directory where to store the
# specifications.
#
def specifications_root
root + "Local Podspecs"
end
# @return [Pathname] The directory where to store the files generated by # @return [Pathname] The directory where to store the files generated by
# CocoaPods to support the umbrella targets. # CocoaPods to support the umbrella targets.
# #
...@@ -193,15 +210,7 @@ module Pod ...@@ -193,15 +210,7 @@ module Pod
end end
end end
# @return [Pathname] the path for the directory where to store the
# specifications.
#
# @todo Migrate old installations and store the for all the pods.
# Two folders should be created `External Sources` and `Podspecs`.
#
def specifications_dir(_external_source = false)
root + "Local Podspecs"
end
# Returns the path of the specification for the Pod with the # Returns the path of the specification for the Pod with the
# given name, if one is stored. # given name, if one is stored.
...@@ -213,11 +222,11 @@ module Pod ...@@ -213,11 +222,11 @@ module Pod
# @return [Nil] if the podspec is not stored. # @return [Nil] if the podspec is not stored.
# #
def specification_path(name) def specification_path(name)
path = specifications_dir + "#{name}.podspec" path = specifications_root + "#{name}.podspec"
if path.exist? if path.exist?
path path
else else
path = specifications_dir + "#{name}.podspec.json" path = specifications_root + "#{name}.podspec.json"
if path.exist? if path.exist?
path path
else else
...@@ -240,7 +249,7 @@ module Pod ...@@ -240,7 +249,7 @@ module Pod
# #
def store_podspec(name, podspec, external_source = false, json = false) def store_podspec(name, podspec, external_source = false, json = false)
file_name = json ? "#{name}.podspec.json" : "#{name}.podspec" file_name = json ? "#{name}.podspec.json" : "#{name}.podspec"
output_path = specifications_dir(external_source) + file_name output_path = specifications_root + file_name
output_path.dirname.mkpath output_path.dirname.mkpath
if podspec.is_a?(String) if podspec.is_a?(String)
output_path.open('w') { |f| f.puts(podspec) } output_path.open('w') { |f| f.puts(podspec) }
......
...@@ -6,6 +6,7 @@ module Pod ...@@ -6,6 +6,7 @@ module Pod
before do before do
dependency = Dependency.new('Reachability', :git => fixture('integration/Reachability')) dependency = Dependency.new('Reachability', :git => fixture('integration/Reachability'))
@subject = ExternalSources.from_dependency(dependency, nil) @subject = ExternalSources.from_dependency(dependency, nil)
config.sandbox.prepare
end end
#--------------------------------------# #--------------------------------------#
...@@ -36,7 +37,7 @@ module Pod ...@@ -36,7 +37,7 @@ module Pod
it 'pre-downloads the Pod and stores the relevant information in the sandbox' do it 'pre-downloads the Pod and stores the relevant information in the sandbox' do
@subject.send(:pre_download, config.sandbox) @subject.send(:pre_download, config.sandbox)
path = config.sandbox.specifications_dir + 'Reachability.podspec' path = config.sandbox.specifications_root + 'Reachability.podspec'
path.should.exist? path.should.exist?
config.sandbox.predownloaded_pods.should == ['Reachability'] config.sandbox.predownloaded_pods.should == ['Reachability']
config.sandbox.checkout_sources.should == { config.sandbox.checkout_sources.should == {
......
...@@ -13,7 +13,7 @@ module Pod ...@@ -13,7 +13,7 @@ module Pod
it 'creates a copy of the podspec' do it 'creates a copy of the podspec' do
@subject.fetch(config.sandbox) @subject.fetch(config.sandbox)
path = config.sandbox.specifications_dir + 'Reachability.podspec' path = config.sandbox.specifications_root + 'Reachability.podspec'
path.should.exist? path.should.exist?
end end
......
...@@ -12,7 +12,7 @@ module Pod ...@@ -12,7 +12,7 @@ module Pod
it "creates a copy of the podspec" do it "creates a copy of the podspec" do
@subject.fetch(config.sandbox) @subject.fetch(config.sandbox)
path = config.sandbox.specifications_dir + 'Reachability.podspec' path = config.sandbox.specifications_root + 'Reachability.podspec'
path.should.exist? path.should.exist?
end end
...@@ -22,7 +22,7 @@ module Pod ...@@ -22,7 +22,7 @@ module Pod
podfile_path = fixture('integration/Podfile') podfile_path = fixture('integration/Podfile')
@subject = ExternalSources.from_dependency(dependency, podfile_path) @subject = ExternalSources.from_dependency(dependency, podfile_path)
@subject.fetch(config.sandbox) @subject.fetch(config.sandbox)
path = config.sandbox.specifications_dir + 'Reachability.podspec' path = config.sandbox.specifications_root + 'Reachability.podspec'
path.should.exist? path.should.exist?
end end
......
...@@ -12,7 +12,7 @@ module Pod ...@@ -12,7 +12,7 @@ module Pod
it "creates a copy of the podspec" do it "creates a copy of the podspec" do
@subject.fetch(config.sandbox) @subject.fetch(config.sandbox)
path = config.sandbox.specifications_dir + 'Reachability.podspec' path = config.sandbox.specifications_root + 'Reachability.podspec'
path.should.exist? path.should.exist?
end end
......
require File.expand_path('../../../spec_helper', __FILE__)
module Pod
describe Installer::Migrator do
it 'performs a migration' do
manifest = stub(:cocoapods_version => Version.new('0.32'))
config.sandbox.stubs(:manifest).returns(manifest)
old_path = config.sandbox.root + 'ARAnalytics'
old_path.mkdir
Installer::Migrator.migrate(config.sandbox)
old_path.should.not.exist?
(config.sandbox.sources_root + 'ARAnalytics').should.exist?
end
it "doesn't perform migrations if they are not needed" do
manifest = stub(:cocoapods_version => Version.new('999'))
config.sandbox.stubs(:manifest).returns(manifest)
Installer::Migrator.expects(:migrate_to_0_34).never
Installer::Migrator.migrate(config.sandbox)
end
end
end
...@@ -4,6 +4,7 @@ module Pod ...@@ -4,6 +4,7 @@ module Pod
describe Installer::AggregateTargetInstaller do describe Installer::AggregateTargetInstaller do
describe 'In General' do describe 'In General' do
before do before do
config.sandbox.prepare
@podfile = Podfile.new do @podfile = Podfile.new do
platform :ios platform :ios
xcodeproj 'dummy' xcodeproj 'dummy'
......
...@@ -4,6 +4,7 @@ module Pod ...@@ -4,6 +4,7 @@ module Pod
describe Installer::PodTargetInstaller do describe Installer::PodTargetInstaller do
describe 'In General' do describe 'In General' do
before do before do
config.sandbox.prepare
@podfile = Podfile.new do @podfile = Podfile.new do
platform :ios platform :ios
xcodeproj 'dummy' xcodeproj 'dummy'
......
...@@ -28,8 +28,6 @@ module Pod ...@@ -28,8 +28,6 @@ module Pod
file_ref = @project.new_file(path) file_ref = @project.new_file(path)
config = @target.build_configuration_list['Release'] config = @target.build_configuration_list['Release']
config.base_configuration_reference = file_ref config.base_configuration_reference = file_ref
File.expects(:exist?).returns(true)
File.expects(:delete).with(path)
XCConfigIntegrator.integrate(@pod_bundle, [@target]) XCConfigIntegrator.integrate(@pod_bundle, [@target])
@project.files.find { |f| f.path == path }.should.be.nil @project.files.find { |f| f.path == path }.should.be.nil
end end
......
...@@ -94,8 +94,8 @@ module Pod ...@@ -94,8 +94,8 @@ module Pod
describe 'Specification store' do describe 'Specification store' do
it 'loads the stored specification with the given name' do it 'loads the stored specification with the given name' do
(@sandbox.specifications_dir).mkdir (@sandbox.specifications_root).mkdir
FileUtils.cp(fixture('banana-lib/BananaLib.podspec'), @sandbox.specifications_dir) FileUtils.cp(fixture('banana-lib/BananaLib.podspec'), @sandbox.specifications_root)
@sandbox.specification('BananaLib').name.should == 'BananaLib' @sandbox.specification('BananaLib').name.should == 'BananaLib'
end end
...@@ -112,7 +112,7 @@ module Pod ...@@ -112,7 +112,7 @@ module Pod
end end
it 'returns the directory where to store the specifications' do it 'returns the directory where to store the specifications' do
@sandbox.specifications_dir.should == temporary_directory + 'Sandbox/Local Podspecs' @sandbox.specifications_root.should == temporary_directory + 'Sandbox/Local Podspecs'
end end
it "returns the path to a spec file in the 'Local Podspecs' dir" do it "returns the path to a spec file in the 'Local Podspecs' dir" do
......
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