Skip to content

Commit ce795d5

Browse files
committed
GitService: Improve hostname extraction
This commit adds support for more repository notations and provides unit tests.
1 parent a476c95 commit ce795d5

File tree

3 files changed

+77
-6
lines changed

3 files changed

+77
-6
lines changed

lib/modulesync/git_service.rb

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,11 @@ def self.endpoint_for(sourcecode:, type:)
8989
end
9090

9191
# This method attempts to guess the git service endpoint based on remote and type
92-
# FIXME: It only supports "git@hostname:repo_path" scheme
9392
def self.guess_endpoint_from(remote:, type:)
94-
pattern = /^git@(.*):(.*)(\.git)*$/
95-
return nil unless remote.match?(pattern)
93+
hostname = extract_hostname(remote)
94+
return nil if hostname.nil?
9695

97-
endpoint = remote.sub(pattern, 'https://\1')
96+
endpoint = "https://#{hostname}"
9897
endpoint += '/api/v4' if type == :gitlab
9998
endpoint
10099
end
@@ -121,5 +120,31 @@ def self.token_for(sourcecode:, type:)
121120

122121
token
123122
end
123+
124+
# This method extracts hostname from URL like:
125+
#
126+
# - ssh://[user@]host.xz[:port]/path/to/repo.git/
127+
# - git://host.xz[:port]/path/to/repo.git/
128+
# - [user@]host.xz:path/to/repo.git/
129+
# - http[s]://host.xz[:port]/path/to/repo.git/
130+
# - ftp[s]://host.xz[:port]/path/to/repo.git/
131+
#
132+
# Returns nil if
133+
# - /path/to/repo.git/
134+
# - file:///path/to/repo.git/
135+
# - any invalid URL
136+
def self.extract_hostname(url)
137+
#pattern = /^((?<user>.*)@)*(?<hostname>.*):(?<path>[a-zA-Z].*)*$/
138+
return nil if url.start_with?('/') || url.start_with?('file://') # local path (e.g. file:///path/to/repo)
139+
140+
unless url.start_with?(/[a-z]+:\/\//) # SSH notation does not contain protocol (e.g. user@server:path/to/repo/)
141+
pattern = /^(.*@)?(?<hostname>[\w|.]*):(.*)$/ # SSH path (e.g. user@server:repo)
142+
return url.match(pattern)[:hostname] if url.match?(pattern)
143+
end
144+
145+
return URI.parse(url).host
146+
rescue URI::InvalidURIError => e
147+
return nil
148+
end
124149
end
125150
end

lib/modulesync/source_code.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,15 @@ def path(*parts)
4848
File.join(working_directory, *parts)
4949
end
5050

51+
def git_service
52+
@git_service ||= GitService.instantiate(**git_service_configuration)
53+
end
54+
55+
def git_service_configuration
56+
@git_service_configuration ||= GitService.configuration_for(sourcecode: self)
57+
end
58+
5159
def open_pull_request
52-
git_service_options = GitService.configuration_for(sourcecode: self)
53-
git_service = GitService.instantiate(**git_service_options)
5460
git_service.open_pull_request(
5561
repo_path: repository_path,
5662
namespace: repository_namespace,

spec/unit/modulesync/git_service_spec.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require 'modulesync'
12
require 'modulesync/git_service'
23

34
describe ModuleSync::GitService do
@@ -164,4 +165,43 @@
164165
end
165166
end
166167
end
168+
169+
RSpec.shared_examples 'hostname_extractor' do |url, hostname|
170+
context "with '#{url}' URL" do
171+
subject { ModuleSync::GitService.extract_hostname(url) }
172+
it "should extract '#{hostname}' as hostname" do
173+
expect(subject).to eq(hostname)
174+
end
175+
end
176+
end
177+
178+
context '#extract_hostname' do
179+
[
180+
%w[ssh://user@host.xz:4444/path/to/repo.git/ host.xz],
181+
%w[ssh://user@host.xz:/path/to/repo.git/ host.xz],
182+
%w[ssh://host.xz/path/to/repo.git/ host.xz],
183+
184+
%w[git://host.xz/path/to/repo.git/ host.xz],
185+
%w[git://host.xz/path/to/repo/ host.xz],
186+
%w[git://host.xz/path/to/repo host.xz],
187+
188+
%w[user@host.xz:path/to/repo.git/ host.xz],
189+
%w[user@host.xz:path/to/repo.git host.xz],
190+
%w[user@host.xz:path/to/repo host.xz],
191+
%w[host.xz:path/to/repo.git/ host.xz],
192+
193+
%w[https://host.xz:8443/path/to/repo.git/ host.xz],
194+
%w[https://host.xz/path/to/repo.git/ host.xz],
195+
196+
%w[ftp://host.xz/path/to/repo/ host.xz],
197+
198+
['/path/to/repo.git/', nil],
199+
200+
['file:///path/to/repo.git/', nil],
201+
202+
['something-invalid', nil],
203+
].each do |url, hostname|
204+
it_should_behave_like 'hostname_extractor', url, hostname
205+
end
206+
end
167207
end

0 commit comments

Comments
 (0)