From 0ad0c9f6a5dc39512fb4fad0ae8bfaa912a12c07 Mon Sep 17 00:00:00 2001 From: danielporterda Date: Fri, 7 Aug 2026 13:13:09 -0400 Subject: [PATCH] Resolve candidate snippets for preview Signed-off-by: danielporterda --- scripts/snippets/resolution.py | 38 ++++++++++++++++++- ...st_candidate_snippet_preview_resolution.py | 38 +++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 tests/test_candidate_snippet_preview_resolution.py diff --git a/scripts/snippets/resolution.py b/scripts/snippets/resolution.py index 050f9f299..c7fbc83d8 100644 --- a/scripts/snippets/resolution.py +++ b/scripts/snippets/resolution.py @@ -3,7 +3,7 @@ from dataclasses import dataclass from typing import Protocol -from .model import ImmutableSourceReference +from .model import ImmutableSourceReference, PullRequestSnippetSource DEFAULT_MAX_SOURCE_BYTES = 1024 * 1024 @@ -14,7 +14,7 @@ class SourceResolutionError(Exception): @dataclass(frozen=True) class ResolvedSource: - reference: ImmutableSourceReference + reference: ImmutableSourceReference | PullRequestSnippetSource commit: str content: bytes @@ -23,6 +23,19 @@ class GitHubFileClient(Protocol): def read_file(self, repository: str, commit: str, path: str) -> bytes: ... +@dataclass(frozen=True) +class PullRequestResolution: + head_commit: str + merged: bool + merge_commit: str | None + + +class GitHubPullRequestClient(GitHubFileClient, Protocol): + def resolve_pull_request( + self, repository: str, pull_request: int + ) -> PullRequestResolution: ... + + def resolve_immutable_source( reference: ImmutableSourceReference, github: GitHubFileClient, @@ -37,3 +50,24 @@ def resolve_immutable_source( f"Source exceeds the {max_source_bytes}-byte size limit" ) return ResolvedSource(reference, reference.commit, content) + + +def resolve_candidate_preview( + reference: PullRequestSnippetSource, + github: GitHubPullRequestClient, + *, + max_source_bytes: int = DEFAULT_MAX_SOURCE_BYTES, +) -> ResolvedSource: + """Read a candidate source at its pull request's current head commit.""" + + pull_request = github.resolve_pull_request( + reference.repository, reference.pull_request + ) + content = github.read_file( + reference.repository, pull_request.head_commit, reference.path + ) + if len(content) > max_source_bytes: + raise SourceResolutionError( + f"Source exceeds the {max_source_bytes}-byte size limit" + ) + return ResolvedSource(reference, pull_request.head_commit, content) diff --git a/tests/test_candidate_snippet_preview_resolution.py b/tests/test_candidate_snippet_preview_resolution.py new file mode 100644 index 000000000..3801ae218 --- /dev/null +++ b/tests/test_candidate_snippet_preview_resolution.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +from scripts.snippets.model import PullRequestSnippetSource +from scripts.snippets.resolution import PullRequestResolution, resolve_candidate_preview + +HEAD = "7a6b8d9012fe34ac56bd7890ef12ab34cd56ef78" + + +class FakeGitHub: + def __init__(self) -> None: + self.read_calls: list[tuple[str, str, str]] = [] + + def resolve_pull_request( + self, repository: str, pull_request: int + ) -> PullRequestResolution: + assert (repository, pull_request) == ("canton-network/splice", 6123) + return PullRequestResolution(HEAD, False, None) + + def read_file(self, repository: str, commit: str, path: str) -> bytes: + self.read_calls.append((repository, commit, path)) + return b"candidate\n" + + +def test_reads_candidate_at_current_pull_request_head() -> None: + github = FakeGitHub() + reference = PullRequestSnippetSource( + repository="canton-network/splice", + pull_request=6123, + path="apps/example.yaml", + ) + + resolved = resolve_candidate_preview(reference, github) + + assert resolved.commit == HEAD + assert resolved.content == b"candidate\n" + assert github.read_calls == [ + ("canton-network/splice", HEAD, "apps/example.yaml") + ]