Commit 62d84717 authored by Fabio Pelosin's avatar Fabio Pelosin

[Git] Code clean up.

parent 3e0ea475
require 'open-uri'
require 'tempfile'
# require 'tempfile'
require 'zlib'
require 'digest/sha1'
module Pod
class Downloader
# Concreted Downloader class that provides support for specifications with
# git sources.
#
class Git < Downloader
include Config::Mixin
executable :git
MAX_CACHE_SIZE = 500
def download
create_cache unless cache_exist?
UI.section(' > Cloning git repo', '', 1) do
......@@ -29,89 +31,26 @@ module Pod
prune_cache
end
def create_cache
UI.section(" > Creating cache git repo (#{cache_path})",'',1) do
cache_path.rmtree if cache_path.exist?
cache_path.mkpath
git! %Q|clone --mirror "#{url}" "#{cache_path}"|
end
end
def prune_cache
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 >= MAX_CACHE_SIZE && !repos.empty?
dir = repos.shift
UI.message "#{'->'.yellow} Removing git cache for `#{origin_url(dir)}'"
dir.rmtree
end
end
end
def cache_path
@cache_path ||= caches_dir + "#{Digest::SHA1.hexdigest(url.to_s)}"
end
def cache_exist?
cache_path.exist? && origin_url(cache_path).to_s == url.to_s
end
def origin_url(dir)
Dir.chdir(dir) { `git config remote.origin.url`.chomp }
end
def caches_dir
Pathname.new(File.expand_path("~/Library/Caches/CocoaPods/Git"))
end
# @!group Download implementations
# @return [Pathname] The clone URL, which resolves to the cache path.
#
def clone_url
cache_path
end
def caches_size
# expressed in Mb
`du -cm`.split("\n").last.to_i
end
def update_cache
UI.section(" > Updating cache git repo (#{cache_path})",'',1) do
Dir.chdir(cache_path) do
if git("config core.bare").chomp == "true"
git! "remote update"
else
git! "reset --hard HEAD"
git! "clean -d -x -f"
git! "pull origin master"
git! "fetch --tags"
end
end
# @return [void] Convenience method to perform clones operations.
#
def clone(from, to)
UI.section(" > Cloning to Pods folder",'',1) do
git! %Q|clone "#{from}" "#{to}"|
end
end
def ref_exists?(ref)
Dir.chdir(cache_path) { git "rev-list --max-count=1 #{ref}" }
$? == 0
end
def ensure_ref_exists(ref)
return if ref_exists?(ref)
# Skip pull if not needed
update_cache
raise Informative, "[!] Cache unable to find git reference `#{ref}' for `#{url}'.".red unless ref_exists?(ref)
end
def branch_exists?(branch)
Dir.chdir(cache_path) { git "branch --all | grep #{branch}$" } # check for remote branch and do suffix matching ($ anchor)
$? == 0
end
def ensure_remote_branch_exists(branch)
return if branch_exists?(branch)
update_cache
raise Informative, "[!] Cache unable to find git reference `#{branch}' for `#{url}' (#{$?}).".red unless branch_exists?(branch)
end
# @return [void] Checkouts the HEAD of the git source in the destination
# path.
#
def download_head
if cache_exist?
update_cache
......@@ -123,6 +62,9 @@ module Pod
Dir.chdir(target_path) { git! "submodule update --init" } if options[:submodules]
end
# @return [void] Checkouts a specific tag of the git source in the
# destination path.
#
def download_tag
ensure_ref_exists(options[:tag])
Dir.chdir(target_path) do
......@@ -134,6 +76,9 @@ module Pod
end
end
# @return [void] Checkouts a specific commit of the git source in the
# destination path.
#
def download_commit
ensure_ref_exists(options[:commit])
clone(clone_url, target_path)
......@@ -142,6 +87,9 @@ module Pod
end
end
# @return [void] Checkouts the HEAD of a specific branch of the git
# source in the destination path.
#
def download_branch
ensure_remote_branch_exists(options[:branch])
clone(clone_url, target_path)
......@@ -153,13 +101,137 @@ module Pod
end
end
def clone(from, to)
UI.section(" > Cloning to Pods folder",'',1) do
git! %Q|clone "#{from}" "#{to}"|
# @!group Checking references
# @return [Bool] Wether a reference (SHA of tag)
#
def ref_exists?(ref)
Dir.chdir(cache_path) { git "rev-list --max-count=1 #{ref}" }
$? == 0
end
# @return [void] Checks if a reference exists in the cache and updates
# only if necessary.
#
# @raises if after the update the reference can't be found.
#
def ensure_ref_exists(ref)
return if ref_exists?(ref)
update_cache
raise Informative, "[!] Cache unable to find git reference `#{ref}' for `#{url}'.".red unless ref_exists?(ref)
end
# @return [Bool] Wether a branch exists in the cache.
#
def branch_exists?(branch)
Dir.chdir(cache_path) { git "branch --all | grep #{branch}$" } # check for remote branch and do suffix matching ($ anchor)
$? == 0
end
# @return [void] Checks if a branch exists in the cache and updates
# only if necessary.
#
# @raises if after the update the branch can't be found.
#
def ensure_remote_branch_exists(branch)
return if branch_exists?(branch)
update_cache
raise Informative, "[!] Cache unable to find git reference `#{branch}' for `#{url}' (#{$?}).".red unless branch_exists?(branch)
end
# @!group Cache
# The maximum allowed size for the cache expressed in Mb.
#
MAX_CACHE_SIZE = 500
# @return [Pathname] The directory where the cache for the current git
# repo is stored.
#
# @note The name of the directory is the SHA1 hash value of the URL of
# the git repo.
#
def cache_path
@cache_path ||= caches_root + "#{Digest::SHA1.hexdigest(url.to_s)}"
end
# @return [Pathname] The directory where the git caches are stored.
#
def caches_root
Pathname.new(File.expand_path("~/Library/Caches/CocoaPods/Git"))
end
# @return [Integer] The global size of the git cache expressed in Mb.
#
def caches_size
`du -cm`.split("\n").last.to_i
end
# @return [Bool] Wether the cache exits.
#
def cache_exist?
cache_path.exist? && cache_origin_url(cache_path).to_s == url.to_s
end
# @return [String] The origin URL of the cache with the given directory.
#
# @param [String] dir The directory of the cache.
#
def cache_origin_url(dir)
Dir.chdir(dir) { `git config remote.origin.url`.chomp }
end
# @return [void] Creates the barebone repo that will serve as the cache
# for the current repo.
#
def create_cache
UI.section(" > Creating cache git repo (#{cache_path})",'',1) do
cache_path.rmtree if cache_path.exist?
cache_path.mkpath
git! %Q|clone --mirror "#{url}" "#{cache_path}"|
end
end
# @return [void] Updates the barebone repo used as a cache against its
# remote.
#
def update_cache
UI.section(" > Updating cache git repo (#{cache_path})",'',1) do
Dir.chdir(cache_path) do
if git("config core.bare").chomp == "true"
git! "remote update"
else
git! "reset --hard HEAD"
git! "clean -d -x -f"
git! "pull origin master"
git! "fetch --tags"
end
end
end
end
# @return [void] Deletes the oldest caches until they the global size is
# below the maximum allowed.
#
def prune_cache
return unless caches_root.exist?
Dir.chdir(caches_root) do
repos = Pathname.new(caches_root).children.select { |c| c.directory? }.sort_by(&:ctime)
while caches_size >= MAX_CACHE_SIZE && !repos.empty?
dir = repos.shift
UI.message "#{'->'.yellow} Removing git cache for `#{cache_origin_url(dir)}'"
dir.rmtree
end
end
end
end
# This class allows to download tarballs from GitHub and is not currently
# being used by CocoaPods as the git cache is preferable.
#
class GitHub < Git
def download_head
download_only? ? download_and_extract_tarball('master') : super
......
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