Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion src/fosslight_util/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ def get_remote_refs(git_url: str):
re.IGNORECASE,
)
_SEMVER_IN_REF = re.compile(
r'(?:^v\.? ?|[-_])'
r'(?:^v\.? ?|[-_]v\.? ?|[-_])'
r'(\d+)\.(\d+)\.(\d+)'
r'(?:(?:-[0-9A-Za-z.-]+)|(?:\.[A-Za-z][0-9A-Za-z.-]*))?'
r'(?:\+[0-9A-Za-z.-]+)?'
Expand Down Expand Up @@ -467,6 +467,48 @@ def _strip_leading_v_prefix(s: str) -> str:
return re.sub(r'^(?:v\.? ?)?', '', s.strip(), flags=re.IGNORECASE)


def _repo_name_from_git_url(git_url: str) -> str:
"""Extract repository name from common git HTTPS/SSH URLs."""
if not git_url:
return ""
url = git_url.strip().rstrip('/')
if url.endswith('.git'):
url = url[:-4]
m = re.match(r'git@[^:]+:[^/]+/([^/@?#]+)$', url)
if m:
return m.group(1)
path = urllib.parse.urlparse(url).path.strip('/')
if path:
segments = path.split('/')
if len(segments) >= 2:
return segments[-1]
return ""


def _repo_prefixed_version_refs(repo_name: str, base: str) -> List[str]:
"""Build {repo}-v{version} style tag candidates from checkout hint."""
if not repo_name or not base:
return []
base = base.strip()
core = _strip_leading_v_prefix(base)
if not core:
return []
repo = repo_name.strip()
candidates = [
f"{repo}-v{core}",
f"{repo}-v.{core}",
f"{repo}_{core}",
f"{repo}-{core}",
]
seen = set()
result = []
for candidate in candidates:
if candidate not in seen:
seen.add(candidate)
result.append(candidate)
return result


def _match_exact_or_v_prefix_ref(base: str, ref_set: set) -> Optional[str]:
"""Exact ref match, or ref equal to base after optional leading v/v./v."""
if base in ref_set:
Expand Down Expand Up @@ -558,11 +600,16 @@ def decide_checkout(checkout_to="", tag="", branch="", git_url=""):
tag_set = set(ref_dict.get("tags", []))
branch_set = set(ref_dict.get("branches", []))
ref_set = tag_set | branch_set
repo_name = _repo_name_from_git_url(git_url)

for raw in (tag, branch, checkout_to):
b = (raw or "").strip()
if not b:
continue
for candidate in _repo_prefixed_version_refs(repo_name, b):
ref, clar = _try_resolve_checkout_base(candidate, ref_set)
if ref is not None:
return ref, clar
ref, clar = _try_resolve_checkout_base(b, ref_set)
if ref is not None:
return ref, clar
Expand Down
69 changes: 69 additions & 0 deletions tests/test_decide_checkout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Copyright (c) 2026 LG Electronics Inc.
# SPDX-License-Identifier: Apache-2.0
"""Tests for git checkout ref resolution (decide_checkout)."""

import pytest

from fosslight_util.download import (
_repo_name_from_git_url,
_repo_prefixed_version_refs,
_try_resolve_checkout_base,
clarified_version_from_oss_version,
decide_checkout,
)


@pytest.mark.parametrize(
"git_url,expected",
[
("https://github.com/rrousselGit/freezed", "freezed"),
("https://github.com/rrousselGit/freezed.git", "freezed"),
("git@github.com:rrousselGit/freezed.git", "freezed"),
],
)
def test_repo_name_from_git_url(git_url, expected):
assert _repo_name_from_git_url(git_url) == expected


def test_repo_prefixed_version_refs():
assert _repo_prefixed_version_refs("freezed", "2.4.4") == [
"freezed-v2.4.4",
"freezed-v.2.4.4",
"freezed_2.4.4",
"freezed-2.4.4",
]
assert _repo_prefixed_version_refs("freezed", "v2.4.4")[0] == "freezed-v2.4.4"


def test_try_resolve_checkout_base_matches_repo_prefixed_tag():
ref_set = {"freezed-v2.4.4", "freezed_annotation-v2.4.4", "master"}
ref, clar = _try_resolve_checkout_base("freezed-v2.4.4", ref_set)
assert ref == "freezed-v2.4.4"
assert clar == "2.4.4"


def test_try_resolve_checkout_base_semver_matches_repo_prefixed_tag():
ref_set = {"freezed-v2.4.4", "freezed_annotation-v2.4.4", "master"}
ref, clar = _try_resolve_checkout_base("2.4.4", ref_set)
assert ref == "freezed-v2.4.4"
assert clar == "2.4.4"


def test_clarified_version_from_repo_prefixed_tag():
assert clarified_version_from_oss_version("freezed-v2.4.4") == "2.4.4"


def test_decide_checkout_resolves_repo_prefixed_tag(monkeypatch):
tags = ["freezed-v2.4.4", "freezed_annotation-v2.4.4"]
monkeypatch.setattr(
"fosslight_util.download.get_remote_refs",
lambda _url: {"tags": tags, "branches": ["master"]},
)

ref, clar = decide_checkout(
checkout_to="2.4.4",
git_url="https://github.com/rrousselGit/freezed",
)

assert ref == "freezed-v2.4.4"
assert clar == "2.4.4"
Loading