Commit 8a9d29e5 authored by Fabio Pelosin's avatar Fabio Pelosin

Added Pod::SourcesManager class.

- handles source logic in a central place.
- the installer does not need to run `pod repo update` anymore.
- similar argument for `pod setup` which now has programmatic access to almost all the needed methods.
- removes a lot of duplicated class-instance methods in the subcommands.
parent f8dfe1a8
...@@ -26,6 +26,7 @@ module Pod ...@@ -26,6 +26,7 @@ module Pod
autoload :Executable, 'cocoapods/executable' autoload :Executable, 'cocoapods/executable'
autoload :ExternalSources, 'cocoapods/external_sources' autoload :ExternalSources, 'cocoapods/external_sources'
autoload :Installer, 'cocoapods/installer' autoload :Installer, 'cocoapods/installer'
autoload :SourcesManager, 'cocoapods/sources_manager'
autoload :Library, 'cocoapods/library' autoload :Library, 'cocoapods/library'
autoload :LocalPod, 'cocoapods/local_pod' autoload :LocalPod, 'cocoapods/local_pod'
autoload :Project, 'cocoapods/project' autoload :Project, 'cocoapods/project'
...@@ -53,7 +54,6 @@ module Pod ...@@ -53,7 +54,6 @@ module Pod
require 'cocoapods/file_list' require 'cocoapods/file_list'
require 'cocoapods/config' require 'cocoapods/config'
require 'cocoapods/source'
end end
if ENV['COCOA_PODS_ENV'] == 'development' if ENV['COCOA_PODS_ENV'] == 'development'
......
...@@ -21,8 +21,8 @@ module Pod ...@@ -21,8 +21,8 @@ module Pod
def self.parse(argv) def self.parse(argv)
command = super command = super
unless command.is_a?(Setup) || ENV['SKIP_SETUP'] unless SourcesManager.master_repo_functional? || command.is_a?(Setup) || ENV['SKIP_SETUP']
Setup.run_if_needed Setup.new(CLAide::ARGV.new([])).run
end end
command command
end end
...@@ -57,6 +57,8 @@ module Pod ...@@ -57,6 +57,8 @@ module Pod
String.send(:define_method, :colorize) { |string , _| string } unless self.colorize_output? String.send(:define_method, :colorize) { |string , _| string } unless self.colorize_output?
end end
#-------------------------------------------------------------------------#
include Config::Mixin include Config::Mixin
private private
......
...@@ -23,7 +23,7 @@ module Pod ...@@ -23,7 +23,7 @@ module Pod
def run def run
update_if_necessary! update_if_necessary!
sets = Source.all_sets sets = SourcesManager.all_sets
sets.each { |set| UI.pod(set, :name) } sets.each { |set| UI.pod(set, :name) }
UI.puts "\n#{sets.count} pods were found" UI.puts "\n#{sets.count} pods were found"
end end
...@@ -40,13 +40,12 @@ module Pod ...@@ -40,13 +40,12 @@ module Pod
self.summary = 'Lists pods introduced in the master spec-repo since the last check' self.summary = 'Lists pods introduced in the master spec-repo since the last check'
def run def run
puts "running"
update_if_necessary! update_if_necessary!
days = [1,2,3,5,8] days = [1,2,3,5,8]
dates, groups = {}, {} dates, groups = {}, {}
days.each {|d| dates[d] = Time.now - 60 * 60 * 24 * d} days.each {|d| dates[d] = Time.now - 60 * 60 * 24 * d}
sets = Source.all_sets sets = SourcesManager.all_sets
creation_dates = Specification::Set::Statistics.instance.creation_dates(sets) creation_dates = Specification::Set::Statistics.instance.creation_dates(sets)
sets.each do |set| sets.each do |set|
......
...@@ -12,8 +12,8 @@ module Pod ...@@ -12,8 +12,8 @@ module Pod
self.summary = 'Add a spec repo.' self.summary = 'Add a spec repo.'
self.description = <<-DESC self.description = <<-DESC
Clones `URL' in the local spec-repos directory at `~/.cocoapods'. The Clones `URL` in the local spec-repos directory at `~/.cocoapods`. The
remote can later be referred to by `NAME'. remote can later be referred to by `NAME`.
DESC DESC
self.arguments = 'NAME URL [BRANCH]' self.arguments = 'NAME URL [BRANCH]'
...@@ -26,16 +26,16 @@ module Pod ...@@ -26,16 +26,16 @@ module Pod
def validate! def validate!
super super
unless @name && @url unless @name && @url
help! "Adding a repo needs a `NAME' and a `URL." help! "Adding a repo needs a `NAME` and a `URL`."
end end
end end
def run def run
UI.section("Cloning spec repo `#{@name}' from `#{@url}'#{" (branch `#{@branch}')" if @branch}") do UI.section("Cloning spec repo `#{@name}` from `#{@url}`#{" (branch `#{@branch}`)" if @branch}") do
config.repos_dir.mkpath config.repos_dir.mkpath
Dir.chdir(config.repos_dir) { git!("clone '#{@url}' #{@name}") } Dir.chdir(config.repos_dir) { git!("clone '#{@url}' #{@name}") }
Dir.chdir(dir) { git!("checkout #{@branch}") } if @branch Dir.chdir(dir) { git!("checkout #{@branch}") } if @branch
check_versions(dir) SourcesManager.check_version_information(dir)
end end
end end
end end
...@@ -46,8 +46,8 @@ module Pod ...@@ -46,8 +46,8 @@ module Pod
self.summary = 'Update a spec repo.' self.summary = 'Update a spec repo.'
self.description = <<-DESC self.description = <<-DESC
Updates the local clone of the spec-repo `NAME'. If `NAME' is omitted Updates the local clone of the spec-repo `NAME`. If `NAME` is omitted
this will update all spec-repos in `~/.cocoapods'. this will update all spec-repos in `~/.cocoapods`.
DESC DESC
self.arguments = '[NAME]' self.arguments = '[NAME]'
...@@ -58,20 +58,7 @@ module Pod ...@@ -58,20 +58,7 @@ module Pod
end end
def run def run
dirs = @name ? [dir] : config.repos_dir.children.select {|c| c.directory?} SourcesManager.update(@name, true)
dirs.each do |dir|
UI.section "Updating spec repo `#{dir.basename}'" do
Dir.chdir(dir) do
`git rev-parse >/dev/null 2>&1`
if $?.exitstatus.zero?
git!("pull")
else
UI.message "Not a git repository"
end
end
end
check_versions(dir)
end
end end
end end
...@@ -81,8 +68,8 @@ module Pod ...@@ -81,8 +68,8 @@ module Pod
self.summary = 'Validates all specs in a repo.' self.summary = 'Validates all specs in a repo.'
self.description = <<-DESC self.description = <<-DESC
Lints the spec-repo `NAME'. If a directory is provided it is assumed Lints the spec-repo `NAME`. If a directory is provided it is assumed
to be the root of a repo. Finally, if `NAME' is not provided this to be the root of a repo. Finally, if `NAME` is not provided this
will lint all the spec-repos known to CocoaPods. will lint all the spec-repos known to CocoaPods.
DESC DESC
...@@ -105,14 +92,14 @@ module Pod ...@@ -105,14 +92,14 @@ module Pod
dirs = config.repos_dir.children.select {|c| c.directory?} dirs = config.repos_dir.children.select {|c| c.directory?}
end end
dirs.each do |dir| dirs.each do |dir|
check_versions(dir) SourcesManager.check_version_information(dir)
UI.puts "\nLinting spec repo `#{dir.realpath.basename}'\n".yellow UI.puts "\nLinting spec repo `#{dir.realpath.basename}`\n".yellow
podspecs = Pathname.glob( dir + '**/*.podspec') podspecs = Pathname.glob( dir + '**/*.podspec')
invalid_count = 0 invalid_count = 0
messages_by_type = {} messages_by_type = {}
podspecs.each do |podspec| podspecs.each do |podspec|
print "\033[K -> #{podspec.relative_path_from(dir)}\r" # print "\033[K -> #{podspec.relative_path_from(dir)}\r" unless config.silent?
validator = Validator.new(podspec) validator = Validator.new(podspec)
validator.quick = true validator.quick = true
validator.repo_path = dir validator.repo_path = dir
...@@ -136,7 +123,8 @@ module Pod ...@@ -136,7 +123,8 @@ module Pod
end end
end end
print "\033[K" # TODO add UI.print
# print "\033[K" unless config.silent?
messages_by_type.each do |type, messages_by_type| messages_by_type.each do |type, messages_by_type|
messages_by_type.each do |message, names| messages_by_type.each do |message, names|
color = type == :error ? :red : :yellow color = type == :error ? :red : :yellow
...@@ -146,12 +134,10 @@ module Pod ...@@ -146,12 +134,10 @@ module Pod
end end
end end
UI.puts "Analyzed #{podspecs.count} podspecs files.\n\n"
UI.puts "Analyzed #{podspecs.count} podspecs files.\n\n" unless config.silent?
if invalid_count == 0 if invalid_count == 0
UI.puts "All the specs passed validation.".green << "\n\n" unless config.silent? UI.puts "All the specs passed validation.".green << "\n\n"
else else
raise Informative, "#{invalid_count} podspecs failed validation." raise Informative, "#{invalid_count} podspecs failed validation."
end end
...@@ -159,78 +145,14 @@ module Pod ...@@ -159,78 +145,14 @@ module Pod
end end
end end
#-----------------------------------------------------------------------#
extend Executable extend Executable
executable :git executable :git
# TODO some of the following methods can probably move to one of the subclasses.
def dir def dir
config.repos_dir + @name config.repos_dir + @name
end end
def check_versions(dir)
versions = versions(dir)
unless is_compatilbe(versions)
min, max = versions['min'], versions['max']
version_msg = ( min == max ) ? min : "#{min} - #{max}"
raise Informative,
"\n[!] The `#{dir.basename.to_s}' repo requires CocoaPods #{version_msg}\n".red +
"Update Cocoapods, or checkout the appropriate tag in the repo.\n\n"
end
UI.puts "\nCocoapods #{versions['last']} is available.\n".green if has_update(versions) && config.new_version_message?
end
protected
def print_messages(type, messages)
return if config.silent?
messages.each {|msg| UI.puts " - #{type.ljust(5)} | #{msg}"}
end
def self.compatible?(name)
dir = Config.instance.repos_dir + name
versions = versions(dir)
is_compatilbe(versions)
end
#--------------------------------------#
private
def versions(dir)
self.class.versions(dir)
end
def self.versions(dir)
require 'yaml'
yaml_file = dir + 'CocoaPods-version.yml'
yaml_file.exist? ? YAML.load_file(yaml_file) : {}
end
def is_compatilbe(versions)
self.class.is_compatilbe(versions)
end
def self.is_compatilbe(versions)
min, max = versions['min'], versions['max']
supports_min = !min || bin_version >= Gem::Version.new(min)
supports_max = !max || bin_version <= Gem::Version.new(max)
supports_min && supports_max
end
def has_update(versions)
self.class.has_update(versions)
end
def self.has_update(versions)
last = versions['last']
last && Gem::Version.new(last) > bin_version
end
def self.bin_version
Gem::Version.new(VERSION)
end
end end
end end
end end
......
...@@ -31,7 +31,7 @@ module Pod ...@@ -31,7 +31,7 @@ module Pod
end end
def run def run
sets = Source.search_by_name(@query.strip, @full_text_search) sets = SourcesManager.search_by_name(@query.strip, @full_text_search)
sets.each do |set| sets.each do |set|
begin begin
UI.pod(set, (@stats ? :stats : :normal)) UI.pod(set, (@stats ? :stats : :normal))
......
...@@ -4,8 +4,8 @@ module Pod ...@@ -4,8 +4,8 @@ module Pod
self.summary = 'Setup the CocoaPods environment' self.summary = 'Setup the CocoaPods environment'
self.description = <<-DESC self.description = <<-DESC
Creates a directory at `~/.cocoapods' which will hold your spec-repos. Creates a directory at `~/.cocoapods` which will hold your spec-repos.
This is where it will create a clone of the public `master' spec-repo from: This is where it will create a clone of the public `master` spec-repo from:
https://github.com/CocoaPods/Specs https://github.com/CocoaPods/Specs
...@@ -24,90 +24,107 @@ module Pod ...@@ -24,90 +24,107 @@ module Pod
super super
end end
def self.dir def run
Config.instance.repos_dir + 'master' UI.section "Setting up CocoaPods master repo" do
end if master_repo_dir.exist?
set_master_repo_url
def dir set_master_repo_branch
self.class.dir update_master_repo
end
def read_only_url
'https://github.com/CocoaPods/Specs.git'
end
def read_write_url
'git@github.com:CocoaPods/Specs.git'
end
def url
if push?
read_write_url
else else
read_only_url add_master_repo
end
end
def origin_url_read_only?
read_master_repo_url.chomp == read_only_url
end end
enable_pre_commit_hooks
def origin_url_push?
read_master_repo_url.chomp == read_write_url
end end
def push? access_type = push? ? "push" : "read-only"
@push_option || (dir.exist? && origin_url_push?) UI.puts "Setup completed (#{access_type} access)".green
end end
def read_master_repo_url #--------------------------------------#
Dir.chdir(dir) do
origin_url = git('config --get remote.origin.url')
end
end
# Sets the url of the master repo according to whether it is push.
#
# @return [void]
#
def set_master_repo_url def set_master_repo_url
Dir.chdir(dir) do Dir.chdir(master_repo_dir) do
git("remote set-url origin '#{url}'") git("remote set-url origin '#{url}'")
end end
end end
# Adds the master repo from the remote.
#
# @return [void]
#
def add_master_repo def add_master_repo
@command ||= Repo::Add.parse(['master', url, 'master']).run @command ||= Repo::Add.parse(['master', url, 'master']).run
end end
# Updates the master repo against the remote.
#
# @return [void]
#
def update_master_repo def update_master_repo
Repo::Update.run(['master']) SourcesManager.update('master', true)
end end
# Sets the repo to the master branch.
#
# @note This is not needed anymore as it was used for CocoaPods 0.6
# release candidates.
#
# @return [void]
#
def set_master_repo_branch def set_master_repo_branch
Dir.chdir(dir) do Dir.chdir(master_repo_dir) do
git("checkout master") git("checkout master")
end end
end end
def self.run_if_needed # Enables the pre-commit hook of the master repo.
self.new(CLAide::ARGV.new([])).run unless #
dir.exist? && Repo.compatible?('master') # @note The hook is enabled in this way because the specs run with the
# master repo as a submodule.
#
# @return [void]
#
def enable_pre_commit_hooks
if (master_repo_dir + '.git/hooks').exist?
hook = master_repo_dir + '.git/hooks/pre-commit'
hook.open('w') { |f| f << "#!/bin/sh\nrake lint" }
`chmod +x '#{hook}'`
end
end
#--------------------------------------#
def url
url = (push?) ? read_write_url : read_only_url
end end
def run def master_repo_dir
UI.section "Setting up CocoaPods master repo" do SourcesManager.master_repo_dir
if dir.exist?
set_master_repo_url
set_master_repo_branch
update_master_repo
else
add_master_repo
end end
# Mainly so the specs run with submodule repos
if (dir + '.git/hooks').exist? def read_only_url
hook = dir + '.git/hooks/pre-commit' 'https://github.com/CocoaPods/Specs.git'
hook.open('w') { |f| f << "#!/bin/sh\nrake lint" }
`chmod +x '#{hook}'`
end end
def read_write_url
'git@github.com:CocoaPods/Specs.git'
end
def push?
@push ||= (@push_option || master_repo_is_push?)
end
def master_repo_is_push?
return false unless master_repo_dir.exist?
Dir.chdir(master_repo_dir) do
url = git('config --get remote.origin.url')
url.chomp == read_write_url
end end
UI.puts "Setup completed (#{push? ? "push" : "read-only"} access)".green
end end
end end
end end
......
...@@ -134,7 +134,7 @@ module Pod ...@@ -134,7 +134,7 @@ module Pod
end end
def run def run
found_sets = Source.search_by_name(@name) found_sets = SourcesManager.search_by_name(@name)
raise Informative, "Unable to find a spec named `#{@name}'." if found_sets.count == 0 raise Informative, "Unable to find a spec named `#{@name}'." if found_sets.count == 0
unless found_sets.count == 1 unless found_sets.count == 1
names = found_sets.map(&:name) * ', ' names = found_sets.map(&:name) * ', '
......
...@@ -77,11 +77,11 @@ module Pod ...@@ -77,11 +77,11 @@ module Pod
end end
define_method(name) do |command| define_method(name) do |command|
send(base_method, command, false) Executable.execute_command(name, command, false)
end end
define_method(name.to_s + "!") do |command| define_method(name.to_s + "!") do |command|
send(base_method, command, true) Executable.execute_command(name, command, true)
end end
private name private name
......
...@@ -242,6 +242,7 @@ module Pod ...@@ -242,6 +242,7 @@ module Pod
UI.info("->".green + " Fetching podspec for `#{name}' from: #{@params[:podspec]}") do UI.info("->".green + " Fetching podspec for `#{name}' from: #{@params[:podspec]}") do
path = @params[:podspec] path = @params[:podspec]
path = Pathname.new(path).expand_path if path.to_s.start_with?("~") path = Pathname.new(path).expand_path if path.to_s.start_with?("~")
require 'open-uri'
open(path) { |io| store_podspec(sandbox, io.read) } open(path) { |io| store_podspec(sandbox, io.read) }
end end
end end
......
...@@ -403,7 +403,7 @@ module Pod ...@@ -403,7 +403,7 @@ module Pod
should_update = !lockfile || !changed_pods.empty? || update_mode should_update = !lockfile || !changed_pods.empty? || update_mode
if should_update if should_update
UI.section 'Updating spec repositories' do UI.section 'Updating spec repositories' do
Command::Repo.new(Command::ARGV.new(["update"])).run SourcesManager.update
end end
end end
end end
......
module Pod
class Source
class << self
include Config::Mixin
# @return [Array<Source>] the list of all the sources known to this
# installation of CocoaPods.
#
def all
Aggregate.new(config.repos_dir).all
end
# @return [Array<Specification::Set>] the list of all the specification
# sets know to this installation of CocoaPods.
#
def all_sets
Aggregate.new(config.repos_dir).all_sets
end
# Search all the sources to match the set for the given dependency.
#
# @return [Set, nil] a set for a given dependency including all the
# {Source} that contain the Pod. If no sources containing the
# Pod where found it returns nil.
#
# @todo Move exceptions to clients?
#
# @raise If no source including the set can be found.
#
def search(dependency)
set = Aggregate.new(config.repos_dir).search(dependency)
raise Informative, "Unable to find a pod named `#{dependency.name}`" unless set
set
end
# Search all the sources with the given search term.
#
# @param [String] query
# The search term.
#
# @param [Bool] full_text_search
# Whether the search should be limited to the name of the Pod or
# should include also the author, the summary, and the
# description.
#
# @raise If no source including the set can be found.
#
# @note Full text search requires to load the specification for each
# pod, hence is considerably slower.
#
# @todo Move exceptions to clients?
#
# @return [Array<Set>] The sets that contain the search term.
#
def search_by_name(query, full_text_search = false)
result = Aggregate.new(config.repos_dir).search_by_name(query, full_text_search)
if result.empty?
extra = ", author, summary, or description" if full_text_search
raise Informative "Unable to find a pod with name#{extra} matching `#{query}'"
end
result
end
end
end
end
module Pod
# Manages all the sources known to the running CocoaPods Instance.
#
class SourcesManager
class << self
include Config::Mixin
# @return [Source::Aggregate] the aggregate of all the sources known to
# this installation of CocoaPods.
#
def aggregate
Source::Aggregate.new(config.repos_dir)
end
# @return [Array<Source>] the list of all the sources known to this
# installation of CocoaPods.
#
def all
aggregate.all
end
# @return [Array<Specification::Set>] the list of all the specification
# sets know to this installation of CocoaPods.
#
def all_sets
aggregate.all_sets
end
# Search all the sources to match the set for the given dependency.
#
# @return [Set, nil] a set for a given dependency including all the
# {Source} that contain the Pod. If no sources containing the
# Pod where found it returns nil.
#
# @raise If no source including the set can be found.
#
def search(dependency)
set = aggregate.search(dependency)
raise Informative, "Unable to find a pod named `#{dependency.name}`" unless set
set
end
# Search all the sources with the given search term.
#
# @param [String] query
# The search term.
#
# @param [Bool] full_text_search
# Whether the search should be limited to the name of the Pod or
# should include also the author, the summary, and the
# description.
#
# @raise If no source including the set can be found.
#
# @note Full text search requires to load the specification for each
# pod, hence is considerably slower.
#
# @return [Array<Set>] The sets that contain the search term.
#
def search_by_name(query, full_text_search = false)
result = aggregate.search_by_name(query, full_text_search)
if result.empty?
extra = ", author, summary, or description" if full_text_search
raise Informative "Unable to find a pod with name#{extra} matching `#{query}`"
end
result
end
#-----------------------------------------------------------------------#
# @!group Updating Sources
extend Executable
executable :git
# Updates the local clone of the spec-repo with the given name or of all
# the git repos if the name is omitted.
#
# @param [String] name
#
# @return [void]
#
def update(source_name = nil, show_output = false)
if source_name
source = aggregate.all.find { |s| s.name == source_name }
raise Informative, "Unable to find the `#{source_name}` repo." unless source
raise Informative, "The `#{source_name}` repo is not a git repo." unless git_repo?(source.repo)
sources = [source]
else
sources = aggregate.all.select { |source| git_repo?(source.repo) }
end
sources.each do |source|
UI.section "Updating spec repo `#{source.name}`" do
Dir.chdir(source.repo) do
output = git!("pull")
UI.puts output if show_output && !config.verbose?
end
check_version_information(source.repo)
end
end
end
# Returns whether a source is a GIT repo.
#
# @param [Pathname] dir
# The directory where the source is stored.
#
# @return [Bool] Wether the given source is a GIT repo.
#
def git_repo?(dir)
Dir.chdir(dir) { `git rev-parse >/dev/null 2>&1` }
$?.exitstatus.zero?
end
# Checks the version information of the source with the given directory.
# It raises if the source is not compatible and if there is CocoaPods
# update it informs the user.
#
# @param [Pathname] dir
# The directory where the source is stored.
#
# @raise If the source is not compatible.
#
# @return [void]
#
def check_version_information(dir)
versions = version_information(dir)
unless repo_compatible?(dir)
min, max = versions['min'], versions['max']
version_msg = ( min == max ) ? min : "#{min} - #{max}"
raise Informative, "The `#{dir.basename.to_s}` repo requires CocoaPods #{version_msg}\n".red +
"Update Cocoapods, or checkout the appropriate tag in the repo."
end
if config.new_version_message? && cocoapods_update?(versions)
UI.puts "\nCocoapods #{versions['last']} is available.\n".green
end
end
# Returns whether a source is compatible with the current version of
# CocoaPods.
#
# @param [Pathname] dir
# The directory where the source is stored.
#
# @return [Bool] whether the source is compatible.
#
def repo_compatible?(dir)
versions = version_information(dir)
min, max = versions['min'], versions['max']
bin_version = Gem::Version.new(Pod::VERSION)
supports_min = !min || bin_version >= Gem::Version.new(min)
supports_max = !max || bin_version <= Gem::Version.new(max)
supports_min && supports_max
end
# Checks whether there is a CocoaPods given the version information of a
# repo.
#
# @param [Hash] version_information
# The version information of a repository.
#
# @return [Bool] whether there is an update.
#
def cocoapods_update?(version_information)
version = version_information['last']
version && Gem::Version.new(version) > Gem::Version.new(Pod::VERSION)
end
# Returns the contents of the `CocoaPods-version.yml` file, which stores
# information about CocoaPods versions.
#
# This file is a hash with the following keys:
#
# - last: the last version of CocoaPods known to the source.
# - min: the minimum version of CocoaPods supported by the source.
# - max: the maximum version of CocoaPods supported by the source.
#
# @param [Pathname] dir
# The directory where the source is stored.
#
# @return [Hash] the versions information from the repo.
#
def version_information(dir)
require 'yaml'
yaml_file = dir + 'CocoaPods-version.yml'
yaml_file.exist? ? YAML.load_file(yaml_file) : {}
end
#-----------------------------------------------------------------------#
# @!group Master repo
# @return [Pathname] The path of the master repo.
#
def master_repo_dir
config.repos_dir + 'master'
end
# @return [Bool] Checks if the master repo is usable.
#
# @note Note this is used to automatically setup the master repo if
# needed.
#
def master_repo_functional?
master_repo_dir.exist? && repo_compatible?(master_repo_dir)
end
end
end
end
...@@ -10,7 +10,7 @@ module Pod ...@@ -10,7 +10,7 @@ module Pod
def report(error) def report(error)
return <<-EOS return <<-EOS
#{'――― MARKDOWN TEMPLATE ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――'.reversed} #{'――― MARKDOWN TEMPLATE ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――'.reversed}
### Report ### Report
...@@ -86,7 +86,7 @@ EOS ...@@ -86,7 +86,7 @@ EOS
end end
def repo_information def repo_information
Pod::Source.all.map do |source| SourcesManager.all.map do |source|
repo = source.repo repo = source.repo
Dir.chdir(repo) do Dir.chdir(repo) do
url = `git config --get remote.origin.url 2>&1`.strip url = `git config --get remote.origin.url 2>&1`.strip
......
...@@ -19,7 +19,7 @@ module Pod ...@@ -19,7 +19,7 @@ module Pod
end end
it "returns the new pods" do it "returns the new pods" do
sets = Source.all_sets sets = SourcesManager.all_sets
jsonkit_set = sets.find { |s| s.name == 'JSONKit' } jsonkit_set = sets.find { |s| s.name == 'JSONKit' }
dates = { dates = {
'BananaLib' => Time.now, 'BananaLib' => Time.now,
......
...@@ -56,56 +56,5 @@ module Pod ...@@ -56,56 +56,5 @@ module Pod
(repo2 + 'README').read.should.include 'Updated' (repo2 + 'README').read.should.include 'Updated'
end end
end end
describe "CocoaPods version" do
extend SpecHelper::Command
extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryRepos
require 'yaml'
before do
config.repos_dir = SpecHelper.tmp_repos_path
@repo = repo_make('repo1')
end
def write_version_file(hash)
yaml = YAML.dump(hash)
@versions_file = tmp_repos_path + "repo1/CocoaPods-version.yml"
File.open(@versions_file, 'w') {|f| f.write(yaml) }
end
it "it doesn't requires CocoaPods-version.yml" do
cmd = command('repo', 'update')
lambda { cmd.check_versions(@repo) }.should.not.raise
end
it "runs with a compatible repo" do
write_version_file({'min' => "0.0.1"})
cmd = command('repo', 'update')
lambda { cmd.check_versions(@repo) }.should.not.raise
end
it "raises if a repo is not compatible" do
write_version_file({'min' => "999.0.0"})
cmd = command('repo', 'update')
lambda { cmd.check_versions(@repo) }.should.raise Informative
end
it "informs about a higher known CocoaPods version" do
write_version_file({'last' => "999.0.0"})
cmd = command('repo', 'update')
cmd.check_versions(@repo)
UI.output.should.include "Cocoapods 999.0.0 is available"
end
it "has a class method that returns if a repo is supported" do
write_version_file({'min' => "999.0.0"})
Command::Repo.compatible?('repo1').should == false
write_version_file({'min' => "0.0.1"})
Command::Repo.compatible?('repo1').should == true
end
end
end end
end end
require File.expand_path('../../../spec_helper', __FILE__) require File.expand_path('../../../spec_helper', __FILE__)
describe Pod::Command::Setup do module Pod
describe Command::Setup do
extend SpecHelper::Command extend SpecHelper::Command
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryRepos extend SpecHelper::TemporaryRepos
...@@ -10,19 +11,19 @@ describe Pod::Command::Setup do ...@@ -10,19 +11,19 @@ describe Pod::Command::Setup do
end end
it "returns the read only URL of the `master` spec-repo" do it "returns the read only URL of the `master` spec-repo" do
cmd = Pod::Command::Setup.new(argv) cmd = Command::Setup.new(argv)
cmd.url.should == 'https://github.com/CocoaPods/Specs.git' cmd.url.should == 'https://github.com/CocoaPods/Specs.git'
end end
it "returns the push URL of the `master' spec-repo" do it "returns the push URL of the `master` spec-repo" do
config.silent = true config.silent = true
cmd = Pod::Command::Setup.new(argv('--push')) cmd = Command::Setup.new(argv('--push'))
cmd.url.should == 'git@github.com:CocoaPods/Specs.git' cmd.url.should == 'git@github.com:CocoaPods/Specs.git'
end end
before do before do
set_up_test_repo set_up_test_repo
Pod::Command::Setup.any_instance.stubs(:read_only_url).returns(test_repo_path.to_s) Command::Setup.any_instance.stubs(:read_only_url).returns(test_repo_path.to_s)
config.repos_dir = SpecHelper.temporary_directory config.repos_dir = SpecHelper.temporary_directory
end end
...@@ -30,7 +31,7 @@ describe Pod::Command::Setup do ...@@ -30,7 +31,7 @@ describe Pod::Command::Setup do
lambda { run_command('setup') }.should.not.raise lambda { run_command('setup') }.should.not.raise
end end
it "creates the local spec-repos directory and creates a clone of the `master' repo" do it "creates the local spec-repos directory and creates a clone of the `master` repo" do
output = run_command('setup') output = run_command('setup')
output.should.include "Setup completed" output.should.include "Setup completed"
output.should.not.include "push" output.should.not.include "push"
...@@ -38,18 +39,11 @@ describe Pod::Command::Setup do ...@@ -38,18 +39,11 @@ describe Pod::Command::Setup do
url.should == test_repo_path.to_s url.should == test_repo_path.to_s
end end
it "preserves push access for the `master' repo" do it "preserves push access for the `master` repo" do
output = run_command('setup') output = run_command('setup')
output.should.not.include "push" output.should.not.include "push"
Dir.chdir(config.repos_dir + 'master') { `git remote set-url origin git@github.com:CocoaPods/Specs.git` } Dir.chdir(config.repos_dir + 'master') { `git remote set-url origin git@github.com:CocoaPods/Specs.git` }
command('setup').url.should == 'git@github.com:CocoaPods/Specs.git' command('setup').url.should == 'git@github.com:CocoaPods/Specs.git'
end end
it "can run if needed" do
output = run_command('setup')
output.should.include "Setup completed"
Pod::UI.output = ''
Pod::Command::Setup.run_if_needed
Pod::UI.output.should == ''
end end
end end
...@@ -2,6 +2,8 @@ require File.expand_path('../../../spec_helper', __FILE__) ...@@ -2,6 +2,8 @@ require File.expand_path('../../../spec_helper', __FILE__)
module Pod module Pod
describe Command::Spec do describe Command::Spec do
describe "In general" do
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryDirectory
it "complains for wrong parameters" do it "complains for wrong parameters" do
...@@ -14,7 +16,9 @@ module Pod ...@@ -14,7 +16,9 @@ module Pod
end end
end end
describe "Command::Spec#create" do #-------------------------------------------------------------------------#
describe "create subcommand" do
extend SpecHelper::Github extend SpecHelper::Github
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryRepos extend SpecHelper::TemporaryRepos
...@@ -91,7 +95,9 @@ module Pod ...@@ -91,7 +95,9 @@ module Pod
end end
end end
describe "Command::Spec#lint" do #-------------------------------------------------------------------------#
describe "lint subcommand" do
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryRepos extend SpecHelper::TemporaryRepos
...@@ -109,13 +115,15 @@ module Pod ...@@ -109,13 +115,15 @@ module Pod
end end
end end
#TODO # TODO VCR is required in CocoaPods only for this test.
xit "lints a remote podspec" do #
Dir.chdir(fixture('spec-repos') + 'master/JSONKit/1.4/') do # it "lints a remote podspec" do
cmd = command('spec', 'lint', '--quick', '--only-errors', '--silent', 'https://github.com/CocoaPods/Specs/raw/master/A2DynamicDelegate/2.0.1/A2DynamicDelegate.podspec') # Dir.chdir(fixture('spec-repos') + 'master/JSONKit/1.4/') do
VCR.use_cassette('linter', :record => :new_episodes) { lambda { cmd.run }.should.not.raise } # cmd = command('spec', 'lint', '--quick', '--only-errors', '--silent', 'https://github.com/CocoaPods/Specs/raw/master/A2DynamicDelegate/2.0.1/A2DynamicDelegate.podspec')
end # # VCR.use_cassette('linter', :record => :new_episodes) { }
end # lambda { cmd.run }.should.not.raise
# end
# end
before do before do
text = (fixture('spec-repos') + 'master/JSONKit/1.4/JSONKit.podspec').read text = (fixture('spec-repos') + 'master/JSONKit/1.4/JSONKit.podspec').read
...@@ -138,7 +146,9 @@ module Pod ...@@ -138,7 +146,9 @@ module Pod
end end
end end
describe "Command::Spec#cat" do #-------------------------------------------------------------------------#
describe "cat subcommand" do
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryRepos extend SpecHelper::TemporaryRepos
...@@ -161,4 +171,5 @@ module Pod ...@@ -161,4 +171,5 @@ module Pod
end end
end end
end
end end
require File.expand_path('../../spec_helper', __FILE__) require File.expand_path('../../spec_helper', __FILE__)
require 'net/http' require 'net/http'
describe Pod::UI do module Pod
describe UI do
extend SpecHelper::Command extend SpecHelper::Command
before do before do
@set = Pod::Source.search(Pod::Dependency.new('CocoaLumberjack')) @set = SourcesManager.search(Dependency.new('CocoaLumberjack'))
Pod::Specification::Set::Statistics.instance.cache_file = nil Specification::Set::Statistics.instance.cache_file = nil
end end
it "presents the name, version, description, homepage and source of a specification set" do it "presents the name, version, description, homepage and source of a specification set" do
Pod::UI.pod(@set) UI.pod(@set)
output = Pod::UI.output output = UI.output
output.should.include? 'CocoaLumberjack' output.should.include? 'CocoaLumberjack'
output.should.include? '1.0' output.should.include? '1.0'
output.should.include? '1.1' output.should.include? '1.1'
...@@ -24,8 +25,8 @@ describe Pod::UI do ...@@ -24,8 +25,8 @@ describe Pod::UI do
it "presents the stats of a specification set" do it "presents the stats of a specification set" do
repo = { "forks"=>42, "watchers"=>318, "pushed_at"=>"2011-01-26T19:06:43Z" } repo = { "forks"=>42, "watchers"=>318, "pushed_at"=>"2011-01-26T19:06:43Z" }
Octokit.expects(:repo).with("robbiehanson/CocoaLumberjack").returns(repo) Octokit.expects(:repo).with("robbiehanson/CocoaLumberjack").returns(repo)
Pod::UI.pod(@set, :stats) UI.pod(@set, :stats)
output = Pod::UI.output output = UI.output
output.should.include? 'Author: Robbie Hanson' output.should.include? 'Author: Robbie Hanson'
output.should.include? 'License: BSD' output.should.include? 'License: BSD'
output.should.include? 'Platform: iOS - OS X' output.should.include? 'Platform: iOS - OS X'
...@@ -35,10 +36,11 @@ describe Pod::UI do ...@@ -35,10 +36,11 @@ describe Pod::UI do
end end
it "should print at least one subspec" do it "should print at least one subspec" do
@set = Pod::Source.search_by_name('RestKit').first @set = SourcesManager.search_by_name('RestKit').first
Pod::UI.pod(@set) UI.pod(@set)
output = Pod::UI.output output = UI.output
output.should.include? "RestKit/Network" output.should.include? "RestKit/Network"
end end
end
end end
require File.expand_path('../../../spec_helper', __FILE__)
describe "Pod::Command::Repo" do
extend SpecHelper::Command
before do
@command = command('repo', 'update')
@command.stubs(:bin_version).returns(Gem::Version.new('0.6.0.rc1'))
end
it "supports a repo with a compatible minimum version" do
versions = { 'min' => '0.5' }
@command.class.send(:is_compatilbe, versions).should == true
end
it "doesn't supports a repo with a non compatible minimum version" do
versions = { 'min' => '0.999' }
@command.class.send(:is_compatilbe, versions).should == false
end
it "supports a repo with a compatible maximum version" do
versions = { 'max' => '0.999' }
@command.class.send(:is_compatilbe, versions).should == true
end
it "doesn't support a repo with an incompatible maximum version" do
versions = { 'max' => '0.5' }
@command.class.send(:is_compatilbe, versions).should == false
end
it "detects if no update is available" do
versions = { 'last' => '0.5' }
@command.class.send(:has_update, versions).should == false
end
it "detects if an update is available" do
versions = { 'last' => '0.999' }
@command.class.send(:has_update, versions).should == true
end
end
...@@ -88,14 +88,13 @@ module Pod ...@@ -88,14 +88,13 @@ module Pod
@resolver = Resolver.new(config.sandbox, @podfile) @resolver = Resolver.new(config.sandbox, @podfile)
end end
it "holds the context state, such as cached specification sets" do it "holds the context state, such as cached specification sets" do
@resolver.resolve @resolver.resolve
cached_sets = @resolver.send(:cached_sets) cached_sets = @resolver.send(:cached_sets)
cached_sets.values.sort_by(&:name).should == [ cached_sets.values.sort_by(&:name).should == [
Source.search_by_name('A2DynamicDelegate').first, SourcesManager.search_by_name('A2DynamicDelegate').first,
Source.search_by_name('BlocksKit').first, SourcesManager.search_by_name('BlocksKit').first,
Source.search_by_name('libffi').first SourcesManager.search_by_name('libffi').first
].sort_by(&:name) ].sort_by(&:name)
end end
......
require File.expand_path('../../spec_helper', __FILE__)
module Pod
describe Pod::Source do
it "returns all the sources" do
Source.all.map(&:name).should == %w[master test_repo]
end
it "returns all the sets" do
Source.all_sets.map(&:name).should.include?('Chameleon')
end
it "searches for the set of a dependency" do
set = Source.search(Dependency.new('Chameleon'))
set.class.should == Pod::Specification::Set
set.name.should == 'Chameleon'
end
it "searches sets by name" do
sets = Source.search_by_name('Chameleon')
sets.all?{ |s| s.class == Pod::Specification::Set}.should.be.true
sets.any?{ |s| s.name == 'Chameleon'}.should.be.true
end
it "can perform a full text search of the sets" do
sets = Source.search_by_name('Drop in sharing', true)
sets.all?{ |s| s.class == Pod::Specification::Set}.should.be.true
sets.any?{ |s| s.name == 'ShareKit'}.should.be.true
end
end
end
require File.expand_path('../../spec_helper', __FILE__)
module Pod
describe SourcesManager do
describe "In general" do
it "returns all the sources" do
SourcesManager.all.map(&:name).should == %w[master test_repo]
end
it "returns all the sets" do
SourcesManager.all_sets.map(&:name).should.include?('Chameleon')
end
it "searches for the set of a dependency" do
set = SourcesManager.search(Dependency.new('Chameleon'))
set.class.should == Specification::Set
set.name.should == 'Chameleon'
end
it "searches sets by name" do
sets = SourcesManager.search_by_name('Chameleon')
sets.all?{ |s| s.class == Specification::Set}.should.be.true
sets.any?{ |s| s.name == 'Chameleon'}.should.be.true
end
it "can perform a full text search of the sets" do
sets = SourcesManager.search_by_name('Drop in sharing', true)
sets.all?{ |s| s.class == Specification::Set}.should.be.true
sets.any?{ |s| s.name == 'ShareKit'}.should.be.true
end
end
#-------------------------------------------------------------------------#
describe "Updating Sources" do
extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryRepos
it "update source backed by a git repository" do
set_up_test_repo
upstream = SpecHelper.temporary_directory + 'upstream'
FileUtils.cp_r(test_repo_path, upstream)
Dir.chdir(test_repo_path) do
`git remote add origin #{upstream}`
`git remote -v`
`git fetch -q`
`git branch --set-upstream master origin/master`
end
config.repos_dir = SpecHelper.tmp_repos_path
SourcesManager.update(test_repo_path.basename.to_s, true)
UI.output.should.match /Already up-to-date/
end
it "returns whether a source is backed by a git repo" do
SourcesManager.git_repo?(SourcesManager.master_repo_dir).should.be.true
SourcesManager.git_repo?(Pathname.new('/tmp')).should.be.false
end
it "informs the user if there is an update for CocoaPods" do
SourcesManager.stubs(:version_information).returns({ 'last' => '999.0' })
SourcesManager.check_version_information(temporary_directory)
UI.output.should.match /Cocoapods 999.0 is available/
end
it "raises while asked to version information of a source if it is not compatible" do
SourcesManager.stubs(:version_information).returns({ 'min' => '999.0' })
e = lambda { SourcesManager.check_version_information(temporary_directory) }.should.raise Informative
e.message.should.match /Update Cocoapods/
SourcesManager.stubs(:version_information).returns({ 'max' => '0.0.1' })
e = lambda { SourcesManager.check_version_information(temporary_directory) }.should.raise Informative
e.message.should.match /Update Cocoapods/
end
it "returns whether a repository is compatible" do
SourcesManager.stubs(:version_information).returns({ 'min' => '0.0.1' })
SourcesManager.repo_compatible?('stub').should.be.true
SourcesManager.stubs(:version_information).returns({ 'max' => '999.0' })
SourcesManager.repo_compatible?('stub').should.be.true
SourcesManager.stubs(:version_information).returns({ 'min' => '999.0' })
SourcesManager.repo_compatible?('stub').should.be.false
SourcesManager.stubs(:version_information).returns({ 'max' => '0.0.1' })
SourcesManager.repo_compatible?('stub').should.be.false
end
it "returns whether there is a CocoaPods update available" do
SourcesManager.cocoapods_update?({ 'last' => '0.0.1' }).should.be.false
SourcesManager.cocoapods_update?({ 'last' => '999.0' }).should.be.true
end
it "it returns an empty array for the version information if the file can't be found" do
SourcesManager.version_information(temporary_directory).should == {}
end
end
#-------------------------------------------------------------------------#
describe "Master repo" do
extend SpecHelper::TemporaryDirectory
it "returns the master repo dir" do
SourcesManager.master_repo_dir.to_s.should.match /fixtures\/spec-repos\/master/
end
it "returns whether the master repo is functional" do
SourcesManager.master_repo_functional?.should.be.true
config.repos_dir = SpecHelper.temporary_directory
SourcesManager.master_repo_functional?.should.be.false
end
end
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