Source code for bridge.pipelines.policies.bt2gh.reconcile_bt_over_gh
"""
Generic reconciliation policies for bio.tools to GitHub mapping.
This module provides a generic function to determine whether a GitHub issue
or pull request should be proposed based on bio.tools metadata, according to
a policy that treats bio.tools as authoritative while preserving existing GitHub
values when bio.tools is silent.
"""
from collections.abc import Awaitable, Callable
from typing import TypeVar
from bridge.logging import get_user_logger
from bridge.utils import maybe_await
logger = get_user_logger()
BTN = TypeVar("BTN") # normalized bio.tools representation
GHN = TypeVar("GHN") # normalized GitHub representation
OUTPUT = TypeVar("OUTPUT") # issue payload type, e.g. dict[str, str]
[docs]
async def reconcile_bt_over_gh(
*,
gh_norm: GHN | None,
bt_norm: BTN | None,
make_output: Callable[[BTN], Awaitable[OUTPUT] | OUTPUT],
log_label: str,
equality_fn: Callable[[GHN, BTN], bool] | None = None,
) -> OUTPUT | None:
"""
Apply a generic bio.tools-over-GitHub policy to decide whether to
propose a GitHub issue or pull request based on bio.tools metadata.
This function operates on *normalized* representations of GitHub and
bio.tools values (``gh_norm`` and ``bt_norm``) and returns an issue/pr
payload constructed from the bio.tools value when applicable.
Policy:
1. If ``bt_norm`` is ``None``, bio.tools is treated as silent and no
issue/pr is proposed. An "unchanged" log entry is emitted.
2. If ``gh_norm`` is not ``None`` and equals ``bt_norm``, the values
are considered aligned and no issue/pr is proposed.
An "exact" log entry is emitted.
3. If ``gh_norm`` is not ``None`` and differs from ``bt_norm``, GitHub
is treated as conflicting with bio.tools. A conflict log entry is
emitted and an issue/pr proposing the bio.tools value is constructed
via ``make_output(bt_norm)``.
4. If ``gh_norm`` is ``None`` and ``bt_norm`` is not ``None``, GitHub
is missing the value and an issue/pr proposing the bio.tools value is
constructed via ``make_output(bt_norm)`` with an added log entry.
Parameters
----------
gh_norm : GHN | None
Normalized representation of the GitHub value, or ``None`` if no
usable value is available from GitHub.
bt_norm : BTN | None
Normalized representation of the bio.tools value, or ``None`` if
no value is recorded in bio.tools.
make_output : Callable[[BTN], Awaitable[OUTPUT] | OUTPUT]
Callable that constructs an issue/pr payload from the normalized
bio.tools value. The callable may be asynchronous.
log_label : str
Short label used in log messages to identify the metadata field
(e.g., ``"description"``, ``"homepage"``, ``"license"``).
equality_fn : Callable[[GHN, BTN], bool] | None, optional
Optional equality function to compare normalized GitHub and
bio.tools values. If ``None``, the default equality operator
(``==``) is used.
Returns
-------
OUTPUT | None
Issue/pr payload to propose according to the policy, or ``None`` if
no issue should be created.
"""
if bt_norm is None:
logger.unchanged(f"No bio.tools {log_label} found, nothing to map.")
return None
if gh_norm is not None:
if equality_fn is not None:
equal = equality_fn(gh_norm, bt_norm)
else:
equal = gh_norm == bt_norm
if equal:
logger.exact(f"bio.tools {log_label} matches GitHub {log_label}, no need to map.")
return None
logger.conflict(f"existing GitHub {log_label} {gh_norm!r} differs from bio.tools {log_label} {bt_norm!r}")
return await maybe_await(make_output, bt_norm)
logger.added(f"{log_label}: {bt_norm!r}")
return await maybe_await(make_output, bt_norm)