Skip to content

Commit cf8d1a7

Browse files
committed
Make Git::URL.clone_to handle cloning to bare and mirror repos
Signed-off-by: James Couball <jcouball@yahoo.com>
1 parent 13471d7 commit cf8d1a7

File tree

4 files changed

+171
-148
lines changed

4 files changed

+171
-148
lines changed

lib/git/url.rb

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def self.parse(url)
5252
end
5353
end
5454

55-
# The name `git clone` would use for the repository directory for the given URL
55+
# The directory `git clone` would use for the repository directory for the given URL
5656
#
5757
# @example
5858
# Git::URL.clone_to('https://github.com/ruby-git/ruby-git.git') #=> 'ruby-git'
@@ -61,12 +61,17 @@ def self.parse(url)
6161
#
6262
# @return [String] the name of the repository directory
6363
#
64-
def self.clone_to(url)
64+
def self.clone_to(url, bare: false, mirror: false)
6565
uri = parse(url)
6666
path_parts = uri.path.split('/')
6767
path_parts.pop if path_parts.last == '.git'
68-
69-
path_parts.last.sub(/\.git$/, '')
68+
directory = path_parts.last
69+
if bare || mirror
70+
directory += '.git' unless directory.end_with?('.git')
71+
elsif directory.end_with?('.git')
72+
directory = directory[0..-5]
73+
end
74+
directory
7075
end
7176
end
7277

tests/units/test_url.rb

Lines changed: 0 additions & 144 deletions
This file was deleted.

tests/units/test_url_clone_to.rb

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# frozen_string_literal: true
2+
3+
require 'test/unit'
4+
5+
# Tests Git::URL.clone_to
6+
#
7+
class TestURLCloneTo < Test::Unit::TestCase
8+
def test_clone_to_full_repo
9+
GIT_URLS.each do |url_data|
10+
url = url_data[:url]
11+
expected_path = url_data[:expected_path]
12+
actual_path = Git::URL.clone_to(url)
13+
assert_equal(
14+
expected_path, actual_path,
15+
"Failed to determine the clone path for URL '#{url}' correctly"
16+
)
17+
end
18+
end
19+
20+
def test_clone_to_bare_repo
21+
GIT_URLS.each do |url_data|
22+
url = url_data[:url]
23+
expected_path = url_data[:expected_bare_path]
24+
actual_path = Git::URL.clone_to(url, bare: true)
25+
assert_equal(
26+
expected_path, actual_path,
27+
"Failed to determine the clone path for URL '#{url}' correctly"
28+
)
29+
end
30+
end
31+
32+
def test_clone_to_mirror_repo
33+
GIT_URLS.each do |url_data|
34+
url = url_data[:url]
35+
# The expected_path is the same for bare and mirror repos
36+
expected_path = url_data[:expected_bare_path]
37+
actual_path = Git::URL.clone_to(url, mirror: true)
38+
assert_equal(
39+
expected_path, actual_path,
40+
"Failed to determine the clone path for URL '#{url}' correctly"
41+
)
42+
end
43+
end
44+
45+
GIT_URLS = [
46+
{
47+
url: 'https://github.com/org/repo',
48+
expected_path: 'repo',
49+
expected_bare_path: 'repo.git'
50+
},
51+
{
52+
url: 'https://github.com/org/repo.git',
53+
expected_path: 'repo',
54+
expected_bare_path: 'repo.git'
55+
},
56+
{
57+
url: 'https://git.mydomain.com/org/repo/.git',
58+
expected_path: 'repo',
59+
expected_bare_path: 'repo.git'
60+
}
61+
].freeze
62+
end

