Skip to content

Commit 084c361

Browse files
committed
refactor(parser,git): Split BaseGitURL from compatibility focused one
1 parent a6955f3 commit 084c361

File tree

3 files changed

+46
-8
lines changed

3 files changed

+46
-8
lines changed

libvcs/parse/base.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,28 @@ class MatcherRegistry(SkipDefaultFieldsReprMixin):
3838

3939
def register(self, cls: Matcher) -> None:
4040
"""
41-
>>> from libvcs.parse.git import GitURL
41+
42+
.. currentmodule:: libvcs.parse.git
43+
44+
>>> from libvcs.parse.git import GitURL, GitBaseURL
45+
46+
:class:`GitBaseURL` - the ``git(1)`` compliant parser - won't accept a pip-style URL:
47+
48+
>>> GitBaseURL.is_valid(url="git+ssh://git@github.com/tony/AlgoXY.git")
49+
False
50+
51+
:class:`GitURL` - the "batteries-included" parser - can do it:
4252
4353
>>> GitURL.is_valid(url="git+ssh://git@github.com/tony/AlgoXY.git")
54+
True
55+
56+
But what if you wanted to do ``github:org/repo``?
57+
58+
>>> GitURL.is_valid(url="github:org/repo")
4459
False
4560
61+
**Extending matching capability:**
62+
4663
>>> class GitHubPrefix(Matcher):
4764
... label = 'gh-prefix'
4865
... description ='Matches prefixes like github:org/repo'
@@ -95,9 +112,15 @@ def register(self, cls: Matcher) -> None:
95112
96113
git URLs + pip-style git URLs:
97114
115+
This is already in :class:`GitURL` via :data:`PIP_DEFAULT_MATCHERS`. For the
116+
sake of showing how extensibility works, here is a recreation based on
117+
:class:`GitBaseURL`:
118+
119+
>>> from libvcs.parse.git import GitBaseURL
120+
98121
>>> from libvcs.parse.git import DEFAULT_MATCHERS, PIP_DEFAULT_MATCHERS
99122
100-
>>> class GitURLWithPip(GitURL):
123+
>>> class GitURLWithPip(GitBaseURL):
101124
... matchers = MatcherRegistry = MatcherRegistry(
102125
... _matchers={m.label: m for m in [*DEFAULT_MATCHERS, *PIP_DEFAULT_MATCHERS]}
103126
... )

libvcs/parse/git.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
"""This module is an all-in-one parser and validator for Git URLs.
22
33
- Detection: :meth:`GitURL.is_valid()`
4-
- Parse: :class:`GitURL`
4+
- Parse:
55
66
compare to :class:`urllib.parse.ParseResult`
77
8-
- Output ``git(1)`` URL: :meth:`GitURL.to_url()`
8+
- Compatibility focused: :class:`GitURL`: Will work with ``git(1)`` as well as
9+
``pip(1)`` style URLs
10+
11+
- Output ``git(1)`` URL: :meth:`GitURL.to_url()`
12+
- Strict ``git(1)`` compatibility: :class:`GitBaseURL`.
13+
14+
- Output ``git(1)`` URL: :meth:`GitBaseURL.to_url()`
915
- Extendable via :class:`~libvcs.parse.base.MatcherRegistry`,
1016
:class:`~libvcs.parse.base.Matcher`
1117
"""
@@ -200,7 +206,7 @@
200206

201207

202208
@dataclasses.dataclass(repr=False)
203-
class GitURL(URLProtocol, SkipDefaultFieldsReprMixin):
209+
class GitBaseURL(URLProtocol, SkipDefaultFieldsReprMixin):
204210
"""Git gepository location. Parses URLs on initialization.
205211
206212
Examples
@@ -333,3 +339,12 @@ def to_url(self) -> str:
333339
parts.append(self.suffix)
334340

335341
return "".join(part for part in parts if isinstance(part, str))
342+
343+
344+
@dataclasses.dataclass(repr=False)
345+
class GitURL(GitBaseURL, URLProtocol, SkipDefaultFieldsReprMixin):
346+
"""Batteries included URL Parser. Supports git(1) and pip URLs."""
347+
348+
matchers = MatcherRegistry = MatcherRegistry(
349+
_matchers={m.label: m for m in [*DEFAULT_MATCHERS, *PIP_DEFAULT_MATCHERS]}
350+
)

tests/parse/test_git.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import pytest
44

55
from libvcs.parse.base import MatcherRegistry
6-
from libvcs.parse.git import DEFAULT_MATCHERS, PIP_DEFAULT_MATCHERS, GitURL
6+
from libvcs.parse.git import DEFAULT_MATCHERS, PIP_DEFAULT_MATCHERS, GitBaseURL, GitURL
77
from libvcs.projects.git import GitProject
88

99

@@ -141,7 +141,7 @@ def test_git_url_extension_pip(
141141
git_url_kwargs: GitURLKwargs,
142142
git_repo: GitProject,
143143
):
144-
class GitURLWithPip(GitURL):
144+
class GitURLWithPip(GitBaseURL):
145145
matchers = MatcherRegistry = MatcherRegistry(
146146
_matchers={m.label: m for m in [*DEFAULT_MATCHERS, *PIP_DEFAULT_MATCHERS]}
147147
)
@@ -152,7 +152,7 @@ class GitURLWithPip(GitURL):
152152
git_url.url = git_url.url.format(local_repo=git_repo.dir)
153153

154154
assert (
155-
GitURL.is_valid(url) != is_valid
155+
GitBaseURL.is_valid(url) != is_valid
156156
), f"{url} compatibility should work with core, expects {not is_valid}"
157157
assert (
158158
GitURLWithPip.is_valid(url) == is_valid

0 commit comments

Comments
 (0)