SVN URL Parser - libvcs.url.svn#

For svn, aka svn(1).

Detect, parse, and validate SVN (Subversion) URLs.

Note

Subversion isn’t seen as often these days, can you β€œrage against the dying of the light” and assure its light is not extinguished? Help assure SVN URL parsing is correct and robust. Visit the project tracker and give us a wave. This API won’t be stabilized until we’re confident Subversion is covered accurately and can handle all-terrain scenarios.

libvcs.url.svn.DEFAULT_RULES: list[Rule] = [Rule(label=core-svn, description=Vanilla svn pattern, pattern=re.compile('\n        ^\n    (?P<scheme>\n      (\n        file|http|https|svn|svn\\+ssh\n      )\n    )\n\n        ://\n        \n    ((?P<user>[^/:@]+)@)?\n    (?P<hostname>([^/:@]+))\n    (:(?P<port>\\d{1,5}), re.VERBOSE), defaults={}), Rule(label=core-svn-scp, description=Vanilla scp(1) / ssh(1) type URL, pattern=re.compile("\n        ^(?P<scheme>ssh)?\n        \n    # Optional user, e.g. 'git@'\n    ((?P<user>\\w+)@)?\n    # Server, e.g. 'github.com'.\n    (?P<hostname>([^/:]+))\n    (?P<separator>:)\n    # The server-s, re.VERBOSE), defaults={'username': 'svn'})]#

Core regular expressions. These are patterns understood by svn(1)

libvcs.url.svn.PIP_DEFAULT_RULES: list[Rule] = [Rule(label=pip-url, description=pip-style svn URL, pattern=re.compile('\n        ^\n    (?P<scheme>\n      (\n        svn\\+ssh|\n        svn\\+https|\n        svn\\+http\n      )\n    )\n\n        ://\n        \n    ((?P<user>[^/:@]+)@)?\n    (?P<hostname>([^/:@]+))\n , re.VERBOSE), defaults={}, is_explicit=True), Rule(label=pip-file-url, description=pip-style svn+file:// URL, pattern=re.compile('\n        (?P<scheme>svn\\+file)://\n        (?P<path>.*)\n        ', re.VERBOSE), defaults={}, is_explicit=True)]#

pip-style svn URLs.

Examples of PIP-style svn URLs (via pip.pypa.io):

MyProject @ svn+https://svn.example.com/MyProject
MyProject @ svn+ssh://svn.example.com/MyProject
MyProject @ svn+ssh://user@svn.example.com/MyProject

Refs (via pip.pypa.io):

MyProject @ -e svn+http://svn.example.com/svn/MyProject/trunk@2019
MyProject @ -e svn+http://svn.example.com/svn/MyProject/trunk@{20080101}

Notes

class libvcs.url.svn.SvnBaseURL(url, scheme=None, user=None, hostname='', port=None, separator='/', path='', ref=None, rule=None)[source]#

Bases: URLProtocol, SkipDefaultFieldsReprMixin

SVN repository location. Parses URLs on initialization.

Examples

>>> SvnBaseURL(
...     url='svn+ssh://svn.debian.org/svn/aliothproj/path/in/project/repository')
SvnBaseURL(url=svn+ssh://svn.debian.org/svn/aliothproj/path/in/project/repository,
       scheme=svn+ssh,
       hostname=svn.debian.org,
       path=svn/aliothproj/path/in/project/repository,
       rule=core-svn)
>>> myrepo = SvnBaseURL(
...     url='svn+ssh://svn.debian.org/svn/aliothproj/path/in/project/repository'
... )
>>> myrepo.hostname
'svn.debian.org'
>>> myrepo.path
'svn/aliothproj/path/in/project/repository'
Parameters:
  • url (str) –

  • scheme (str | None) –

  • user (str | None) –

  • hostname (str) –

  • port (int | None) –

  • separator (str) –

  • path (str) –

  • ref (str | None) –

  • rule (str | None) –

rule#

name of the Rule

Type:

str

url: str#
scheme: Optional[str] = None#
user: Optional[str] = None#
hostname: str = ''#
port: Optional[int] = None#
separator: str = '/'#
path: str = ''#
ref: Optional[str] = None#
rule: Optional[str] = None#
rule_map = RuleMap(_rule_map={'core-svn': Rule(label=core-svn, description=Vanilla svn pattern, pattern=re.compile('\n        ^\n    (?P<scheme>\n      (\n        file|http|https|svn|svn\\+ssh\n      )\n    )\n\n        ://\n        \n    ((?P<user>[^/:@]+)@)?\n    (?P<hostname>([^/:@]+))\n    (:(?P<port>\\d{1,5}), re.VERBOSE), defaults={}), 'core-svn-scp': Rule(label=core-svn-scp, description=Vanilla scp(1) / ssh(1) type URL, pattern=re.compile("\n        ^(?P<scheme>ssh)?\n        \n    # Optional user, e.g. 'git@'\n    ((?P<user>\\w+)@)?\n    # Server, e.g. 'github.com'.\n    (?P<hostname>([^/:]+))\n    (?P<separator>:)\n    # The server-s, re.VERBOSE), defaults={'username': 'svn'})})#
classmethod is_valid(url, is_explicit=None)[source]#

Whether URL is compatible with VCS or not.

Return type:

bool

Parameters:
  • url (str) –

  • is_explicit (bool | None) –

Examples

>>> SvnBaseURL.is_valid(
...     url='svn+ssh://svn.debian.org/svn/aliothproj/path/in/project/repository'
... )
True
>>> SvnBaseURL.is_valid(url='notaurl')
False
to_url()[source]#

Return a svn(1)-compatible URL. Can be used with svn checkout.

Return type:

str

Examples

>>> svn_url = SvnBaseURL(
...     url='svn+ssh://my-username@my-server/vcs-python/libvcs'
... )
>>> svn_url
SvnBaseURL(url=svn+ssh://my-username@my-server/vcs-python/libvcs,
        scheme=svn+ssh,
        user=my-username,
        hostname=my-server,
        path=vcs-python/libvcs,
        rule=core-svn)

Switch repo libvcs -> vcspull:

>>> svn_url.path = 'vcs-python/vcspull'
>>> svn_url.to_url()
'svn+ssh://my-username@my-server/vcs-python/vcspull'

Switch user to β€œtom”:

>>> svn_url.user = 'tom'
>>> svn_url.to_url()
'svn+ssh://tom@my-server/vcs-python/vcspull'
_abc_impl = <_abc._abc_data object>#
_is_protocol = False#
class libvcs.url.svn.SvnPipURL(url, scheme=None, user=None, hostname='', port=None, separator='/', path='', ref=None, rule=None, rev=None)[source]#

Bases: SvnBaseURL, URLProtocol, SkipDefaultFieldsReprMixin

Supports pip svn URLs.

Parameters:
  • url (str) –

  • scheme (str | None) –

  • user (str | None) –

  • hostname (str) –

  • port (int | None) –

  • separator (str) –

  • path (str) –

  • ref (str | None) –

  • rule (str | None) –

  • rev (str | None) –

rev: Optional[str] = None#
rule_map = RuleMap(_rule_map={'pip-url': Rule(label=pip-url, description=pip-style svn URL, pattern=re.compile('\n        ^\n    (?P<scheme>\n      (\n        svn\\+ssh|\n        svn\\+https|\n        svn\\+http\n      )\n    )\n\n        ://\n        \n    ((?P<user>[^/:@]+)@)?\n    (?P<hostname>([^/:@]+))\n , re.VERBOSE), defaults={}, is_explicit=True), 'pip-file-url': Rule(label=pip-file-url, description=pip-style svn+file:// URL, pattern=re.compile('\n        (?P<scheme>svn\\+file)://\n        (?P<path>.*)\n        ', re.VERBOSE), defaults={}, is_explicit=True)})#
classmethod is_valid(url, is_explicit=None)[source]#

Whether URL is compatible with VCS or not.

Return type:

bool

Parameters:
  • url (str) –

  • is_explicit (bool | None) –

Examples

>>> SvnPipURL.is_valid(
...     url='svn+https://svn.project.org/project-central'
... )
True
>>> SvnPipURL.is_valid(url='svn+ssh://svn@svn.python.org:cpython')
True
>>> SvnPipURL.is_valid(url='notaurl')
False
to_url()[source]#

Return a svn(1)-compatible URL. Can be used with svn clone.

Return type:

str

Examples

>>> svn_url = SvnPipURL(url='svn+https://svn.project.org/project-central')
>>> svn_url
SvnPipURL(url=svn+https://svn.project.org/project-central,
        scheme=svn+https,
        hostname=svn.project.org,
        path=project-central,
        rule=pip-url)

Switch repo project-central -> mobile-browser:

>>> svn_url.path = 'mobile-browser'
>>> svn_url.to_url()
'svn+https://svn.project.org/mobile-browser'

Switch them to localhost:

>>> svn_url.hostname = 'localhost'
>>> svn_url.scheme = 'http'
>>> svn_url.to_url()
'http://localhost/mobile-browser'
_abc_impl = <_abc._abc_data object>#
_is_protocol = False#
class libvcs.url.svn.SvnURL(url, scheme=None, user=None, hostname='', port=None, separator='/', path='', ref=None, rule=None, rev=None)[source]#

Bases: SvnPipURL, SvnBaseURL, URLProtocol, SkipDefaultFieldsReprMixin

Batteries included URL Parser. Supports svn(1) and pip URLs.

Ancestors (MRO) This URL parser inherits methods and attributes from the following parsers:

Parameters:
  • url (str) –

  • scheme (str | None) –

  • user (str | None) –

  • hostname (str) –

  • port (int | None) –

  • separator (str) –

  • path (str) –

  • ref (str | None) –

  • rule (str | None) –

  • rev (str | None) –

rule_map = RuleMap(_rule_map={'core-svn': Rule(label=core-svn, description=Vanilla svn pattern, pattern=re.compile('\n        ^\n    (?P<scheme>\n      (\n        file|http|https|svn|svn\\+ssh\n      )\n    )\n\n        ://\n        \n    ((?P<user>[^/:@]+)@)?\n    (?P<hostname>([^/:@]+))\n    (:(?P<port>\\d{1,5}), re.VERBOSE), defaults={}), 'core-svn-scp': Rule(label=core-svn-scp, description=Vanilla scp(1) / ssh(1) type URL, pattern=re.compile("\n        ^(?P<scheme>ssh)?\n        \n    # Optional user, e.g. 'git@'\n    ((?P<user>\\w+)@)?\n    # Server, e.g. 'github.com'.\n    (?P<hostname>([^/:]+))\n    (?P<separator>:)\n    # The server-s, re.VERBOSE), defaults={'username': 'svn'}), 'pip-url': Rule(label=pip-url, description=pip-style svn URL, pattern=re.compile('\n        ^\n    (?P<scheme>\n      (\n        svn\\+ssh|\n        svn\\+https|\n        svn\\+http\n      )\n    )\n\n        ://\n        \n    ((?P<user>[^/:@]+)@)?\n    (?P<hostname>([^/:@]+))\n , re.VERBOSE), defaults={}, is_explicit=True), 'pip-file-url': Rule(label=pip-file-url, description=pip-style svn+file:// URL, pattern=re.compile('\n        (?P<scheme>svn\\+file)://\n        (?P<path>.*)\n        ', re.VERBOSE), defaults={}, is_explicit=True)})#
_abc_impl = <_abc._abc_data object>#
_is_protocol = False#
classmethod is_valid(url, is_explicit=None)[source]#

Whether URL is compatible included Svn URL rule_map or not.

Return type:

bool

Parameters:
  • url (str) –

  • is_explicit (bool | None) –

Examples

Will match normal svn(1) URLs, use SvnURL.is_valid() for that.

>>> SvnURL.is_valid(
... url='https://svn.project.org/project-central/project-central')
True
>>> SvnURL.is_valid(url='svn@svn.project.org:MyProject/project')
True

Pip-style URLs:

>>> SvnURL.is_valid(url='svn+https://svn.project.org/project-central/project')
True
>>> SvnURL.is_valid(url='svn+ssh://svn@svn.project.org:MyProject/project')
True
>>> SvnURL.is_valid(url='notaurl')
False

Explicit VCS detection

Pip-style URLs are prefixed with the VCS name in front, so its rule_map can unambiguously narrow the type of VCS:

>>> SvnURL.is_valid(
...     url='svn+ssh://svn@svn.project.org:project-central/image',
...     is_explicit=True
... )
True

Below, while it’s svn.project.org, that doesn’t necessarily mean that the URL itself is conclusively a svn URL (e.g. the pattern is too broad):

>>> SvnURL.is_valid(
...     url='svn@svn.project.org:project-central/image', is_explicit=True
... )
False

You could create a project rule that consider svn.project.org hostnames to be exclusively svn:

>>> projectRule = Rule(
...     # Since svn.project.org exclusively serves svn repos, make explicit
...     label='project-rule',
...     description='Matches svn.project.org https URLs, exact VCS match',
...     pattern=re.compile(
...         rf'''
...         ^(?P<scheme>ssh)?
...         ((?P<user>\w+)@)?
...         (?P<hostname>(svn.project.org)+):
...         (?P<path>(\w[^:]+))
...         ''',
...         re.VERBOSE,
...     ),
...     is_explicit=True,
...     defaults={
...         'hostname': 'svn.project.org'
...     }
... )
>>> SvnURL.rule_map.register(projectRule)
>>> SvnURL.is_valid(
...     url='svn@svn.project.org:project-central/image', is_explicit=True
... )
True
>>> SvnURL(url='svn@svn.project.org:project-central/image').rule
'project-rule'

This is just us cleaning up:

>>> SvnURL.rule_map.unregister('project-rule')
>>> SvnURL(url='svn@svn.project.org:project-central/project-rule').rule
'core-svn-scp'
to_url()[source]#

Return a svn(1)-compatible URL. Can be used with svn clone.

Return type:

str

Examples

SSH style URL:

>>> svn_url = SvnURL(url='svn@svn.project.org:project-central/browser')
>>> svn_url.path = 'project-central/gfx'
>>> svn_url.to_url()
'svn@svn.project.org:project-central/gfx'

HTTPs URL:

>>> svn_url = SvnURL(url='https://svn.project.org/project-central/memory')
>>> svn_url.path = 'project-central/image'
>>> svn_url.to_url()
'https://svn.project.org/project-central/image'

Switch them to svnlab:

>>> svn_url.hostname = 'localhost'
>>> svn_url.scheme = 'http'
>>> svn_url.to_url()
'http://localhost/project-central/image'

Pip style URL, thanks to this class implementing SvnPipURL:

>>> svn_url = SvnURL(url='svn+ssh://svn@svn.project.org/project-central/image')
>>> svn_url.hostname = 'localhost'
>>> svn_url.to_url()
'svn+ssh://svn@localhost/project-central/image'
>>> svn_url.user = None
>>> svn_url.to_url()
'svn+ssh://localhost/project-central/image'