Skip to content

Commit

Permalink
normalize source vcs urls (#701)
Browse files Browse the repository at this point in the history
This change ensures when referencing source url for package
specifications of source type "git" or for VCS dependencies, a
normalized version returned at all times.

Relates-to: python-poetry/poetry#8999
  • Loading branch information
abn authored Feb 24, 2024
1 parent 219c52e commit 71d26d7
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 5 deletions.
13 changes: 12 additions & 1 deletion src/poetry/core/packages/specification.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def __init__(
self._pretty_name = name
self._name = canonicalize_name(name)
self._source_type = source_type
self._source_url = source_url
self._source_url = self._normalize_source_url(source_type, source_url)
self._source_reference = source_reference
self._source_resolved_reference = source_resolved_reference
self._source_subdirectory = source_subdirectory
Expand All @@ -45,6 +45,17 @@ def __init__(

self._features = frozenset(canonicalize_name(feature) for feature in features)

@staticmethod
def _normalize_source_url(
source_type: str | None, source_url: str | None
) -> str | None:
if source_type and source_url and source_type == "git":
from poetry.core.vcs.git import ParsedUrl

return ParsedUrl.parse(source_url).url

return source_url

@property
def name(self) -> NormalizedName:
return self._name
Expand Down
5 changes: 3 additions & 2 deletions src/poetry/core/packages/vcs_dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ def __init__(
# Attributes must be immutable for clone() to be safe!
# (For performance reasons, clone only creates a copy instead of a deep copy).
self._vcs = vcs
self._source = source

self._branch = branch
self._tag = tag
Expand All @@ -47,13 +46,15 @@ def __init__(
optional=optional,
allows_prereleases=True,
source_type=self._vcs.lower(),
source_url=self._source,
source_url=source,
source_reference=branch or tag or rev or "HEAD",
source_resolved_reference=resolved_rev,
source_subdirectory=directory,
extras=extras,
)

self._source = self.source_url or source

@property
def vcs(self) -> str:
return self._vcs
Expand Down
2 changes: 1 addition & 1 deletion src/poetry/core/vcs/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def parse(cls, url: str) -> ParsedUrl:
if m:
groups = m.groupdict()
return ParsedUrl(
groups.get("protocol"),
groups.get("protocol", "ssh"),
groups.get("resource"),
groups.get("pathname"),
groups.get("user"),
Expand Down
38 changes: 38 additions & 0 deletions tests/packages/test_specification.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,41 @@ def test_equal_specifications_have_same_hash(
assert spec1 == spec2
assert spec2 == spec1
assert hash(spec1) == hash(spec2)


@pytest.mark.parametrize(
"source_url,normalized_url",
[
("https://github.com/demo/demo.git", "https://github.com/demo/demo.git"),
("git@github.com:demo/demo.git", "ssh://git@github.com/demo/demo.git"),
],
)
def test_specification_normalize_source_url_method(
source_url: str, normalized_url: str
) -> None:
assert (
PackageSpecification._normalize_source_url("git", source_url) == normalized_url
)
assert (
PackageSpecification._normalize_source_url("notgit", source_url) == source_url
)


@pytest.mark.parametrize(
"source_url,normalized_url",
[
("https://github.com/demo/demo.git", "https://github.com/demo/demo.git"),
("git@github.com:demo/demo.git", "ssh://git@github.com/demo/demo.git"),
],
)
def test_specification_uses_normalize_source_url_for_git(
source_url: str, normalized_url: str
) -> None:
assert (
PackageSpecification(
name="demo",
source_type="git",
source_url=source_url,
).source_url
== normalized_url
)
18 changes: 18 additions & 0 deletions tests/packages/test_vcs_dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,21 @@ def test_vcs_dependencies_are_equal_if_resolved_references_match() -> None:
)

assert dependency1 == dependency2


@pytest.mark.parametrize(
"source_url,normalized_url",
[
("https://github.com/demo/demo.git", "https://github.com/demo/demo.git"),
("git@github.com:demo/demo.git", "ssh://git@github.com/demo/demo.git"),
],
)
def test_vcs_source_is_normalized(source_url: str, normalized_url: str) -> None:
dependency = VCSDependency(
name="demo",
vcs="git",
source=source_url,
branch="main",
)
assert dependency.source == normalized_url
assert dependency.source_url == normalized_url
2 changes: 1 addition & 1 deletion tests/vcs/test_vcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ def test_normalize_url(url: str, normalized: GitUrl) -> None:
),
(
"git@github.com:org/repo",
ParsedUrl(None, "github.com", ":org/repo", "git", None, "repo", None),
ParsedUrl("ssh", "github.com", ":org/repo", "git", None, "repo", None),
),
(
"git+https://github.com/sdispater/pendulum",
Expand Down

0 comments on commit 71d26d7

Please sign in to comment.