Skip to content

Commit 84cc8b1

Browse files
evanrittenhouseradoering
authored andcommitted
Correctly parse Git submodule URLs (#7017)
(cherry picked from commit 71b3d6e)
1 parent fc1014b commit 84cc8b1

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

src/poetry/vcs/git/backend.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from pathlib import Path
88
from subprocess import CalledProcessError
99
from typing import TYPE_CHECKING
10+
from urllib.parse import urljoin
1011

1112
from dulwich import porcelain
1213
from dulwich.client import HTTPUnauthorized
@@ -331,16 +332,24 @@ def _clone_submodules(cls, repo: Repo) -> None:
331332
repo_root = Path(repo.path)
332333
modules_config = repo_root.joinpath(".gitmodules")
333334

335+
# A relative URL by definition starts with ../ or ./
336+
relative_submodule_regex = re.compile(r"^\.{1,2}/")
337+
334338
if modules_config.exists():
335339
config = ConfigFile.from_path(str(modules_config))
336340

337341
url: bytes
338342
path: bytes
339343
submodules = parse_submodules(config)
344+
340345
for path, url, name in submodules:
341346
path_relative = Path(path.decode("utf-8"))
342347
path_absolute = repo_root.joinpath(path_relative)
343348

349+
url_string = url.decode("utf-8")
350+
if relative_submodule_regex.search(url_string):
351+
url_string = urljoin(f"{Git.get_remote_url(repo)}/", url_string)
352+
344353
source_root = path_absolute.parent
345354
source_root.mkdir(parents=True, exist_ok=True)
346355

@@ -357,7 +366,7 @@ def _clone_submodules(cls, repo: Repo) -> None:
357366
continue
358367

359368
cls.clone(
360-
url=url.decode("utf-8"),
369+
url=url_string,
361370
source_root=source_root,
362371
name=path_relative.name,
363372
revision=revision,

tests/integration/test_utils_vcs_git.py

+24
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,30 @@ def test_git_clone_clones_submodules(source_url: str) -> None:
240240
assert len(list(submodule_package_directory.glob("*"))) > 1
241241

242242

243+
def test_git_clone_clones_submodules_with_relative_urls(source_url: str) -> None:
244+
with Git.clone(url=source_url, branch="relative_submodule") as repo:
245+
submodule_package_directory = (
246+
Path(repo.path) / "submodules" / "relative-url-submodule"
247+
)
248+
249+
assert submodule_package_directory.exists()
250+
assert submodule_package_directory.joinpath("README.md").exists()
251+
assert len(list(submodule_package_directory.glob("*"))) > 1
252+
253+
254+
def test_git_clone_clones_submodules_with_relative_urls_and_explicit_base(
255+
source_url: str,
256+
) -> None:
257+
with Git.clone(url=source_url, branch="relative_submodule") as repo:
258+
submodule_package_directory = (
259+
Path(repo.path) / "submodules" / "relative-url-submodule-with-base"
260+
)
261+
262+
assert submodule_package_directory.exists()
263+
assert submodule_package_directory.joinpath("README.md").exists()
264+
assert len(list(submodule_package_directory.glob("*"))) > 1
265+
266+
243267
def test_system_git_fallback_on_http_401(
244268
mocker: MockerFixture,
245269
source_url: str,

0 commit comments

Comments
 (0)