tests/units/test_url_parse.rb

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# frozen_string_literal: true
2+
3+
require 'test/unit'
4+
5+
# Tests Git::URL.parse
6+
#
7+
class TestURLParse < Test::Unit::TestCase
8+
def test_parse_with_invalid_url
9+
url = 'user@host.xz:/path/to/repo.git/'
10+
assert_raise(Addressable::URI::InvalidURIError) do
11+
Git::URL.parse(url)
12+
end
13+
end
14+
15+
def test_parse
16+
GIT_URLS.each do |url_data|
17+
url = url_data[:url]
18+
expected_uri = url_data[:expected_uri]
19+
actual_uri = Git::URL.parse(url).to_hash.delete_if { |_key, value| value.nil? }
20+
assert_equal(expected_uri, actual_uri, "Failed to parse URL '#{url}' correctly")
21+
end
22+
end
23+
24+
# For any URL, #to_s should return the url passed to Git::URL.parse(url)
25+
def test_to_s
26+
GIT_URLS.each do |url_data|
27+
url = url_data[:url]
28+
to_s = Git::URL.parse(url).to_s
29+
assert_equal(url, to_s, "Parsed URI#to_s does not return the original URL '#{url}' correctly")
30+
end
31+
end
32+
33+
GIT_URLS = [
34+
{
35+
url: 'ssh://host.xz/path/to/repo.git/',
36+
expected_uri: { scheme: 'ssh', host: 'host.xz', path: '/path/to/repo.git/' }
37+
},
38+
{
39+
url: 'ssh://host.xz:4443/path/to/repo.git/',
40+
expected_uri: { scheme: 'ssh', host: 'host.xz', port: 4443, path: '/path/to/repo.git/' }
41+
},
42+
{
43+
url: 'ssh:///path/to/repo.git/',
44+
expected_uri: { scheme: 'ssh', host: '', path: '/path/to/repo.git/' }
45+
},
46+
{
47+
url: 'user@host.xz:path/to/repo.git/',
48+
expected_uri: { scheme: 'git-alt', user: 'user', host: 'host.xz', path: '/path/to/repo.git/' }
49+
},
50+
{
51+
url: 'host.xz:path/to/repo.git/',
52+
expected_uri: { scheme: 'git-alt', host: 'host.xz', path: '/path/to/repo.git/' }
53+
},
54+
{
55+
url: 'git://host.xz:4443/path/to/repo.git/',
56+
expected_uri: { scheme: 'git', host: 'host.xz', port: 4443, path: '/path/to/repo.git/' }
57+
},
58+
{
59+
url: 'git://user@host.xz:4443/path/to/repo.git/',
60+
expected_uri: { scheme: 'git', user: 'user', host: 'host.xz', port: 4443, path: '/path/to/repo.git/' }
61+
},
62+
{
63+
url: 'https://host.xz/path/to/repo.git/',
64+
expected_uri: { scheme: 'https', host: 'host.xz', path: '/path/to/repo.git/' }
65+
},
66+
{
67+
url: 'https://host.xz:4443/path/to/repo.git/',
68+
expected_uri: { scheme: 'https', host: 'host.xz', port: 4443, path: '/path/to/repo.git/' }
69+
},
70+
{
71+
url: 'ftps://host.xz:4443/path/to/repo.git/',
72+
expected_uri: { scheme: 'ftps', host: 'host.xz', port: 4443, path: '/path/to/repo.git/' }
73+
},
74+
{
75+
url: 'ftps://host.xz:4443/path/to/repo.git/',
76+
expected_uri: { scheme: 'ftps', host: 'host.xz', port: 4443, path: '/path/to/repo.git/' }
77+
},
78+
{
79+
url: 'file:./relative-path/to/repo.git/',
80+
expected_uri: { scheme: 'file', path: './relative-path/to/repo.git/' }
81+
},
82+
{
83+
url: 'file:///path/to/repo.git/',
84+
expected_uri: { scheme: 'file', host: '', path: '/path/to/repo.git/' }
85+
},
86+
{
87+
url: 'file:///path/to/repo.git',
88+
expected_uri: { scheme: 'file', host: '', path: '/path/to/repo.git' }
89+
},
90+
{
91+
url: 'file://host.xz/path/to/repo.git',
92+
expected_uri: { scheme: 'file', host: 'host.xz', path: '/path/to/repo.git' }
93+
},
94+
{ url: '/path/to/repo.git/', expected_uri: { path: '/path/to/repo.git/' } },
95+
{ url: '/path/to/bare-repo/.git', expected_uri: { path: '/path/to/bare-repo/.git' } },
96+
{ url: 'relative-path/to/repo.git/', expected_uri: { path: 'relative-path/to/repo.git/' } },
97+
{ url: './relative-path/to/repo.git/', expected_uri: { path: './relative-path/to/repo.git/' } },
98+
{ url: '../ruby-git/.git', expected_uri: { path: '../ruby-git/.git' } }
99+
].freeze
100+
end

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy