Skip to content

Commit 2cf23b3

Browse files
committed
feat(svn,parse): Fixes and examples for Subversion URL Parsing
1 parent 350c43b commit 2cf23b3

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

libvcs/parse/svn.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,20 @@
2929
RE_PATH = r"""
3030
((?P<user>.*)@)?
3131
(?P<hostname>([^/:]+))
32-
(?P<separator>[:,/])?
32+
(:(?P<port>\d{1,4}))?
33+
(?P<separator>/)?
3334
(?P<path>
3435
(\w[^:.]*)
3536
)?
3637
"""
3738

39+
# Valid schemes for svn(1).
40+
# See Table 1.1 Repository access URLs in SVN Book
41+
# https://svnbook.red-bean.com/nightly/en/svn.basic.in-action.html#svn.basic.in-action.wc.tbl-1
3842
RE_SCHEME = r"""
3943
(?P<scheme>
4044
(
41-
http|https|
42-
svn\+ssh
45+
file|http|https|svn|svn\+ssh
4346
)
4447
)
4548
"""
@@ -154,10 +157,12 @@ class SvnURL(URLProtocol, SkipDefaultFieldsReprMixin):
154157
"""
155158

156159
url: str
157-
scheme: str = dataclasses.field(init=False)
158-
hostname: str = dataclasses.field(init=False)
159-
path: str = dataclasses.field(init=False)
160+
scheme: Optional[str] = None
160161
user: Optional[str] = None
162+
hostname: str = dataclasses.field(default="")
163+
port: Optional[int] = None
164+
separator: str = dataclasses.field(default="/")
165+
path: str = dataclasses.field(default="")
161166

162167
#
163168
# commit-ish: ref
@@ -213,9 +218,9 @@ def to_url(self) -> str:
213218
>>> svn_location
214219
SvnURL(url=svn+ssh://my-username@my-server/vcs-python/libvcs,
215220
scheme=svn+ssh,
221+
user=my-username,
216222
hostname=my-server,
217223
path=vcs-python/libvcs,
218-
user=my-username,
219224
matcher=core-svn)
220225
221226
Switch repo libvcs -> vcspull:
@@ -232,12 +237,15 @@ def to_url(self) -> str:
232237
>>> svn_location.to_url()
233238
'svn+ssh://tom@my-server/vcs-python/vcspull'
234239
"""
235-
if self.scheme is not None:
236-
parts = [self.scheme, "://"]
237-
if self.user:
238-
parts.extend([self.user, "@"])
239-
parts += [self.hostname, "/", self.path]
240-
else:
241-
parts = [self.user or "svn", "@", self.hostname, ":", self.path]
240+
parts = [self.scheme or "ssh", "://"]
241+
if self.user:
242+
parts.extend([self.user, "@"])
243+
244+
parts.append(self.hostname)
245+
246+
if self.port is not None:
247+
parts.extend([":", f"{self.port}"])
248+
249+
parts.extend([self.separator, self.path])
242250

243251
return "".join(part for part in parts if isinstance(part, str))

0 commit comments

Comments
 (0)