Source code for bridge.pipelines.bt2gh_for_pr_issues.map_funcs.license
"""
Map license metadata from bio.tools to GitHub.
This module compares the license recorded in bio.tools with the license
detected on a GitHub repository and, when appropriate, proposes a pull
request that adds a full LICENSE file based on the SPDX canonical text.
It applies a bio.tools-over-GitHub policy.
"""
from bridge.builders import compose_spdx_license_metadata
from bridge.core import SPDXLicense
from bridge.core.biotools import License as BTLicense
from bridge.core.github_repo import License as GHLicense
from bridge.logging import get_user_logger
from bridge.pipelines.policies.bt2gh import reconcile_bt_over_gh
from bridge.pipelines.utils import find_matching_enum_member
logger = get_user_logger()
[docs]
async def map_license(gh_license: GHLicense | None, bt_license: BTLicense | None) -> dict[str, str] | None:
"""
Propose a GitHub pull request to add a LICENSE file based on bio.tools
license metadata, using the generic bio.tools-over-GitHub policy.
The GitHub license (when present) is normalized via its SPDX identifier
and compared against the bio.tools license enum. If bio.tools provides
a license, the full canonical license text is fetched from the SPDX service
and proposed as a new ``LICENSE.txt`` file. If GitHub already declares a different license,
that value is treated as authoritative, a conflict is logged, but the pull
request is still proposed.
Parameters
----------
gh_license : GHLicense | None
License metadata detected on the GitHub repository, or ``None``
if no license is declared.
bt_license : BTLicense | None
License value from the bio.tools entry, represented as a bio.tools
license enum, or ``None`` if not available.
Returns
-------
dict[str, str] | None
A dictionary with the filename ``LICENSE.txt`` as key and the
full license text as value, or ``None`` if no pull request should
be created under the policy.
"""
gh_norm = find_matching_enum_member(gh_license.spdx_id, BTLicense) if gh_license else None
bt_norm = bt_license
async def make_pr(bt_value: BTLicense) -> dict[str, str] | None:
spdx_id = bt_value.value
try:
license: SPDXLicense = await compose_spdx_license_metadata(spdx_id)
full_text = license.licenseText
logger.added(f"LICENSE.txt with full text for SPDX ID '{spdx_id}'")
return {"LICENSE.txt": full_text}
except Exception as e:
logger.unchanged(f"could not retrieve full text for SPDX ID '{spdx_id}': {e}")
return None
return await reconcile_bt_over_gh(
gh_norm=gh_norm,
bt_norm=bt_norm,
make_output=make_pr,
log_label="license",
)