Skip to content

Commit 81e2b03

Browse files
authored
Merge pull request #681 from igor-makarov/normalize-spec-repo-naming
Normalize spec repo name generation
2 parents 6173a89 + 18fc3d7 commit 81e2b03

File tree

2 files changed

+89
-28
lines changed

2 files changed

+89
-28
lines changed

lib/cocoapods-core/source/manager.rb

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require 'public_suffix'
2+
13
module Pod
24
class Source
35
class Manager
@@ -409,12 +411,12 @@ def canonic_url(url)
409411
# @example A non-Github.com URL
410412
#
411413
# name_for_url('https://sourceforge.org/Artsy/Specs.git')
412-
# # sourceforge-artsy-specs
414+
# # sourceforge-artsy
413415
#
414416
# @example A file URL
415417
#
416418
# name_for_url('file:///Artsy/Specs.git')
417-
# # artsy-specs
419+
# # artsy
418420
#
419421
# @param [#to_s] url
420422
# The URL of the source.
@@ -424,33 +426,52 @@ def canonic_url(url)
424426
def name_for_url(url)
425427
base_from_host_and_path = lambda do |host, path|
426428
if host && !host.empty?
427-
base = host.split('.')[-2] || host
428-
base += '-'
429+
domain = PublicSuffix.parse(host) rescue nil
430+
base = [domain&.sld || host]
431+
base = [] if base == %w(github)
429432
else
430-
base = ''
433+
base = []
431434
end
432435

433-
base + path.gsub(/.git$/, '').gsub(%r{^/}, '').split('/').join('-')
436+
path = path.gsub(/.git$/, '').gsub(%r{^/}, '').split('/')
437+
path.pop if path.last == 'specs'
438+
439+
(base + path).join('-')
440+
end
441+
442+
valid_url = lambda do |url|
443+
url =~ URI.regexp && (URI(url) rescue false)
444+
end
445+
446+
valid_scp_url = lambda do |url|
447+
valid_url['scp://' + url]
434448
end
435449

