diff --git a/swh/lister/gitlab/lister.py b/swh/lister/gitlab/lister.py --- a/swh/lister/gitlab/lister.py +++ b/swh/lister/gitlab/lister.py @@ -103,6 +103,10 @@ credentials: Optional[CredentialsType] = None, incremental: bool = False, ): + # to ensure urljoin will produce valid Sources URL + if not url.endswith("/"): + url += "/" + if instance is None: instance = parse_url(url).host super().__init__( @@ -161,7 +165,7 @@ } if id_after is not None: parameters["id_after"] = str(id_after) - return f"{self.url}projects?{urlencode(parameters)}" + return f"{self.url.rstrip('/')}/projects?{urlencode(parameters)}" def get_pages(self) -> Iterator[PageResult]: next_page: Optional[str] diff --git a/swh/lister/gitlab/tests/test_lister.py b/swh/lister/gitlab/tests/test_lister.py --- a/swh/lister/gitlab/tests/test_lister.py +++ b/swh/lister/gitlab/tests/test_lister.py @@ -216,6 +216,16 @@ assert lister.session.headers["Authorization"] == "Bearer api-token" +def test_lister_gitlab_url_computation(swh_scheduler): + instance = "gitlab" + url = api_url(instance).rstrip("/") + assert not url.endswith("/") + + lister = GitLabLister(scheduler=swh_scheduler, url=url) + assert lister.url == api_url(instance) + assert lister.url.endswith("/") + + @pytest.mark.parametrize( "url,expected_result", [