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

[Git] Code clean up.

parent 3e0ea475
require 'open-uri' require 'open-uri'
require 'tempfile' # require 'tempfile'
require 'zlib' require 'zlib'
require 'digest/sha1' require 'digest/sha1'
module Pod module Pod
class Downloader class Downloader
# Concreted Downloader class that provides support for specifications with
# git sources.
#
class Git < Downloader class Git < Downloader
include Config::Mixin include Config::Mixin
executable :git executable :git
MAX_CACHE_SIZE = 500
def download def download
create_cache unless cache_exist? create_cache unless cache_exist?
UI.section(' > Cloning git repo', '', 1) do UI.section(' > Cloning git repo', '', 1) do
...@@ -29,137 +31,207 @@ module Pod ...@@ -29,137 +31,207 @@ module Pod
prune_cache prune_cache
end 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 # @!group Download implementations
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 # @return [Pathname] The clone URL, which resolves to the cache path.
@cache_path ||= caches_dir + "#{Digest::SHA1.hexdigest(url.to_s)}" #
def clone_url
cache_path
end end
def cache_exist? # @return [void] Convenience method to perform clones operations.
cache_path.exist? && origin_url(cache_path).to_s == url.to_s #
def clone(from, to)
UI.section(" > Cloning to Pods folder",'',1) do
git! %Q|clone "#{from}" "#{to}"|
end end
def origin_url(dir)
Dir.chdir(dir) { `git config remote.origin.url`.chomp }
end end
def caches_dir # @return [void] Checkouts the HEAD of the git source in the destination
Pathname.new(File.expand_path("~/Library/Caches/CocoaPods/Git")) # path.
#
def download_head
if cache_exist?
update_cache
else
create_cache
end end
def clone_url clone(clone_url, target_path)
cache_path Dir.chdir(target_path) { git! "submodule update --init" } if options[:submodules]
end end
def caches_size # @return [void] Checkouts a specific tag of the git source in the
# expressed in Mb # destination path.
`du -cm`.split("\n").last.to_i #
def download_tag
ensure_ref_exists(options[:tag])
Dir.chdir(target_path) do
git! "init"
git! "remote add origin '#{clone_url}'"
git! "fetch origin tags/#{options[:tag]}"
git! "reset --hard FETCH_HEAD"
git! "checkout -b activated-pod-commit"
end
end end
def update_cache # @return [void] Checkouts a specific commit of the git source in the
UI.section(" > Updating cache git repo (#{cache_path})",'',1) do # destination path.
Dir.chdir(cache_path) do #
if git("config core.bare").chomp == "true" def download_commit
git! "remote update" ensure_ref_exists(options[:commit])
else clone(clone_url, target_path)
git! "reset --hard HEAD" Dir.chdir(target_path) do
git! "clean -d -x -f" git! "checkout -b activated-pod-commit #{options[:commit]}"
git! "pull origin master"
git! "fetch --tags"
end end
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)
Dir.chdir(target_path) do
git! "remote add upstream '#{@url}'" # we need to add the original url, not the cache url
git! "fetch -q upstream" # refresh the branches
git! "checkout --track -b activated-pod-commit upstream/#{options[:branch]}" # create a new tracking branch
UI.message("Just downloaded and checked out branch: #{options[:branch]} from upstream #{clone_url}")
end end
end end
# @!group Checking references
# @return [Bool] Wether a reference (SHA of tag)
#
def ref_exists?(ref) def ref_exists?(ref)
Dir.chdir(cache_path) { git "rev-list --max-count=1 #{ref}" } Dir.chdir(cache_path) { git "rev-list --max-count=1 #{ref}" }
$? == 0 $? == 0
end 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) def ensure_ref_exists(ref)
return if ref_exists?(ref) return if ref_exists?(ref)
# Skip pull if not needed
update_cache update_cache
raise Informative, "[!] Cache unable to find git reference `#{ref}' for `#{url}'.".red unless ref_exists?(ref) raise Informative, "[!] Cache unable to find git reference `#{ref}' for `#{url}'.".red unless ref_exists?(ref)
end end
# @return [Bool] Wether a branch exists in the cache.
#
def branch_exists?(branch) def branch_exists?(branch)
Dir.chdir(cache_path) { git "branch --all | grep #{branch}$" } # check for remote branch and do suffix matching ($ anchor) Dir.chdir(cache_path) { git "branch --all | grep #{branch}$" } # check for remote branch and do suffix matching ($ anchor)
$? == 0 $? == 0
end 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) def ensure_remote_branch_exists(branch)
return if branch_exists?(branch) return if branch_exists?(branch)
update_cache update_cache
raise Informative, "[!] Cache unable to find git reference `#{branch}' for `#{url}' (#{$?}).".red unless branch_exists?(branch) raise Informative, "[!] Cache unable to find git reference `#{branch}' for `#{url}' (#{$?}).".red unless branch_exists?(branch)
end end
def download_head
if cache_exist? # @!group Cache
update_cache
else # The maximum allowed size for the cache expressed in Mb.
create_cache #
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 end
clone(clone_url, target_path) # @return [Pathname] The directory where the git caches are stored.
Dir.chdir(target_path) { git! "submodule update --init" } if options[:submodules] #
def caches_root
Pathname.new(File.expand_path("~/Library/Caches/CocoaPods/Git"))
end end
def download_tag # @return [Integer] The global size of the git cache expressed in Mb.
ensure_ref_exists(options[:tag]) #
Dir.chdir(target_path) do def caches_size
git! "init" `du -cm`.split("\n").last.to_i
git! "remote add origin '#{clone_url}'"
git! "fetch origin tags/#{options[:tag]}"
git! "reset --hard FETCH_HEAD"
git! "checkout -b activated-pod-commit"
end end
# @return [Bool] Wether the cache exits.
#
def cache_exist?
cache_path.exist? && cache_origin_url(cache_path).to_s == url.to_s
end end
def download_commit # @return [String] The origin URL of the cache with the given directory.
ensure_ref_exists(options[:commit]) #
clone(clone_url, target_path) # @param [String] dir The directory of the cache.
Dir.chdir(target_path) do #
git! "checkout -b activated-pod-commit #{options[:commit]}" 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
end end
def download_branch # @return [void] Updates the barebone repo used as a cache against its
ensure_remote_branch_exists(options[:branch]) # remote.
clone(clone_url, target_path) #
Dir.chdir(target_path) do def update_cache
git! "remote add upstream '#{@url}'" # we need to add the original url, not the cache url UI.section(" > Updating cache git repo (#{cache_path})",'',1) do
git! "fetch -q upstream" # refresh the branches Dir.chdir(cache_path) do
git! "checkout --track -b activated-pod-commit upstream/#{options[:branch]}" # create a new tracking branch if git("config core.bare").chomp == "true"
UI.message("Just downloaded and checked out branch: #{options[:branch]} from upstream #{clone_url}") git! "remote update"
else
git! "reset --hard HEAD"
git! "clean -d -x -f"
git! "pull origin master"
git! "fetch --tags"
end
end
end end
end end
def clone(from, to) # @return [void] Deletes the oldest caches until they the global size is
UI.section(" > Cloning to Pods folder",'',1) do # below the maximum allowed.
git! %Q|clone "#{from}" "#{to}"| #
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 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 class GitHub < Git
def download_head def download_head
download_only? ? download_and_extract_tarball('master') : super 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