Commit d5b06cc4 authored by Fabio Pelosin's avatar Fabio Pelosin

Merge branch 'master' into xcodeproj-refactor

* master:
  Release 0.15.2
  [Bundle] Update.
  [Gemspec] Require Xcodeproj 0.3.5.
  Remove stray puts.
  Update the lockfiles of the examples.
  [Gemfile] Install and remove dependency on letters gem.
  [LocalPod] Always use Pathname::glob.
  [Gemspec] Use spermy indicator for xcodeproj.
  [Specs] Complete revert of 8e72cbe1
  Fixed a bug with the flags passed into `Dir.glob`
  Fixing a bug where `downcase` was being called on the list of used file paths
  Updated `clean_paths` and `expand_paths` methods to use `File::FNM_CASEFOLD`
  [Linter/Push] Properly singularize words in output.
  [Bundler] Update.
  [UI] Support for running CocoaPods without a terminal.
  [Git] Force a barebone repo for the cache.
  [Git] Code clean up.
  [LocalPod] Fixing clean paths

Conflicts:
	lib/cocoapods/local_pod.rb
parents b7061f76 7ea1d46c
## Master ## Master
[CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.15.1...master) [CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.15.1...master)[Xcodeproj](https://github.com/CocoaPods/Xcodeproj/compare/0.3.4...master)
###### Bug fixes ## 0.15.2
[CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.15.1...0.15.2)
###### Enhancements
- Added support for `.hh` headers. - Added support for `.hh` headers.
[#576](https://github.com/CocoaPods/CocoaPods/pull/576) [#576](https://github.com/CocoaPods/CocoaPods/pull/576)
###### Bug fixes
- Restored support for running CocoaPods without a terminal.
[#575](https://github.com/CocoaPods/CocoaPods/issues/575)
[#577](https://github.com/CocoaPods/CocoaPods/issues/577)
- The git cache now always uses a barebones repo preventing a number of related issues.
[#581](https://github.com/CocoaPods/CocoaPods/issues/581)
[#569](https://github.com/CocoaPods/CocoaPods/issues/569)
- Improved fix for the issue that lead to empty directories for Pods.
[#572](https://github.com/CocoaPods/CocoaPods/issues/572)
[#602](https://github.com/CocoaPods/CocoaPods/issues/602)
- Xcodeproj robustness against invalid values, such as malformed UTF8.
[#592](https://github.com/CocoaPods/CocoaPods/issues/592)
## 0.15.1 ## 0.15.1
[CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.15.0...0.15.1) [CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.15.0...0.15.1)
......
...@@ -17,7 +17,6 @@ group :debugging do ...@@ -17,7 +17,6 @@ group :debugging do
gem "kicker", :git => "https://github.com/alloy/kicker.git", :branch => "3.0.0" gem "kicker", :git => "https://github.com/alloy/kicker.git", :branch => "3.0.0"
gem "awesome_print" gem "awesome_print"
gem "pry" gem "pry"
gem "letters"
end end
group :documentation do group :documentation do
......
GIT GIT
remote: git://github.com/CocoaPods/Xcodeproj.git remote: git://github.com/CocoaPods/Xcodeproj.git
revision: 5a53472bf5342b2f17632fd53fa802930776406b revision: da9a356535ec7e97c11f2d5648e2f154165c1a19
specs: specs:
xcodeproj (0.3.4) xcodeproj (0.3.5)
activesupport (~> 3.2.6) activesupport (~> 3.2.6)
GIT GIT
...@@ -17,7 +17,7 @@ GIT ...@@ -17,7 +17,7 @@ GIT
PATH PATH
remote: . remote: .
specs: specs:
cocoapods (0.15.1) cocoapods (0.15.2)
activesupport (~> 3.2.6) activesupport (~> 3.2.6)
colored (~> 1.2) colored (~> 1.2)
escape (~> 0.0.4) escape (~> 0.0.4)
...@@ -26,7 +26,7 @@ PATH ...@@ -26,7 +26,7 @@ PATH
octokit (~> 1.7) octokit (~> 1.7)
open4 (~> 1.3.0) open4 (~> 1.3.0)
rake (~> 0.9.0) rake (~> 0.9.0)
xcodeproj (>= 0.3.4) xcodeproj (~> 0.3.5)
GEM GEM
remote: http://rubygems.org/ remote: http://rubygems.org/
...@@ -37,18 +37,9 @@ GEM ...@@ -37,18 +37,9 @@ GEM
addressable (2.3.2) addressable (2.3.2)
awesome_print (1.1.0) awesome_print (1.1.0)
bacon (1.1.0) bacon (1.1.0)
coderay (1.0.7) coderay (1.0.8)
colored (1.2) colored (1.2)
colorize (0.5.8)
columnize (0.3.6)
crack (0.3.1) crack (0.3.1)
debugger (1.2.0)
columnize (>= 0.3.1)
debugger-linecache (~> 1.1.1)
debugger-ruby_core_source (~> 1.1.3)
debugger-linecache (1.1.2)
debugger-ruby_core_source (>= 1.1.1)
debugger-ruby_core_source (1.1.3)
escape (0.0.4) escape (0.0.4)
faraday (0.8.4) faraday (0.8.4)
multipart-post (~> 1.1) multipart-post (~> 1.1)
...@@ -58,22 +49,16 @@ GEM ...@@ -58,22 +49,16 @@ GEM
hashie (1.2.0) hashie (1.2.0)
i18n (0.6.1) i18n (0.6.1)
json (1.7.5) json (1.7.5)
letters (0.2.3) listen (0.5.3)
activesupport
awesome_print
colorize
debugger
xml-simple
listen (0.5.2)
metaclass (0.0.1) metaclass (0.0.1)
method_source (0.8) method_source (0.8.1)
mocha (0.11.4) mocha (0.11.4)
metaclass (~> 0.0.1) metaclass (~> 0.0.1)
mocha-on-bacon (0.2.1) mocha-on-bacon (0.2.1)
mocha (>= 0.9.8) mocha (>= 0.9.8)
multi_json (1.3.6) multi_json (1.3.6)
multipart-post (1.1.5) multipart-post (1.1.5)
octokit (1.15.1) octokit (1.18.0)
addressable (~> 2.2) addressable (~> 2.2)
faraday (~> 0.8) faraday (~> 0.8)
faraday_middleware (~> 0.8) faraday_middleware (~> 0.8)
...@@ -86,15 +71,14 @@ GEM ...@@ -86,15 +71,14 @@ GEM
slop (~> 3.3.1) slop (~> 3.3.1)
rake (0.9.2.2) rake (0.9.2.2)
rb-fsevent (0.9.2) rb-fsevent (0.9.2)
redcarpet (2.1.1) redcarpet (2.2.2)
slop (3.3.3) slop (3.3.3)
terminal-notifier (1.4.2) terminal-notifier (1.4.2)
vcr (2.2.5) vcr (2.2.5)
webmock (1.8.11) webmock (1.8.11)
addressable (>= 2.2.7) addressable (>= 2.2.7)
crack (>= 0.1.7) crack (>= 0.1.7)
xml-simple (1.1.1) yard (0.8.3)
yard (0.8.2.1)
PLATFORMS PLATFORMS
ruby ruby
...@@ -105,7 +89,6 @@ DEPENDENCIES ...@@ -105,7 +89,6 @@ DEPENDENCIES
cocoapods! cocoapods!
github-markup github-markup
kicker! kicker!
letters
mocha (~> 0.11.4) mocha (~> 0.11.4)
mocha-on-bacon mocha-on-bacon
pry pry
......
...@@ -26,7 +26,7 @@ Gem::Specification.new do |s| ...@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
s.executables = %w{ pod } s.executables = %w{ pod }
s.require_paths = %w{ lib } s.require_paths = %w{ lib }
s.add_runtime_dependency 'xcodeproj', '>= 0.3.4' s.add_runtime_dependency 'xcodeproj', '~> 0.3.5'
s.add_runtime_dependency 'faraday', '~> 0.8.1' s.add_runtime_dependency 'faraday', '~> 0.8.1'
s.add_runtime_dependency 'octokit', '~> 1.7' s.add_runtime_dependency 'octokit', '~> 1.7'
......
PODS: COCOAPODS: 0.15.1
- AFNetworking (0.7.0):
PODS:
- AFNetworking (0.7.0):
- JSONKit - JSONKit
- FormatterKit (1.0.0): - FormatterKit (1.0.0):
- FormatterKit/ArrayFormatter (= 1.0.0) - FormatterKit/ArrayFormatter (= 1.0.0)
- FormatterKit/LocationFormatter (= 1.0.0) - FormatterKit/LocationFormatter (= 1.0.0)
- FormatterKit/OrdinalNumberFormatter (= 1.0.0) - FormatterKit/OrdinalNumberFormatter (= 1.0.0)
...@@ -17,19 +19,17 @@ PODS: ...@@ -17,19 +19,17 @@ PODS:
- FormatterKit/UnitOfInformationFormatter (1.0.0) - FormatterKit/UnitOfInformationFormatter (1.0.0)
- JSONKit (1.5pre) - JSONKit (1.5pre)
DEPENDENCIES: SPEC CHECKSUMS:
- AFNetworking (~> 0.7.0) FormatterKit/UnitOfInformationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
- FormatterKit
SPEC CHECKSUMS:
AFNetworking: 1dd63e737768662b7180659e91846408df4ae7df
FormatterKit: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/ArrayFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/LocationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/OrdinalNumberFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/TimeIntervalFormatter: 12dea999a2df19e389f7b821962fc4088de8b821 FormatterKit/TimeIntervalFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
AFNetworking: 7bf22b0ed1d9068909cd67206db78204eb63dd2c
JSONKit: a01a22c75f27eae76b4badd55a91c20fe6e86477
FormatterKit/OrdinalNumberFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/LocationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/URLRequestFormatter: 12dea999a2df19e389f7b821962fc4088de8b821 FormatterKit/URLRequestFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/UnitOfInformationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821 FormatterKit/ArrayFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
JSONKit: 3d4708953ea7ae399a49777372d8b060a43ddd27 FormatterKit: 12dea999a2df19e389f7b821962fc4088de8b821
COCOAPODS: 0.13.0 DEPENDENCIES:
- AFNetworking (~> 0.7.0)
- FormatterKit
PODS: SPEC CHECKSUMS:
- AFNetworking (0.7.0): FormatterKit/UnitOfInformationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
AFNetworking: 7bf22b0ed1d9068909cd67206db78204eb63dd2c
JSONKit: a01a22c75f27eae76b4badd55a91c20fe6e86477
FormatterKit/URLRequestFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/OrdinalNumberFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/TimeIntervalFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/ArrayFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/LocationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
PODS:
- AFNetworking (0.7.0):
- JSONKit - JSONKit
- FormatterKit (1.0.0): - FormatterKit (1.0.0):
- FormatterKit/ArrayFormatter (= 1.0.0) - FormatterKit/ArrayFormatter (= 1.0.0)
- FormatterKit/LocationFormatter (= 1.0.0) - FormatterKit/LocationFormatter (= 1.0.0)
- FormatterKit/OrdinalNumberFormatter (= 1.0.0) - FormatterKit/OrdinalNumberFormatter (= 1.0.0)
...@@ -17,19 +28,8 @@ PODS: ...@@ -17,19 +28,8 @@ PODS:
- FormatterKit/UnitOfInformationFormatter (1.0.0) - FormatterKit/UnitOfInformationFormatter (1.0.0)
- JSONKit (1.5pre) - JSONKit (1.5pre)
DEPENDENCIES: COCOAPODS: 0.15.1
DEPENDENCIES:
- AFNetworking (~> 0.7.0) - AFNetworking (~> 0.7.0)
- FormatterKit - FormatterKit
SPEC CHECKSUMS:
AFNetworking: 1dd63e737768662b7180659e91846408df4ae7df
FormatterKit: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/ArrayFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/LocationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/OrdinalNumberFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/TimeIntervalFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/URLRequestFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/UnitOfInformationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
JSONKit: 3d4708953ea7ae399a49777372d8b060a43ddd27
COCOAPODS: 0.13.0
PODS: DEPENDENCIES:
- MGSplitViewController (1.0.0)
DEPENDENCIES:
- MGSplitViewController (= 1.0.0) - MGSplitViewController (= 1.0.0)
SPEC CHECKSUMS: SPEC CHECKSUMS:
MGSplitViewController: e0b0bc01aa81e1559765c39e7a764c890dac373a MGSplitViewController: e0b0bc01aa81e1559765c39e7a764c890dac373a
COCOAPODS: 0.13.0 PODS:
- MGSplitViewController (1.0.0)
COCOAPODS: 0.15.1
PODS: COCOAPODS: 0.15.1
- AFNetworking (1.0RC1)
DEPENDENCIES: DEPENDENCIES:
- AFNetworking - AFNetworking
SPEC CHECKSUMS: SPEC CHECKSUMS:
AFNetworking: b21c1252d437fd322e7db1caa93b163d76a362cb AFNetworking: b21c1252d437fd322e7db1caa93b163d76a362cb
COCOAPODS: 0.13.0 PODS:
- AFNetworking (1.0RC1)
...@@ -12,7 +12,7 @@ unless Gem::Version::Requirement.new('>= 1.4.0').satisfied_by?(Gem::Version.new( ...@@ -12,7 +12,7 @@ unless Gem::Version::Requirement.new('>= 1.4.0').satisfied_by?(Gem::Version.new(
end end
module Pod module Pod
VERSION = '0.15.1' VERSION = '0.15.2'
class PlainInformative < StandardError class PlainInformative < StandardError
end end
...@@ -57,13 +57,6 @@ module Pod ...@@ -57,13 +57,6 @@ module Pod
end end
end end
class Pathname
def glob(pattern = '')
Dir.glob((self + pattern).to_s).map { |f| Pathname.new(f) }
end
end
if ENV['COCOA_PODS_ENV'] == 'development' if ENV['COCOA_PODS_ENV'] == 'development'
require 'letters'
require 'awesome_print' require 'awesome_print'
end end
require 'fileutils' require 'fileutils'
require 'active_support/core_ext/string/inflections'
module Pod module Pod
class Command class Command
...@@ -66,12 +67,18 @@ module Pod ...@@ -66,12 +67,18 @@ module Pod
def podspec_files def podspec_files
files = Pathname.glob(@podspec || "*.podspec") files = Pathname.glob(@podspec || "*.podspec")
raise Informative, "[!] Couldn't find .podspec file in current directory".red if files.empty? raise Informative, "[!] Couldn't find any .podspec file in current directory".red if files.empty?
files files
end end
# @return [Integer] The number of the podspec files to push.
#
def count
podspec_files.count
end
def validate_podspec_files def validate_podspec_files
UI.puts "\nValidating specs".yellow unless config.silent UI.puts "\nValidating #{'spec'.pluralize(count)}".yellow unless config.silent
lint_argv = ["lint"] lint_argv = ["lint"]
lint_argv << "--only-errors" if @allow_warnings lint_argv << "--only-errors" if @allow_warnings
lint_argv << "--silent" if config.silent lint_argv << "--silent" if config.silent
...@@ -82,7 +89,7 @@ module Pod ...@@ -82,7 +89,7 @@ module Pod
end end
def add_specs_to_repo def add_specs_to_repo
UI.puts "\nAdding the specs to the #{@repo} repo\n".yellow unless config.silent UI.puts "\nAdding the #{'spec'.pluralize(count)} to the `#{@repo}' repo\n".yellow unless config.silent
podspec_files.each do |spec_file| podspec_files.each do |spec_file|
spec = Pod::Specification.from_file(spec_file) spec = Pod::Specification.from_file(spec_file)
output_path = File.join(repo_dir, spec.name, spec.version.to_s) output_path = File.join(repo_dir, spec.name, spec.version.to_s)
......
...@@ -90,7 +90,7 @@ module Pod ...@@ -90,7 +90,7 @@ module Pod
dirs.each do |dir| dirs.each do |dir|
check_versions(dir) check_versions(dir)
UI.puts "\nLinting spec repo `#{dir.realpath.basename}'\n".yellow UI.puts "\nLinting spec repo `#{dir.realpath.basename}'\n".yellow
podspecs = dir.glob('**/*.podspec') podspecs = Pathname.glob( dir + '**/*.podspec')
invalid_count = 0 invalid_count = 0
podspecs.each do |podspec| podspecs.each do |podspec|
......
# encoding: utf-8 # encoding: utf-8
require 'active_support/core_ext/string/inflections'
module Pod module Pod
class Command class Command
class Spec < Command class Spec < Command
...@@ -104,8 +106,8 @@ module Pod ...@@ -104,8 +106,8 @@ module Pod
UI.puts unless config.silent? UI.puts unless config.silent?
end end
UI.puts "Analyzed #{podspecs_to_lint.count} podspecs files.\n\n" unless config.silent?
count = podspecs_to_lint.count count = podspecs_to_lint.count
UI.puts "Analyzed #{count} #{'podspec'.pluralize(count)}.\n\n" unless config.silent?
if invalid_count == 0 if invalid_count == 0
lint_passed_message = count == 1 ? "#{podspecs_to_lint.first.basename} passed validation." : "All the specs passed validation." lint_passed_message = count == 1 ? "#{podspecs_to_lint.first.basename} passed validation." : "All the specs passed validation."
UI.puts lint_passed_message.green << "\n\n" unless config.silent? UI.puts lint_passed_message.green << "\n\n" unless config.silent?
...@@ -136,7 +138,7 @@ module Pod ...@@ -136,7 +138,7 @@ module Pod
end end
files << output_path files << output_path
else if (pathname = Pathname.new(path)).directory? else if (pathname = Pathname.new(path)).directory?
files += pathname.glob('**/*.podspec') files += Pathname.glob(pathname + '**/*.podspec')
raise Informative, "No specs found in the current directory." if files.empty? raise Informative, "No specs found in the current directory." if files.empty?
else else
files << (pathname = Pathname.new(path)) files << (pathname = Pathname.new(path))
......
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,89 +31,26 @@ module Pod ...@@ -29,89 +31,26 @@ 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
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 # @!group Download implementations
Pathname.new(File.expand_path("~/Library/Caches/CocoaPods/Git"))
end
# @return [Pathname] The clone URL, which resolves to the cache path.
#
def clone_url def clone_url
cache_path cache_path
end end
def caches_size # @return [void] Convenience method to perform clones operations.
# expressed in Mb #
`du -cm`.split("\n").last.to_i def clone(from, to)
end UI.section(" > Cloning to Pods folder",'',1) do
git! %Q|clone "#{from}" "#{to}"|
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
end end
def ref_exists?(ref) # @return [void] Checkouts the HEAD of the git source in the destination
Dir.chdir(cache_path) { git "rev-list --max-count=1 #{ref}" } # path.
$? == 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
def download_head def download_head
if cache_exist? if cache_exist?
update_cache update_cache
...@@ -123,6 +62,9 @@ module Pod ...@@ -123,6 +62,9 @@ module Pod
Dir.chdir(target_path) { git! "submodule update --init" } if options[:submodules] Dir.chdir(target_path) { git! "submodule update --init" } if options[:submodules]
end end
# @return [void] Checkouts a specific tag of the git source in the
# destination path.
#
def download_tag def download_tag
ensure_ref_exists(options[:tag]) ensure_ref_exists(options[:tag])
Dir.chdir(target_path) do Dir.chdir(target_path) do
...@@ -134,6 +76,9 @@ module Pod ...@@ -134,6 +76,9 @@ module Pod
end end
end end
# @return [void] Checkouts a specific commit of the git source in the
# destination path.
#
def download_commit def download_commit
ensure_ref_exists(options[:commit]) ensure_ref_exists(options[:commit])
clone(clone_url, target_path) clone(clone_url, target_path)
...@@ -142,6 +87,9 @@ module Pod ...@@ -142,6 +87,9 @@ module Pod
end end
end end
# @return [void] Checkouts the HEAD of a specific branch of the git
# source in the destination path.
#
def download_branch def download_branch
ensure_remote_branch_exists(options[:branch]) ensure_remote_branch_exists(options[:branch])
clone(clone_url, target_path) clone(clone_url, target_path)
...@@ -153,13 +101,135 @@ module Pod ...@@ -153,13 +101,135 @@ module Pod
end end
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 (commit SHA or 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.
#
# @note The previous implementation of the cache didn't use a barebone
# git repo. This method takes into account this fact and checks
# that the cache is actually a barebone repo. If the cache was not
# barebone it will be deleted and recreated.
#
def cache_exist?
cache_path.exist? &&
cache_origin_url(cache_path).to_s == url.to_s &&
Dir.chdir(cache_path) { git("config core.bare").chomp == "true" }
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) { git! "remote update" }
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 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
......
...@@ -163,14 +163,15 @@ module Pod ...@@ -163,14 +163,15 @@ module Pod
# #
# @return [Array<Strings>] The paths that can be deleted. # @return [Array<Strings>] The paths that can be deleted.
# #
# @note The Paths are downcased to prevent issues. See #568. # @note Implementation detail: Don't use Dir#glob as there is an
# unexplained issue (#568, #572 and #602).
# #
def clean_paths def clean_paths
cached_used_paths = used_files cached_used = used_files
files = Dir.glob(root + "**/*", File::FNM_DOTMATCH) files = Pathname.glob(root + "**/*", File::FNM_DOTMATCH | File::FNM_CASEFOLD).map(&:to_s)
files.reject! do |candidate| files.reject! do |candidate|
candidate.end_with?('.', '..') || cached_used_paths.any? do |path| candidate.end_with?('.', '..') || cached_used.any? do |path|
path.include?(candidate) || candidate.include?(path) path.include?(candidate) || candidate.include?(path)
end end
end end
......
...@@ -35,7 +35,7 @@ module Pod ...@@ -35,7 +35,7 @@ module Pod
if @path if @path
@path @path
else else
xcodeprojs = config.project_root.glob('*.xcodeproj') xcodeprojs = Pathname.glob(config.project_root + '*.xcodeproj')
if xcodeprojs.size == 1 if xcodeprojs.size == 1
@path = xcodeprojs.first @path = xcodeprojs.first
end end
......
...@@ -196,8 +196,9 @@ module Pod ...@@ -196,8 +196,9 @@ module Pod
# @!group Helpers # @!group Helpers
# Wraps a string taking into account the width of the terminal and an # @return [String] Wraps a string taking into account the width of the
# option indent. Adapted from http://blog.macromates.com/2006/wrapping-text-with-regular-expressions/ # terminal and an option indent. Adapted from
# http://blog.macromates.com/2006/wrapping-text-with-regular-expressions/
# #
# @param [String] txt The string to wrap # @param [String] txt The string to wrap
# #
...@@ -205,8 +206,12 @@ module Pod ...@@ -205,8 +206,12 @@ module Pod
# #
# @return [String] The formatted string. # @return [String] The formatted string.
# #
# @note If CocoaPods is not being run in a terminal or the width of the
# terminal is too small a width of 80 is assumed.
#
def wrap_string(txt, indent = '') def wrap_string(txt, indent = '')
width = `stty size`.split(' ')[1].to_i - indent.length width = `stty size`.split(' ')[1].to_i - indent.length
width = 80 unless width >= 10
txt.strip.gsub(/(.{1,#{width}})( +|$)\n?|(.{#{width}})/, indent + "\\1\\3\n") txt.strip.gsub(/(.{1,#{width}})( +|$)\n?|(.{#{width}})/, indent + "\\1\\3\n")
end end
end end
......
...@@ -56,11 +56,11 @@ describe Pod::LocalPod do ...@@ -56,11 +56,11 @@ describe Pod::LocalPod do
end end
it "returns an expanded list the files to clean" do it "returns an expanded list the files to clean" do
clean_paths = @pod.clean_paths.map { |p| p.to_s.gsub(/.*pods\/bananalib/,'') } clean_paths = @pod.clean_paths.map { |p| p.to_s.gsub(/.*Pods\/BananaLib/,'') }
clean_paths.should.include "/.git/config" clean_paths.should.include "/.git/config"
# * There are some hidden files on Travis # * There are some hidden files on Travis
# * The submodule of the repo (libPusher) can be ignore, to reduce noise of this test # * The submodule of the repo (libPusher) can be ignore, to reduce noise of this test
clean_files_without_hidden = clean_paths.reject { |p| p.to_s.include?('/.') || p.to_s.include?('libpusher') } clean_files_without_hidden = clean_paths.reject { |p| p.to_s.include?('/.') || p.to_s.include?('libPusher') }
clean_files_without_hidden.should == %W[ /sub-dir /sub-dir/sub-dir-2 /sub-dir/sub-dir-2/somefile.txt ] clean_files_without_hidden.should == %W[ /sub-dir /sub-dir/sub-dir-2 /sub-dir/sub-dir-2/somefile.txt ]
end end
...@@ -208,9 +208,9 @@ describe Pod::LocalPod do ...@@ -208,9 +208,9 @@ describe Pod::LocalPod do
/StoreKit/StoreKit_Prefix.pch /StoreKit/StoreKit_Prefix.pch
/UIKit/UIKit_Prefix.pch /UIKit/UIKit_Prefix.pch
] ]
root = @pod.root.to_s.downcase root = @pod.root.to_s
computed = @pod.clean_paths.each{ |p| p.gsub!(root, '') } computed = @pod.clean_paths.each{ |p| p.gsub!(root, '') }
assert_array_equals(expected.map(&:downcase), computed) assert_array_equals(expected, computed)
end end
it "resolves the used files" do it "resolves the used files" do
......
...@@ -105,7 +105,7 @@ describe "Pod::Podfile" do ...@@ -105,7 +105,7 @@ describe "Pod::Podfile" do
end end
path = config.project_root + 'MyProject.xcodeproj' path = config.project_root + 'MyProject.xcodeproj'
config.project_root.expects(:glob).with('*.xcodeproj').returns([path]) Pathname.expects(:glob).with(config.project_root + '*.xcodeproj').returns([path])
podfile.target_definitions[:default].user_project.path.should == path podfile.target_definitions[:default].user_project.path.should == path
podfile.target_definitions[:another_target].user_project.path.should == path podfile.target_definitions[:another_target].user_project.path.should == path
...@@ -113,7 +113,7 @@ describe "Pod::Podfile" do ...@@ -113,7 +113,7 @@ describe "Pod::Podfile" do
it "assumes the basename of the workspace is the same as the default target's project basename" do it "assumes the basename of the workspace is the same as the default target's project basename" do
path = config.project_root + 'MyProject.xcodeproj' path = config.project_root + 'MyProject.xcodeproj'
config.project_root.expects(:glob).with('*.xcodeproj').returns([path]) Pathname.expects(:glob).with(config.project_root + '*.xcodeproj').returns([path])
Pod::Podfile.new {}.workspace.should == config.project_root + 'MyProject.xcworkspace' Pod::Podfile.new {}.workspace.should == config.project_root + 'MyProject.xcworkspace'
Pod::Podfile.new do Pod::Podfile.new do
...@@ -225,13 +225,13 @@ describe "Pod::Podfile" do ...@@ -225,13 +225,13 @@ describe "Pod::Podfile" do
it "returns a Xcode project found in the working dir when no explicit project is specified" do it "returns a Xcode project found in the working dir when no explicit project is specified" do
xcodeproj1 = config.project_root + '1.xcodeproj' xcodeproj1 = config.project_root + '1.xcodeproj'
config.project_root.expects(:glob).with('*.xcodeproj').returns([xcodeproj1]) Pathname.expects(:glob).with(config.project_root + '*.xcodeproj').returns([xcodeproj1])
Pod::Podfile::UserProject.new.path.should == xcodeproj1 Pod::Podfile::UserProject.new.path.should == xcodeproj1
end end
it "returns `nil' if more than one Xcode project was found in the working when no explicit project is specified" do it "returns `nil' if more than one Xcode project was found in the working when no explicit project is specified" do
xcodeproj1, xcodeproj2 = config.project_root + '1.xcodeproj', config.project_root + '2.xcodeproj' xcodeproj1, xcodeproj2 = config.project_root + '1.xcodeproj', config.project_root + '2.xcodeproj'
config.project_root.expects(:glob).with('*.xcodeproj').returns([xcodeproj1, xcodeproj2]) Pathname.expects(:glob).with(config.project_root + '*.xcodeproj').returns([xcodeproj1, xcodeproj2])
Pod::Podfile::UserProject.new.path.should == nil Pod::Podfile::UserProject.new.path.should == nil
end end
......
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