Commit 0d4dd44b authored by Fabio Pelosin's avatar Fabio Pelosin

Merge pull request #248 from CocoaPods/git-cache

[Downloader::Git] Cache repos
parents 81d3550d cfbdef54
......@@ -14,6 +14,7 @@ module Pod
attr_accessor :clean, :verbose, :silent
attr_accessor :generate_docs, :doc_install, :force_doc
attr_accessor :integrate_targets
attr_accessor :git_cache_size
alias_method :clean?, :clean
alias_method :verbose?, :verbose
......@@ -27,6 +28,7 @@ module Pod
@repos_dir = Pathname.new(File.expand_path("~/.cocoapods"))
@verbose = @silent = @force_doc = false
@clean = @generate_docs = @doc_install = @integrate_targets = true
@git_cache_size = 500
end
def project_root
......
......@@ -26,9 +26,9 @@ module Pod
def clean
# implement in sub-classes
end
private
def self.for_target(target_path, options)
options = options.dup
if url = options.delete(:git)
......
require 'open-uri'
require 'tempfile'
require 'zlib'
require 'digest/sha1'
module Pod
class Downloader
class Git < Downloader
include Config::Mixin
executable :git
def download
prepare_cache
puts '->'.green << ' Cloning git repo' if config.verbose?
if options[:tag]
download_tag
elsif options[:commit]
......@@ -15,16 +19,72 @@ module Pod
else
download_head
end
removed_cached_repos_if_needed
end
def prepare_cache
return if config.git_cache_size == 0
if is_cache_valid?
puts '->'.green << " Updating cache git repo (#{cache_path})" if config.verbose?
Dir.chdir(cache_path) do
git "reset --hard HEAD"
git "clean -d -x -f"
git "pull"
end
else
puts '->'.green << " Creating cache git repo (#{cache_path})" if config.verbose?
cache_path.rmtree if cache_path.exist?
cache_path.mkpath
git "clone '#{url}' #{cache_path}"
end
end
def removed_cached_repos_if_needed
return unless caches_dir.exist?
Dir.chdir(caches_dir) do
repos = Pathname.new(caches_dir).children.select { |c| c.directory? }.sort_by(&:ctime)
while caches_size >= config.git_cache_size && !repos.empty?
dir = repos.shift
puts '->'.yellow << " Removing git cache for `#{origin_url(dir)}'" if config.verbose?
dir.rmtree
end
end
end
def cache_path
@cache_path ||= caches_dir + "#{Digest::SHA1.hexdigest(url.to_s)}"
end
def is_cache_valid?
cache_path.exist? && origin_url(cache_path) == url
end
def origin_url(dir)
Dir.chdir(dir) { `git config remote.origin.url`.chomp }
end
def caches_dir
Pathname.new "/var/tmp/CocoaPods/Git"
end
def clone_url
# git_cache_size = 0 disables the cache
config.git_cache_size == 0 ? url : cache_path
end
def caches_size
# expressed in Mb
`du -cm`.split("\n").last.to_i
end
def download_head
git "clone '#{url}' '#{target_path}'"
git "clone '#{clone_url}' '#{target_path}'"
end
def download_tag
Dir.chdir(target_path) do
git "init"
git "remote add origin '#{url}'"
git "remote add origin '#{clone_url}'"
git "fetch origin tags/#{options[:tag]}"
git "reset --hard FETCH_HEAD"
git "checkout -b activated-pod-commit"
......@@ -32,7 +92,7 @@ module Pod
end
def download_commit
git "clone '#{url}' '#{target_path}'"
git "clone '#{clone_url}' '#{target_path}'"
Dir.chdir(target_path) do
git "checkout -b activated-pod-commit #{options[:commit]}"
......@@ -71,7 +131,7 @@ module Pod
original_url, username, reponame = *(url.match(/[:\/]([\w\-]+)\/([\w\-]+)\.git/).to_a)
"https://github.com/#{username}/#{reponame}/tarball/#{id}"
end
def tmp_path
target_path + "tarball.tar.gz"
end
......
......@@ -53,6 +53,7 @@ end
config = Pod::Config.instance
config.silent = true
config.repos_dir = SpecHelper.tmp_repos_path
config.git_cache_size = 0
require 'tmpdir'
......
......@@ -19,7 +19,7 @@ describe "Pod::Downloader" do
downloader.url.should == 'http://banana-corp.local/banana-lib.git'
downloader.options.should == { :tag => 'v1.0' }
end
it 'returns a github downloader when the :git URL is on github' do
pod = Pod::LocalPod.new(fixture_spec('banana-lib/BananaLib.podspec'), temporary_sandbox, Pod::Platform.ios)
pod.specification.stubs(:source).returns(:git => "git://github.com/CocoaPods/CocoaPods")
......@@ -36,21 +36,21 @@ describe Pod::Downloader::GitHub do
))
downloader.tarball_url_for('master').should == "https://github.com/CocoaPods/CocoaPods/tarball/master"
end
it 'can convert private HTTP repository URLs to the tarball URL' do
downloader = Pod::Downloader.for_pod(stub_pod_with_source(
:git => "https://lukeredpath@github.com/CocoaPods/CocoaPods.git"
))
downloader.tarball_url_for('master').should == "https://github.com/CocoaPods/CocoaPods/tarball/master"
end
it 'can convert private SSH repository URLs to the tarball URL' do
downloader = Pod::Downloader.for_pod(stub_pod_with_source(
:git => "git@github.com:CocoaPods/CocoaPods.git"
))
downloader.tarball_url_for('master').should == "https://github.com/CocoaPods/CocoaPods/tarball/master"
end
it 'can convert public git protocol repository URLs to the tarball URL' do
downloader = Pod::Downloader.for_pod(stub_pod_with_source(
:git => "git://github.com/CocoaPods/CocoaPods.git"
......
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