Skip to content

Commit 5dc3d0d

Browse files
authored
2 parents 95d27a8 + 46ba19a commit 5dc3d0d

File tree

3 files changed

+342
-6
lines changed

3 files changed

+342
-6
lines changed

CHANGES

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,20 @@ $ pip install --user --upgrade --pre libvcs
1515

1616
<!-- Maintainers, insert changes / features for the next release here -->
1717

18+
### New features
19+
20+
### urls: AWS CodeCommit support (#443)
21+
22+
- Support for [AWS CodeCommit] URL patterns. Examples:
23+
24+
- HTTPS: `https://git-codecommit.us-east-1.amazonaws.com/v1/repos/test`
25+
- SSH: `ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/test`
26+
- HTTPS (GRC):
27+
- `codecommit::us-east-1://test`
28+
- `codecommit://test`
29+
30+
[AWS CodeCommit]: https://docs.aws.amazon.com/codecommit/
31+
1832
### Breaking changes
1933

2034
#### urls: Variable changes (#463)

src/libvcs/url/git.py

Lines changed: 225 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from .constants import RE_PIP_REV, RE_SCP, RE_USER
2727

2828
RE_PATH = r"""
29-
(?P<hostname>([^/:]+))
29+
(?P<hostname>([^/:@]+))
3030
(:(?P<port>\d{1,5}))?
3131
(?P<separator>[:,/])?
3232
(?P<path>
@@ -108,6 +108,95 @@
108108
)
109109
"""
110110

