Source code for action0.github.models.comparison

"""The commit comparison model (:py:class:`Comparison`)."""

from __future__ import annotations

from dataclasses import dataclass
from dataclasses import field
from enum import StrEnum
from typing import Any

from .commit import Commit
from .commit import CommitFile


[docs] class ComparisonStatus(StrEnum): """How ``head`` relates to ``base`` in a comparison.""" DIVERGED = "diverged" AHEAD = "ahead" BEHIND = "behind" IDENTICAL = "identical"
[docs] @dataclass class Comparison: """ The comparison of two commits — what :py:class:`~action0.github.operations.commits.CompareCommits` returns: GitHub's three-dot comparison, i.e. ``head`` measured against the merge base (like ``git log base...head``), not against ``base`` itself. """ status: ComparisonStatus """How ``head`` relates to ``base``.""" ahead_by: int """How many commits ``head`` is ahead of the merge base.""" behind_by: int """How many commits ``base`` is ahead of the merge base.""" total_commits: int """The total number of commits ``head`` is ahead by — can exceed ``len(commits)``, which GitHub caps at 250.""" html_url: str """The web URL of the comparison, e.g. ``"https://github.com/octo/demo/compare/main...topic"``.""" merge_base_commit: Commit """The merge base — the common ancestor the comparison is measured from (the fork point).""" commits: list[Commit] = field(default_factory=list) """The commits ``head`` is ahead by, oldest first — capped at 250 (:py:attr:`total_commits` has the real count; list the rest via :py:class:`~action0.github.operations.commits.ListCommits`).""" files: list[CommitFile] = field(default_factory=list) """The combined diff, file by file — capped at 300 files."""
[docs] @classmethod def from_json(cls, data: Any) -> Comparison: """ Build a comparison from one decoded JSON object. :param data: the decoded JSON object :return: the comparison """ return cls( status=ComparisonStatus(data["status"]), ahead_by=data["ahead_by"], behind_by=data["behind_by"], total_commits=data["total_commits"], html_url=data["html_url"], merge_base_commit=Commit.from_json(data["merge_base_commit"]), commits=[Commit.from_json(item) for item in data.get("commits", [])], files=[CommitFile.from_json(item) for item in data.get("files", [])], )