Skip to content

Commit 042feab

Browse files
authored
Map name (issue) bt->gh (#116)
* feat: let policy take optional equality fn param * feat: implement name map * feat: wire name map * fix: pass correct arguments in wire * doc: add placeholder for diagram
1 parent 1ebfb4f commit 042feab

File tree

5 files changed

+103
-4
lines changed

5 files changed

+103
-4
lines changed

docs/source/api_reference/diagrams.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ bio.tools → GitHub mapping for pull requests
133133
The flowcharts below detail the mapping of specific fields from bio.tools to GitHub
134134
in the form of pull requests.
135135

136+
Map name
137+
~~~~~~~~~~
138+
139+
TODO: add diagram here.
140+
136141
Map license
137142
~~~~~~~~~~~~~~~~
138143

src/bridge/pipelines/bt2gh_for_pr/map.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,16 @@
99
from bridge.pipelines.protocols import MapItem, Method, ModelsMap
1010
from bridge.pipelines.utils import load_dict_from_yaml_file
1111

12-
from .map_funcs import map_citation, map_description, map_homepage, map_license, map_readme, map_topics, map_version
12+
from .map_funcs import (
13+
map_citation,
14+
map_description,
15+
map_homepage,
16+
map_license,
17+
map_name,
18+
map_readme,
19+
map_topics,
20+
map_version,
21+
)
1322

1423

1524
class MapDestination(BaseModel):
@@ -24,7 +33,7 @@ class MapDestination(BaseModel):
2433
List of properties to be mapped to pull requests.
2534
"""
2635

27-
issue: list[str] = ["description", "homepage", "topics", "version"]
36+
issue: list[str] = ["name", "description", "homepage", "topics", "version"]
2837
pr: list[str] = ["citation", "readme", "license"]
2938

3039

@@ -43,7 +52,15 @@ def map(self) -> dict[str, MapItem]:
4352
Map bio.tools metadata property to corresponding GitHub property.
4453
"""
4554
return {
46-
"name": MapItem(schema_entry=self.metadata.name, repo_entry=self.repo.repo.name, method=Method.EXACT),
55+
"name": MapItem(
56+
schema_entry={
57+
"name": self.metadata.name,
58+
"biotoolsID": self.metadata.biotoolsID.root,
59+
},
60+
repo_entry=self.repo.repo.name,
61+
method=Method.EXACT,
62+
fn=map_name,
63+
),
4764
"version": MapItem(
4865
schema_entry=self.metadata.version,
4966
repo_entry=self.repo.latest_release.tag_name,

src/bridge/pipelines/bt2gh_for_pr/map_funcs/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from .description import map_description
77
from .homepage import map_homepage
88
from .license import map_license
9+
from .name import map_name
910
from .readme import map_readme
1011
from .topics import map_topics
1112
from .version import map_version
@@ -18,4 +19,5 @@
1819
"map_readme",
1920
"map_license",
2021
"map_version",
22+
"map_name",
2123
]
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""
2+
Map repository name from bio.tools to GitHub.
3+
4+
This module compares the bio.tools name and ID with the GitHub repository name.
5+
If the GitHub name does not match either, it proposes an issue suggesting
6+
to update the repository name to the bio.tools ID.
7+
It applies a bio.tools-over-GitHub issue policy.
8+
"""
9+
10+
from bridge.logging import get_user_logger
11+
from bridge.pipelines.policies.bt2gh import reconcile_bt_over_gh
12+
from bridge.pipelines.utils import normalize_text, str_contain_each_other
13+
14+
logger = get_user_logger()
15+
16+
17+
def map_name(gh_name: str | None, bt_params: dict[str, str | None] | None) -> dict[str, str] | None:
18+
"""
19+
Propose a GitHub issue to update the GitHub repository name based on bio.tools name and ID metadata,
20+
using the generic bio.tools-over-GitHub issue policy.
21+
22+
Parameters
23+
----------
24+
gh_name : str | None
25+
GitHub repository name.
26+
bt_params : dict[str, str | None] | None
27+
A dictionary containing existing bio.tools metadata parameters.
28+
Expected keys:
29+
- ``"name"`` : bio.tools name
30+
- ``"biotoolsID"`` : bio.tools ID
31+
32+
Returns
33+
-------
34+
dict[str, str] | None
35+
A mapping with the issue title as key and the issue body as value,
36+
or ``None`` if no issue is to be created.
37+
"""
38+
if bt_params is None:
39+
logger.unchanged("No bio.tools params found, nothing to map.")
40+
return None
41+
42+
bt_name = bt_params.get("name")
43+
bt_id = bt_params.get("biotoolsID")
44+
45+
gh_norm = normalize_text(gh_name)
46+
bt_name_norm = normalize_text(bt_name)
47+
bt_id_norm = normalize_text(bt_id)
48+
49+
def make_issue(name: str) -> dict[str, str]:
50+
return {
51+
"Update repository name from bio.tools metadata": (
52+
f"The GitHub repository name '{gh_name}' does not match the bio.tools "
53+
f"name '{bt_name}' or ID '{bt_id}'.\n\n"
54+
f"Proposed new name: '{bt_id}'.\n\n"
55+
"Please consider updating the repository name."
56+
),
57+
}
58+
59+
return reconcile_bt_over_gh(
60+
bt_norm=bt_id_norm,
61+
gh_norm=gh_norm,
62+
make_output=make_issue,
63+
log_label="name/id",
64+
equality_fn=lambda gh, bt: str_contain_each_other(gh, bt) or str_contain_each_other(gh, bt_name_norm),
65+
)

src/bridge/pipelines/policies/bt2gh/reconcile_bt_over_gh.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ async def reconcile_bt_over_gh(
2626
bt_norm: BTN | None,
2727
make_output: Callable[[BTN], Awaitable[OUTPUT] | OUTPUT],
2828
log_label: str,
29+
equality_fn: Callable[[GHN, BTN], bool] | None = None,
2930
) -> OUTPUT | None:
3031
"""
3132
Apply a generic bio.tools-over-GitHub policy to decide whether to
@@ -63,6 +64,10 @@ async def reconcile_bt_over_gh(
6364
log_label : str
6465
Short label used in log messages to identify the metadata field
6566
(e.g., ``"description"``, ``"homepage"``, ``"license"``).
67+
equality_fn : Callable[[GHN, BTN], bool] | None, optional
68+
Optional equality function to compare normalized GitHub and
69+
bio.tools values. If ``None``, the default equality operator
70+
(``==``) is used.
6671
6772
Returns
6873
-------
@@ -75,7 +80,12 @@ async def reconcile_bt_over_gh(
7580
return None
7681

7782
if gh_norm is not None:
78-
if gh_norm == bt_norm:
83+
if equality_fn is not None:
84+
equal = equality_fn(gh_norm, bt_norm)
85+
else:
86+
equal = gh_norm == bt_norm
87+
88+
if equal:
7989
logger.exact(f"bio.tools {log_label} matches GitHub {log_label}, no need to map.")
8090
return None
8191

0 commit comments

Comments
 (0)