Skip to content
Draft
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
38 changes: 36 additions & 2 deletions scripts/snippets/resolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -14,7 +14,7 @@ class SourceResolutionError(Exception):

@dataclass(frozen=True)
class ResolvedSource:
reference: ImmutableSourceReference
reference: ImmutableSourceReference | PullRequestSnippetSource
commit: str
content: bytes

Expand All @@ -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,
Expand All @@ -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)
38 changes: 38 additions & 0 deletions tests/test_candidate_snippet_preview_resolution.py
Original file line number Diff line number Diff line change
@@ -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")
]