Skip to content

Commit 5f7183e

Browse files
committed
Fix path/branch extraction stripping every marker occurrence
GitHubPlatform and GitLabPlatform built `path`/`branch` with str.replace(marker, ""), which removes *every* occurrence of the marker rather than only the leading one. A URL whose file path or branch name contained the same segment again was silently corrupted: parse('.../blob/main/src/blob/utils.py').path -> 'main/srcutils.py' parse('.../tree/feature/tree/x').branch -> 'featurex' The leading marker is already guaranteed by the preceding startswith check, so slice it off instead. Slicing (rather than str.removeprefix) keeps the declared Python 3.8 compatibility. Adds regression tests for nested /blob/ paths and /tree/ branch names on both GitHub and GitLab.
1 parent bcd0893 commit 5f7183e

4 files changed

Lines changed: 80 additions & 5 deletions

File tree

changes/PRNUM.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix ``path`` and ``branch`` extraction removing *every* ``/blob/`` and ``/tree/`` occurrence instead of only the leading marker, which corrupted file paths and branch names containing those segments.

giturlparse/platforms/github.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class GitHubPlatform(BasePlatform):
3434
def clean_data(data):
3535
data = BasePlatform.clean_data(data)
3636
if data["path_raw"].startswith("/blob/"):
37-
data["path"] = data["path_raw"].replace("/blob/", "")
37+
data["path"] = data["path_raw"][len("/blob/") :]
3838
if data["path_raw"].startswith("/tree/"):
39-
data["branch"] = data["path_raw"].replace("/tree/", "")
39+
data["branch"] = data["path_raw"][len("/tree/") :]
4040
return data

giturlparse/platforms/gitlab.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ class GitLabPlatform(BasePlatform):
3838
def clean_data(data):
3939
data = BasePlatform.clean_data(data)
4040
if data["path_raw"].startswith("/blob/"):
41-
data["path"] = data["path_raw"].replace("/blob/", "")
41+
data["path"] = data["path_raw"][len("/blob/") :]
4242
if data["path_raw"].startswith("/-/blob/"):
43-
data["path"] = data["path_raw"].replace("/-/blob/", "")
43+
data["path"] = data["path_raw"][len("/-/blob/") :]
4444
if data["path_raw"].startswith("/-/tree/"):
45-
data["branch"] = data["path_raw"].replace("/-/tree/", "")
45+
data["branch"] = data["path_raw"][len("/-/tree/") :]
4646
return data

giturlparse/tests/test_parse.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,80 @@
481481
},
482482
),
483483
),
484+
(
485+
"HTTPS",
486+
(
487+
# Regression: a file path that itself contains a "blob" directory must
488+
# not have the inner "/blob/" stripped (only the leading marker).
489+
"https://github.com/nephila/giturlparse/blob/master/giturlparse/blob/data.py",
490+
{
491+
"host": "github.com",
492+
"resource": "github.com",
493+
"port": "",
494+
"user": "git",
495+
"owner": "nephila",
496+
"repo": "giturlparse",
497+
"name": "giturlparse",
498+
"groups": [],
499+
"path": "master/giturlparse/blob/data.py",
500+
"path_raw": "/blob/master/giturlparse/blob/data.py",
501+
"pathname": "/nephila/giturlparse/blob/master/giturlparse/blob/data.py",
502+
"branch": "",
503+
"protocol": "https",
504+
"protocols": ["https"],
505+
"platform": "github",
506+
},
507+
),
508+
),
509+
(
510+
"HTTPS",
511+
(
512+
# Regression: a branch name containing "/tree/" must be preserved
513+
# in full rather than having every "/tree/" removed.
514+
"https://github.com/nephila/giturlparse/tree/feature/tree/x",
515+
{
516+
"host": "github.com",
517+
"resource": "github.com",
518+
"port": "",
519+
"user": "git",
520+
"owner": "nephila",
521+
"repo": "giturlparse",
522+
"name": "giturlparse",
523+
"groups": [],
524+
"path": "",
525+
"path_raw": "/tree/feature/tree/x",
526+
"pathname": "/nephila/giturlparse/tree/feature/tree/x",
527+
"branch": "feature/tree/x",
528+
"protocol": "https",
529+
"protocols": ["https"],
530+
"platform": "github",
531+
},
532+
),
533+
),
534+
(
535+
"HTTPS",
536+
(
537+
# Regression (GitLab): inner "/blob/" in the file path must survive.
538+
"https://gitlab.com/nephila/giturlparse/-/blob/master/giturlparse/blob/data.py",
539+
{
540+
"host": "gitlab.com",
541+
"resource": "gitlab.com",
542+
"port": "",
543+
"user": "git",
544+
"owner": "nephila",
545+
"repo": "giturlparse",
546+
"name": "giturlparse",
547+
"groups": [],
548+
"path": "master/giturlparse/blob/data.py",
549+
"path_raw": "/-/blob/master/giturlparse/blob/data.py",
550+
"pathname": "/nephila/giturlparse/-/blob/master/giturlparse/blob/data.py",
551+
"branch": "",
552+
"protocol": "https",
553+
"protocols": ["https"],
554+
"platform": "gitlab",
555+
},
556+
),
557+
),
484558
(
485559
"HTTPS",
486560
(

0 commit comments

Comments
 (0)