Commit 8eba1796 authored by Samuel E. Giddins's avatar Samuel E. Giddins

Make the specification of URL in Podfile much more robust

parent 9e47e11d
......@@ -7,7 +7,7 @@ GIT
GIT
remote: https://github.com/CocoaPods/Core.git
revision: 4189457e12113b09eafc1ebabcf1559fc23ef7b9
revision: 64d5b311a7ee1dd6e0ad8716a1bd5033436d04d8
branch: source-url
specs:
cocoapods-core (0.34.0.rc2)
......
......@@ -371,13 +371,16 @@ module Pod
@sources ||= begin
sources = podfile.sources
if sources.empty?
SourcesManager.master
SourcesManager.all.tap do |all|
UI.warn all.reduce("The use of implicit sources has been " \
"deprecated. To replicate the previous behavior, add the " \
"following to your Podfile:") \
{ |w, s| w << "\nsource '#{s.url}'" }
end
else
urls = sources.select { |s| s =~ /\A#{URI.regexp}\z/ }
url_sources = urls.map do |url|
SourcesManager.find_or_create_source_with_url!(url)
sources.map do |url|
SourcesManager.find_or_create_source_with_url(url)
end
SourcesManager.sources(sources - urls) + url_sources
end
end
end
......
......@@ -35,32 +35,16 @@ module Pod
#
def find_or_create_source_with_url(url)
unless source = source_with_url(url)
name = URI(url).path.split('/')[-2]
UI.section("Cloning spec repo `#{name}` from `#{url}`") do
config.repos_dir.mkpath
Dir.chdir(config.repos_dir) do
command = "clone '#{url}' #{name}"
output = git(command)
name = name_for_url(url)
Command::Repo::Add.new(CLAide::ARGV.new([name, url])).run
source = source_with_url(url)
end
check_version_information(config.repos_dir + name)
source = sources([name]).find
end
end
raise Informative, "Unable to add a source with url `#{url}`:\n\n" +
output unless source
raise Informative, "Unable to add a source with url `#{url}` named " \
"`#{name}`.\nYou can add it manually via `pod repo add NAME " \
"#{url}`.\n\n#{output}" unless source
source
end
# @return [Source] The source whose {Source#url} is equal to `url`.
#
# @param [String] url
# The URL of the source.
#
def source_with_url(url)
aggregate.sources.find { |s| s.url == url }
end
# @return [Array<Source>] The list of all the sources known to this
# installation of CocoaPods.
#
......@@ -381,6 +365,56 @@ module Pod
raise Informative, "Unable to find the `#{name}` repo."
end
end
# @return [Source] The source whose {Source#url} is equal to `url`.
#
# @param [String] url
# The URL of the source.
#
def source_with_url(url)
aggregate.sources.find { |s| s.url == url }
end
# Returns a suitable repository name for `url`.
#
# @example A GitHub.com URL
#
# name_for_url('https://github.com/Artsy/Specs.git')
# # "artsy"
# name_for_url('https://github.com/Artsy/Specs.git')
# # "artsy-1"
#
# @example A non-Github.com URL
#
# name_for_url('https://sourceforge.org/Artsy/Specs.git')
# # sourceforge-artsy-specs
#
# @param [#to_s] url
# The URL of the source.
#
# @return [String] A suitable repository name for `url`.
#
def name_for_url(url)
case url.downcase
when %r{github.com(:|/)cocoapods/specs}
base = 'master'
when %r{github.com(:|/)(.+)/(.+)}
base = Regexp.last_match[2]
else
raise Informative,
"`#{url}` is not a valid URL." unless url =~ URI.regexp
url = URI(url.downcase)
base = url.host.split('.')[-2] +
url.path.gsub(/.git$/, '').split('/').join('-')
end
name = base
infinity = 1.0 / 0
(1..infinity).each do |i|
break unless source_dir(name).exist?
name = "#{base}-#{i}"
end
name
end
end
end
end
......@@ -465,6 +465,49 @@ module Pod
e.message.should.match /Targets with different platforms/
end
end
#--------------------------------------#
describe 'sources' do
describe 'when there are no explicit sources' do
it 'defaults to all sources' do
@analyzer.send(:sources).map(&:url).should ==
SourcesManager.all.map(&:url)
end
it 'prints a warning about the deprecation of implicit sources' do
@analyzer.send(:sources)
UI.warnings.should.match /implicit(.+)sources(.+)deprecated/
end
it 'prints a warning about how to add explicit sources' do
@analyzer.send(:sources)
UI.warnings.should.
match %r{^source 'https://github.com/CocoaPods/Specs.git'$}
end
end
describe 'when there are explicit sources' do
it 'raises if no specs repo with that URL could be added' do
podfile = Podfile.new do
source 'not-a-git-repo'
end
@analyzer.instance_variable_set(:@podfile, podfile)
should.raise Informative do
@analyzer.send(:sources)
end.message.should.match /not a valid URL/
end
it 'fetches a specs repo that is specified by the podfile' do
podfile = Podfile.new do
source 'https://github.com/artsy/Specs.git'
end
@analyzer.instance_variable_set(:@podfile, podfile)
SourcesManager.expects(:find_or_create_source_with_url).once
@analyzer.send(:sources)
end
end
end
end
end
end
......@@ -101,6 +101,62 @@ module Pod
path = SourcesManager.search_index_path.to_s
path.should.match %r{Library/Caches/CocoaPods/search_index.yaml}
end
describe 'managing sources by URL' do
describe 'generating a repo name from a URL' do
it 'uses `master` for the master CocoaPods repository' do
url = 'https://github.com/CocoaPods/Specs.git'
Pathname.any_instance.stubs(:exist?).
returns(false).then.returns(true)
SourcesManager.send(:name_for_url, url).should == 'master'
url = 'git@github.com:CocoaPods/Specs.git'
Pathname.any_instance.stubs(:exist?).
returns(false).then.returns(true)
SourcesManager.send(:name_for_url, url).should == 'master'
end
it 'uses the organization name for github.com URLs' do
url = 'https://github.com/segiddins/banana.git'
SourcesManager.send(:name_for_url, url).should == 'segiddins'
end
it 'uses a combination of host and path for other URLs' do
url = 'https://sourceforge.org/Artsy/Specs.git'
SourcesManager.send(:name_for_url, url).
should == 'sourceforge-artsy-specs'
end
it 'appends a number to the name if the base name dir exists' do
url = 'https://github.com/segiddins/banana.git'
Pathname.any_instance.stubs(:exist?).
returns(true).then.returns(false)
SourcesManager.send(:name_for_url, url).should == 'segiddins-1'
url = 'https://sourceforge.org/Artsy/Specs.git'
Pathname.any_instance.stubs(:exist?).
returns(true).then.returns(false)
SourcesManager.send(:name_for_url, url).
should == 'sourceforge-artsy-specs-1'
end
end
describe 'finding or creating a source by URL' do
it 'returns an existing matching source' do
Source.any_instance.stubs(:url).returns('url')
SourcesManager.expects(:name_for_url).never
SourcesManager.find_or_create_source_with_url('url').url.
should == 'url'
end
it 'runs `pod repo add` when there is no matching source' do
Command::Repo::Add.any_instance.stubs(:run).once
SourcesManager.stubs(:source_with_url).returns(nil).then.returns(true)
SourcesManager.find_or_create_source_with_url('https://banana.com/local/specs.git').
should == true
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