Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
153 changes: 87 additions & 66 deletions otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,87 @@ def is_resolve_success(val: ResolveResult) -> TypeGuard[ResolveSuccess]:
SHA_REGEX = r"^[a-f0-9]{7,64}$"


def _ref_specificity(ref: str) -> int:
"""Sort key for refs that share a SHA: PR head, then merge-queue, then rest."""
if ref.startswith("refs/pull/"):
return 0
if re.match(MERGE_QUEUE_REGEX, ref):
return 1
return 2


def _classify_sha_match(
sdk: str,
version: str,
sha: str,
ref: str,
infix: str | None,
) -> ResolveSuccess:
"""Turn a single (sha, ref) pair matched by a SHA lookup into a result.

Normalizes the ref into a filesystem-safe ``tag`` (slashes flattened to
``--``) and flags branch-like refs (PR heads, merge-queue refs, branches)
as ``head`` so callers know to build from source rather than fetch a
released artifact. Shared by both single- and multi-match SHA lookups so a
merge-queue commit pointed at by only one ref is handled the same as one
pointed at by several.
"""
if ref.startswith("refs/pull/"):
pr_number = ref.split("/")[2]
return {
"sdk": sdk,
"alias": version,
"head": True,
"pr": pr_number,
"sha": sha,
"tag": f"pull-{pr_number}",
}

mq_match = re.match(MERGE_QUEUE_REGEX, ref)
if mq_match:
to_branch = mq_match.group("branch")
pr_number = mq_match.group("pr_number")
if to_branch and pr_number:
return {
"sdk": sdk,
"alias": version,
"head": True,
"pr": pr_number,
"sha": sha,
"tag": f"mq-{to_branch}-{pr_number}",
}
suffix = ref.split("refs/heads/gh-readonly-queue/")[-1]
return {
"sdk": sdk,
"alias": version,
"head": True,
"sha": sha,
"tag": "mq--" + suffix.replace("/", "--"),
}
Comment thread
dmihalcik-virtru marked this conversation as resolved.
Outdated

if ref.startswith("refs/heads/"):
branch = ref.split("refs/heads/")[-1]
Comment thread
dmihalcik-virtru marked this conversation as resolved.
Outdated
return {
"sdk": sdk,
"alias": version,
"head": True,
"sha": sha,
"tag": branch.replace("/", "--"),
}

tag = ref
if tag.startswith("refs/tags/"):
tag = tag.split("refs/tags/")[-1]
if infix:
tag = tag.split(f"{infix}/")[-1]
Comment thread
dmihalcik-virtru marked this conversation as resolved.
Outdated
return {
"sdk": sdk,
"alias": version,
"sha": sha,
"tag": tag,
}
Comment thread
dmihalcik-virtru marked this conversation as resolved.


def _try_resolve_js_npm(
sdk: str,
version: str,
Expand Down Expand Up @@ -170,72 +251,12 @@ def _resolve_against(
"sha": version,
"tag": version,
}
if len(matching_tags) > 1:
for sha, tag in matching_tags:
if tag.startswith("refs/pull/"):
pr_number = tag.split("/")[2]
return {
"sdk": sdk,
"alias": version,
"head": True,
"sha": sha,
"tag": f"pull-{pr_number}",
}
for sha, tag in matching_tags:
mq_match = re.match(MERGE_QUEUE_REGEX, tag)
if mq_match:
to_branch = mq_match.group("branch")
pr_number = mq_match.group("pr_number")
if to_branch and pr_number:
return {
"sdk": sdk,
"alias": version,
"head": True,
"pr": pr_number,
"sha": sha,
"tag": f"mq-{to_branch}-{pr_number}",
}
suffix = tag.split("refs/heads/gh-readonly-queue/")[-1]
flattag = "mq--" + suffix.replace("/", "--")
return {
"sdk": sdk,
"alias": version,
"head": True,
"sha": sha,
"tag": flattag,
}
head = False
if tag.startswith("refs/heads/"):
head = True
tag = tag.split("refs/heads/")[-1]
flattag = tag.replace("/", "--")
return {
"sdk": sdk,
"alias": version,
"head": head,
"sha": sha,
"tag": flattag,
}

return {
"sdk": sdk,
"alias": version,
"err": (
f"SHA {version} points to multiple tags, unable to differentiate: "
f"{', '.join(tag for _, tag in matching_tags)}"
),
}
(sha, tag) = matching_tags[0]
if tag.startswith("refs/tags/"):
tag = tag.split("refs/tags/")[-1]
if infix:
tag = tag.split(f"{infix}/")[-1]
return {
"sdk": sdk,
"alias": version,
"sha": sha,
"tag": tag,
}
# A SHA can be pointed at by several refs at once — e.g. a merge-queue
# commit that is both a branch tip and a `gh-readonly-queue` ref.
# Prefer the most specific (PR > merge-queue > branch/tag) so the dist
# tag is meaningful and source-built refs get flagged as heads.
sha, ref = min(matching_tags, key=lambda st: _ref_specificity(st[1]))
return _classify_sha_match(sdk, version, sha, ref, infix)

if version.startswith("refs/pull/"):
merge_heads = [
Expand Down
23 changes: 23 additions & 0 deletions otdf-sdk-mgr/tests/test_resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,29 @@ def test_multiple_matches_branch_only(self):
assert result.get("head") is True
assert result["tag"] == "feature--my-branch"

def test_single_match_merge_queue(self):
# A merge-queue commit is usually pointed at by exactly one ref (the
# gh-readonly-queue branch). It must still flatten to an mq tag and be
# flagged as a head so the caller builds it from source.
mq_ref = f"refs/heads/gh-readonly-queue/main/pr-3630-{SHA40}"
ls = make_ls_remote((SHA40, mq_ref))
with patch_git(ls):
result = resolve("go", SHA40, None)
assert is_resolve_success(result)
assert result["tag"] == "mq-main-3630"
assert result.get("pr") == "3630"
assert result.get("head") is True

def test_single_match_branch_flagged_head(self):
# A SHA that points at a single branch ref must flatten slashes and be
# flagged as a head (it has no released artifact to install).
ls = make_ls_remote((SHA40, "refs/heads/feature/my-branch"))
with patch_git(ls):
result = resolve("go", SHA40, None)
assert is_resolve_success(result)
assert result.get("head") is True
assert result["tag"] == "feature--my-branch"


# ---------------------------------------------------------------------------
# resolve() — refs/pull/NNN
Expand Down
Loading