111+
AWS_CODE_COMMIT_DEFAULT_RULES: list[Rule] = [
112+
Rule(
113+
label="aws-code-commit-https",
114+
description="AWS CodeCommit HTTPS-style",
115+
pattern=re.compile(
116+
rf"""
117+
https://git-codecommit\.
118+
((?P<region>[^/]+)\.)
119+
# Server, e.g. 'github.com'.
120+
(?P<hostname>([^/:]+))
121+
(?P<separator>:)?
122+
# The server-side path. e.g. 'user/project.git'. Must start with an
123+
# alphanumeric character so as not to be confusable with a Windows paths
124+
# like 'C:/foo/bar' or 'C:\foo\bar'.
125+
(?P<path>(\w[^:.]+))?
126+
{RE_PIP_REV}?
127+
""",
128+
re.VERBOSE,
129+
),
130+
is_explicit=True,
131+
),
132+
Rule(
133+
label="aws-code-commit-ssh",
134+
description="AWS CodeCommit SSH-style",
135+
pattern=re.compile(
136+
rf"""
137+
ssh://git-codecommit\.
138+
((?P<region>[^/]+)\.)
139+
# Server, e.g. 'github.com'.
140+
(?P<hostname>([^/:]+))
141+
(?P<separator>:)?
142+
# The server-side path. e.g. 'user/project.git'. Must start with an
143+
# alphanumeric character so as not to be confusable with a Windows paths
144+
# like 'C:/foo/bar' or 'C:\foo\bar'.
145+
(?P<path>(\w[^:.]+))?
146+
{RE_PIP_REV}?
147+
""",
148+
re.VERBOSE,
149+
),
150+
is_explicit=True,
151+
),
152+
Rule(
153+
label="aws-code-commit-https-grc",
154+
description="AWS CodeCommit git repository",
155+
pattern=re.compile(
156+
rf"""
157+
codecommit://
158+
{RE_PATH}
159+
{RE_PIP_REV}?
160+
""",
161+
re.VERBOSE,
162+
),
163+
is_explicit=True,
164+
weight=0,
165+
),
166+
Rule(
167+
label="aws-code-commit-https-grc-with-region",
168+
description="AWS CodeCommit git repository with region",
169+
pattern=re.compile(
170+
rf"""
171+
codecommit::
172+
(?P<region>[^/]+)
173+
://
174+
{RE_PATH}
175+
{RE_PIP_REV}?
176+
""",
177+
re.VERBOSE,
178+
),
179+
is_explicit=True,
180+
weight=0,
181+
),
182+
]
183+
"""AWS CodeCommit-style git URLs.
184+
185+
Examples of CodeCommit-style git URLs (via AWS)::
186+
187+
codecommit://MyDemoRepo
188+
codecommit://`CodeCommitProfile`@MyDemoRepo
189+
codecommit::ap-northeast-1://MyDemoRepo
190+
191+
Notes
192+
-----
193+
194+
- https://aws.amazon.com/codecommit/
195+
- https://docs.aws.amazon.com/codecommit/
196+
- https://docs.aws.amazon.com/codecommit/latest/userguide/setting-up-git-remote-codecommit.html#:~:text=For%20example%2C%20to%20clone%20a%20repository%20named
197+
"""
198+
199+
111200
PIP_DEFAULT_RULES: list[Rule] = [
112201
Rule(
113202
label="pip-url",
@@ -363,6 +452,141 @@ def to_url(self) -> str:
363452
return "".join(part for part in parts if isinstance(part, str))
364453

365454

455+
@dataclasses.dataclass(repr=False)
456+
class GitAWSCodeCommitURL(
457+
GitBaseURL,
458+
URLProtocol,
459+
SkipDefaultFieldsReprMixin,
460+
):
461+
"""Supports AWS CodeCommit git URLs."""
462+
463+
# AWS CodeCommit Region
464+
region: Optional[str] = None
465+
# commit-ish (rev): tag, branch, ref
466+
rev: Optional[str] = None
467+
468+
rule_map = RuleMap(_rule_map={m.label: m for m in AWS_CODE_COMMIT_DEFAULT_RULES})
469+
470+
def to_url(self) -> str:
471+
"""Export AWS CodeCommit-compliant URL.
472+
473+
Examples
474+
--------
475+
HTTPS (GRC, a.k.a. git-remote-codecommit) URL:
476+
477+
>>> git_url = GitAWSCodeCommitURL(
478+
... url='codecommit://test'
479+
... )
480+
481+
>>> git_url
482+
GitAWSCodeCommitURL(url=codecommit://test,
483+
hostname=test,
484+
rule=aws-code-commit-https-grc)
485+
486+
>>> git_url = GitAWSCodeCommitURL(
487+
... url='codecommit::us-east-1://test'
488+
... )
489+
490+
>>> git_url
491+
GitAWSCodeCommitURL(url=codecommit::us-east-1://test,
492+
hostname=test,
493+
rule=aws-code-commit-https-grc-with-region,
494+
region=us-east-1)
495+
496+
>>> git_url.path = 'libvcs/vcspull'
497+
498+
>>> git_url.to_url()
499+
'codecommit::us-east-1://libvcs/vcspull'
500+
501+
It also accepts revisions, e.g. branch, tag, ref:
502+
503+
>>> git_url = GitAWSCodeCommitURL(
504+
... url='codecommit::us-east-1://test@v0.10.0'
505+
... )
506+
507+
>>> git_url
508+
GitAWSCodeCommitURL(url=codecommit::us-east-1://test@v0.10.0,
509+
hostname=test,
510+
rule=aws-code-commit-https-grc-with-region,
511+
region=us-east-1,
512+
rev=v0.10.0)
513+
514+
>>> git_url.path = 'libvcs/vcspull'
515+
516+
>>> git_url.to_url()
517+
'codecommit::us-east-1://libvcs/vcspull@v0.10.0'
518+
"""
519+
url = super().to_url()
520+
521+
"""Return an AWS CodeCommit-compatible URL."""
522+
523+
if isinstance(self.rule, str) and self.rule.startswith(
524+
"aws-code-commit-https-grc",
525+
):
526+
if self.region:
527+
url = f"codecommit::{self.region}://{self.path}"
528+
elif self.user:
529+
url = f"codecommit://{self.user}@{self.path}"
530+
else:
531+
url = f"codecommit://{self.path}"
532+
533+
if self.rev:
534+
url = f"{url}@{self.rev}"
535+
return url
536+
537+
@classmethod
538+
def is_valid(cls, url: str, is_explicit: Optional[bool] = None) -> bool:
539+
"""Whether URL is compatible with AWS CodeCommit Git's VCS URL pattern or not.
540+
541+
Examples
542+
--------
543+
Will **not** match normal ``git(1)`` URLs, use :meth:`GitURL.is_valid` for that.
544+
545+
>>> GitAWSCodeCommitURL.is_valid(url='https://github.com/vcs-python/libvcs.git')
546+
False
547+
548+
>>> GitAWSCodeCommitURL.is_valid(url='git@github.com:vcs-python/libvcs.git')
549+
False
550+
551+
AWS CodeCommit HTTPS URL:
552+
553+
>>> GitAWSCodeCommitURL.is_valid(
554+
... url='https://git-codecommit.us-east-1.amazonaws.com/v1/repos/test',
555+
... )
556+
True
557+
558+
AWS CodeCommit HTTPS (GRC) URLs:
559+
560+
>>> GitAWSCodeCommitURL.is_valid(url='codecommit::ap-northeast-1://MyDemoRepo')
561+
True
562+
563+
>>> GitAWSCodeCommitURL.is_valid(url='codecommit://MyDemoRepo')
564+
True
565+
566+
AWS CodeCommit SSH URL:
567+
568+
>>> GitAWSCodeCommitURL.is_valid(
569+
... url='ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/test',
570+
... )
571+
True
572+
573+
>>> GitAWSCodeCommitURL.is_valid(url='notaurl')
574+
False
575+
576+
**Explicit VCS detection**
577+
578+
AWS CodeCommit-style URLs are prefixed with the VCS name in front, so its
579+
`rule_map` can unambiguously narrow the type of VCS:
580+
581+
>>> GitAWSCodeCommitURL.is_valid(
582+
... url='ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/test',
583+
... is_explicit=True,
584+
... )
585+
True
586+
"""
587+
return super().is_valid(url=url, is_explicit=is_explicit)
588+
589+
366590
@dataclasses.dataclass(repr=False)
367591
class GitPipURL(
368592
GitBaseURL,

0 commit comments

Comments
 (0)