436-
case url.to_s.downcase
450+
url = url.to_s.downcase
451+
452+
case url
437453
when %r{https://#{Regexp.quote(trunk_repo_hostname)}}i
454+
# Main CDN repo
438455
base = Pod::TrunkSource::TRUNK_REPO_NAME
439-
when %r{github.com[:/]+(.+)/(.+)}
440-
base = Regexp.last_match[1]
441-
when %r{^\S+@(\S+)[:/]+(.+)$}
442-
host, path = Regexp.last_match.captures
443-
base = base_from_host_and_path[host, path]
444-
when URI.regexp
445-
url = URI(url.downcase)
456+
when valid_url
457+
# HTTPS URL or something similar
458+
url = valid_url[url]
446459
base = base_from_host_and_path[url.host, url.path]
460+
when valid_scp_url
461+
# SCP-style URLs for private git repos
462+
url = valid_scp_url[url]
463+
base = base_from_host_and_path[url.host, url.path]
464+
when %r{(?:git|ssh|https?|git@([-\w.]+)):(\/\/)?(.*?)(\.git)(\/?|\#[-\d\w._]+?)$}i
465+
# Additional SCP-style URLs for private git repos
466+
host, _, path = Regexp.last_match.captures
467+
base = base_from_host_and_path[host, path]
447468
else
448-
base = url.to_s.downcase
469+
# This is nearly impossible, with all the previous cases
470+
raise Informative, "Couldn't determine repo name for URL: #{url}"
449471
end
450472

451473
name = base
452-
infinity = 1.0 / 0
453-
(1..infinity).each do |i|
474+
(1..).each do |i|
454475
break unless source_dir(name).exist?
455476
name = "#{base}-#{i}"
456477
end

spec/source/manager_spec.rb

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -198,29 +198,61 @@ module Pod
198198
@sources_manager.send(:name_for_url, url).should == 'trunk'
199199
end
200200

201-
it 'uses the organization name for github.com URLs' do
201+
it 'uses the organization and repo name for github.com URLs' do
202202
url = 'https://github.com/segiddins/banana.git'
203+
@sources_manager.send(:name_for_url, url).should == 'segiddins-banana'
204+
end
205+
206+
it 'uses the organization name only for github.com specs URLs' do
207+
url = 'https://github.com/segiddins/Specs.git'
203208
@sources_manager.send(:name_for_url, url).should == 'segiddins'
204209
end
205210

206211
it 'uses a combination of host and path for other URLs' do
207212
url = 'https://sourceforge.org/Artsy/Specs.git'
208213
@sources_manager.send(:name_for_url, url).
209-
should == 'sourceforge-artsy-specs'
214+
should == 'sourceforge-artsy'
215+
url = 'https://sourceforge.org.au/Artsy/Specs.git'
216+
@sources_manager.send(:name_for_url, url).
217+
should == 'sourceforge-artsy'
218+
url = 'https://pvt.sourceforge.org.au/Artsy/Specs.git'
219+
@sources_manager.send(:name_for_url, url).
220+
should == 'sourceforge-artsy'
221+
end
222+
223+
it 'does not remove /specs path component if it is not the last one' do
224+
url = 'https://sourceforge.org.au/Specs/Path/Repo.git'
225+
@sources_manager.send(:name_for_url, url).should == 'sourceforge-specs-path-repo'
226+
end
227+
228+
it 'can understand arbitrary URI schemes' do
229+
url = 'banana://website.org/Artsy/Specs.git'
230+
@sources_manager.send(:name_for_url, url).
231+
should == 'website-artsy'
232+
end
233+
234+
it 'should raise on completely ridiculous non-URL input' do
235+
url = ' '
236+
should.raise Informative do
237+
@sources_manager.send(:name_for_url, url)
238+
end.message.should.== "Couldn't determine repo name for URL: #{url}"
210239
end
211240

212241
it 'supports scp-style URLs' do
213242
url = 'git@git-host.com:specs.git'
214243
@sources_manager.send(:name_for_url, url).
215-
should == 'git-host-specs'
244+
should == 'git-host'
216245

217246
url = 'git@git-host.com/specs.git'
218247
@sources_manager.send(:name_for_url, url).
219-
should == 'git-host-specs'
248+
should == 'git-host'
220249

221250
url = 'git@git-host.com:/specs.git'
222251
@sources_manager.send(:name_for_url, url).
223-
should == 'git-host-specs'
252+
should == 'git-host'
253+
url = 'git@github.com/segiddins/Specs'
254+
@sources_manager.send(:name_for_url, url).
255+
should == 'segiddins'
224256
end
225257

226258
it 'supports ssh URLs with an aliased hostname' do
@@ -230,9 +262,12 @@ module Pod
230262
end
231263

232264
it 'supports file URLs' do
233-
url = 'file:///Users/kurrytran/pod-specs'
265+
url = 'file:///Users/kurrytran/etc'
234266
@sources_manager.send(:name_for_url, url).
235-
should == 'users-kurrytran-pod-specs'
267+
should == 'users-kurrytran-etc'
268+
url = 'file:///Users/kurrytran/specs'
269+
@sources_manager.send(:name_for_url, url).
270+
should == 'users-kurrytran'
236271
end
237272

238273
it 'uses the repo name if no parent directory' do
@@ -244,20 +279,25 @@ module Pod
244279
it 'supports ssh URLs with no user component' do
245280
url = 'ssh://company.com/pods/specs.git'
246281
@sources_manager.send(:name_for_url, url).
247-
should == 'company-pods-specs'
282+
should == 'company-pods'
248283
end
249284

250285
it 'appends a number to the name if the base name dir exists' do
251286
url = 'https://github.com/segiddins/banana.git'
252287
Pathname.any_instance.stubs(:exist?).
253288
returns(true).then.returns(false)
254-
@sources_manager.send(:name_for_url, url).should == 'segiddins-1'
289+
@sources_manager.send(:name_for_url, url).should == 'segiddins-banana-1'
255290

256291
url = 'https://sourceforge.org/Artsy/Specs.git'
257292
Pathname.any_instance.stubs(:exist?).
258293
returns(true).then.returns(false)
259-
@sources_manager.send(:name_for_url, url).
260-
should == 'sourceforge-artsy-specs-1'
294+
@sources_manager.send(:name_for_url, url).should == 'sourceforge-artsy-1'
295+
296+
url = 'https://sourceforge.org/Artsy/Specs.git'
297+
Pathname.any_instance.stubs(:exist?).
298+
returns(true).then.
299+
returns(true).then.returns(false)
300+
@sources_manager.send(:name_for_url, url).should == 'sourceforge-artsy-2'
261301
end
262302
end
263303

0 commit comments

Comments
 (0)