Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/97.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix HTTP normalization and protocol rewrites for generic Git hosts.
8 changes: 5 additions & 3 deletions giturlparse/platforms/base.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import itertools
import re
from typing import ClassVar


class BasePlatform:
FORMATS = {
FORMATS: ClassVar[dict] = {
"http": r"http://%(domain)s/%(repo)s%(dot_git)s",
"https": r"https://%(domain)s/%(repo)s%(dot_git)s",
"ssh": r"git@%(domain)s:%(repo)s%(dot_git)s%(path_raw)s",
"git": r"git://%(domain)s/%(repo)s%(dot_git)s%(path_raw)s",
}

PATTERNS = {
PATTERNS: ClassVar[dict] = {
"ssh": r"(?P<_user>.+)@(?P<domain>[^/]+?):(?P<repo>.+)(?:(\.git)?(/)?)",
"http": r"(?P<protocols>(?P<protocol>http))://(?P<domain>[^/]+?)/(?P<repo>.+)(?:(\.git)?(/)?)",
"https": r"(?P<protocols>(?P<protocol>https))://(?P<domain>[^/]+?)/(?P<repo>.+)(?:(\.git)?(/)?)",
Expand All @@ -19,7 +21,7 @@ class BasePlatform:
# None means it matches all domains
DOMAINS = None
SKIP_DOMAINS = None
DEFAULTS = {}
DEFAULTS: ClassVar[dict] = {}

def __init__(self):
# Precompile PATTERNS
Expand Down
42 changes: 40 additions & 2 deletions giturlparse/tests/test_rewrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
class UrlRewriteTestCase(unittest.TestCase):
def _test_rewrite(self, source, protocol, expected):
parsed = parse(source)
self.assertTrue(parsed.valid, "Invalid Url: %s" % source)
self.assertTrue(parsed.valid, f"Invalid Url: {source}")
return self.assertEqual(parse(source).format(protocol), expected)

def test_rewrites(self):
Expand All @@ -98,13 +98,51 @@ def test_rewrites(self):
def _test_rewrite_components(self, field, data):
parsed = parse(data["source"])
setattr(parsed, field, data["value"])
self.assertTrue(parsed.valid, "Invalid Url: %s" % data["source"])
self.assertTrue(parsed.valid, f"Invalid Url: {data['source']}")
return self.assertEqual(parsed.url, data["expected"])

def test_rewrite_components(self):
for field, data in REWRITE_COMPONENTS.items():
self._test_rewrite_components(field, data)

def test_generic_http_normalized(self):
for domain in ("git.example.org", "git.example.org:8080"):
for repo in ("project", "project.git", "Org/project.git"):
source = f"http://{domain}/{repo}"
expected = source if repo.endswith(".git") else source + ".git"
with self.subTest(source=source):
parsed = parse(source)
self.assertTrue(parsed.valid)
self.assertEqual(parsed.platform, "base")
self.assertEqual(parsed.normalized, expected)

def test_generic_http_rewrites(self):
expected = {
"ssh": "git@git.example.org:project.git",
"http": "http://git.example.org/project.git",
"https": "https://git.example.org/project.git",
"git": "git://git.example.org/project.git",
}
for url in expected.values():
for suffix in ("", ".git"):
source = url[:-4] + suffix
parsed = parse(source)
with self.subTest(source=source, operation="urls"):
self.assertTrue(parsed.valid)
self.assertEqual(parsed.platform, "base")
self.assertEqual(parsed.urls, expected)
with self.subTest(source=source, operation="url2http"):
self.assertEqual(parsed.url2http, expected["http"])
self.assertEqual(parsed.format("http"), expected["http"])

def test_generic_http_name_update(self):
for source in ("http://git.example.org/project", "http://git.example.org/project.git"):
with self.subTest(source=source):
parsed = parse(source)
parsed.name = "new-project"
self.assertEqual(parsed.url, "http://git.example.org/new-project.git")
self.assertEqual(parsed.normalized, parsed.url)


# Test Suite
suite = unittest.TestLoader().loadTestsFromTestCase(UrlRewriteTestCase)
Loading