From bd29525b57a1105bc5fb2f0da5bfc61001aef6b9 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Sun, 2 Jun 2024 21:56:47 +0200 Subject: feat: add setting labels for individual tickets --- import_issues.py | 153 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 96 insertions(+), 57 deletions(-) diff --git a/import_issues.py b/import_issues.py index 6086f9b..d3c154b 100755 --- a/import_issues.py +++ b/import_issues.py @@ -135,7 +135,7 @@ from datetime import datetime, timezone from email.message import EmailMessage from email.utils import format_datetime, make_msgid from pathlib import Path -from typing import Dict, List, Optional +from typing import Any, Optional logging.basicConfig( format="%(levelname)s:%(funcName)s:%(message)s", @@ -183,9 +183,9 @@ email_count = 0 issue_count = 0 -def read_id_map_file(file_path: Path) -> Dict[int, str]: +def read_id_map_file(file_path: Path) -> dict[int, str]: """Reads a CSV file with ID,NAME mappings and returns the resulting dict.""" - result: Dict[int, str] = {} + result: dict[int, str] = {} with open(file_path, newline="") as fh: reader = csv.reader(fh) @@ -294,8 +294,10 @@ def run_hut(cmds, tracker, msg, args=None, delay=None): return res -def open_ticket_by_hut( +def open_ticket_by_email( + smtp, delay: float, + mode: str, tracker: str, frm: str, title: str, @@ -305,11 +307,10 @@ def open_ticket_by_hut( closed_at: Optional[str], is_closed: bool, is_confidential: bool, - labels: List[Dict[str, Any]], + labels: list[dict[str, Any]], milestone_name: Optional[str], gitlab_ticket_url: str, -) -> str: - +): lines = [] pheaders = [] @@ -327,6 +328,17 @@ def open_ticket_by_hut( if milestone_name: pheaders.append(f"Milestone: {milestone_name}") + if labels: + pheaders.append( + "Labels: " + + ", ".join( + [ + x["label"]["title"] + for x in sorted(labels, key=lambda x: x["label"]["title"]) + ] + ) + ) + if is_confidential: pheaders.append("Confidential: true") @@ -334,18 +346,19 @@ def open_ticket_by_hut( lines.append("") lines.append(body) - msg = title - if len(lines): - msg += "\n" + "\n".join(lines) - out = run_hut(["ticket", "create"], tracker, msg, delay=delay) - - return out + do_mail( + smtp=smtp, + delay=delay, + mode=mode, + frm=frm, + to=f"{tracker}@todo.sr.ht", + subject=title, + body="\n".join(lines), + ) -def open_ticket_by_email( - smtp, +def open_ticket_by_hut( delay: float, - mode: str, tracker: str, frm: str, title: str, @@ -355,10 +368,11 @@ def open_ticket_by_email( closed_at: Optional[str], is_closed: bool, is_confidential: bool, - label_names: List[str], + labels: list[dict[str, Any]], milestone_name: Optional[str], gitlab_ticket_url: str, -): +) -> str: + lines = [] pheaders = [] @@ -376,9 +390,6 @@ def open_ticket_by_email( if milestone_name: pheaders.append(f"Milestone: {milestone_name}") - if label_names: - pheaders.append("Labels: " + ", ".join(sorted(label_names))) - if is_confidential: pheaders.append("Confidential: true") @@ -386,15 +397,38 @@ def open_ticket_by_email( lines.append("") lines.append(body) - do_mail( - smtp=smtp, - delay=delay, - mode=mode, - frm=frm, - to=f"{tracker}@todo.sr.ht", - subject=title, - body="\n".join(lines), - ) + msg = title + if len(lines): + msg += "\n" + "\n".join(lines) + out = run_hut(["ticket", "create"], tracker, msg, delay=delay) + out.issue_id = int(out.stderr.strip()[len("Created new ticket #") :]) + + for label in sorted(labels, key=lambda x: x["label"]["title"]): + # {"target_type":"Issue", + # "created_at":"2023-11-03T22:10:29.419Z", + # "updated_at":"2023-11-03T22:10:29.419Z", + # "label":{"title":"smime", + # "color":"#00b140", + # "project_id":346279, + # "created_at":"2023-02-02T10:49:17.779Z", + # "updated_at":"2023-02-02T10:49:17.779Z", + # "template":false, + # "description":null, + # "group_id":null, + # "type":"ProjectLabel", + # "priorities":[]}} + label_name = label["label"]["title"] + label_color = label["label"]["color"] + ensure_label(tracker, label_name, label_color, delay=delay) + run_hut( + ["ticket", "label"], + tracker, + None, + args=[str(out.issue_id), "-l", label_name], + delay=delay, + ) + + return out def open_ticket( @@ -411,7 +445,7 @@ def open_ticket( closed_at: Optional[str], is_closed: bool, is_confidential: bool, - labels: List[Dict[str, Any]], + labels: list[dict[str, Any]], milestone_name: Optional[str], gitlab_ticket_url: str, ) -> int: @@ -623,10 +657,10 @@ def run( include_confidential: bool, skip_confidential: bool, ): - label_ids_to_names: Optional[Dict[int, str]] = ( + label_ids_to_names: Optional[dict[int, str]] = ( read_id_map_file(labels_file_path) if labels_file_path else None ) - user_ids_to_names: Optional[Dict[int, str]] = ( + user_ids_to_names: Optional[dict[int, str]] = ( read_id_map_file(users_file_path) if users_file_path else None ) # TODO Might be able to automatically map note.events.author_id to @@ -701,7 +735,7 @@ def run( log.info("Creating tickets.") - issue_id_map: Dict[int, int] = {} + issue_id_map: dict[int, int] = {} # While we're creating tickets, we can't just loop over the sorted # issue_jsons. We have to loop over potential issue IDs and handle any that @@ -753,7 +787,7 @@ def run( closed_at=issue_json["closed_at"], is_closed=(issue_json["state"] == "closed"), is_confidential=(issue_json.get("confidential") is True), - label_names=[x["label"]["title"] for x in issue_json["label_links"]], + labels=list(issue_json["label_links"]), milestone_name=issue_json.get("milestone", {}).get("title") or None, gitlab_ticket_url=f"{gitlab_project_url}/-/issues/{gitlab_issue_id}", ) @@ -852,7 +886,7 @@ def run( ) -def main(): +def parse_args(args_in: list[str]) -> dict[str, Any]: parser = argparse.ArgumentParser( prog="import_issues.py", description="Import Gitlab issues into Sourcehut via SMTP.", @@ -990,7 +1024,11 @@ def main(): help="Exported Gitlab tree/project/ directory containing ndjson files.", ) - args = vars(parser.parse_args()) + return vars(parser.parse_args(args_in)) + + +def main(): + args = parse_args(sys.argv[1:]) export_dir = args["export_dir"] assert export_dir, "Must have a exported project directory." @@ -1072,26 +1110,27 @@ def main(): if smtp_user: smtp.login(smtp_user, smtp_password) - run( - smtp=smtp, - delay=delay, - mode=mode, - tracker=tracker, - frm=frm, - export_dir_path=export_dir_path, - gitlab_project_url=args["gitlab_project_url"].rstrip("/"), - labels_file_path=None if skip_labels else Path(labels_file), - skip_unknown_labels=skip_unknown_labels, - users_file_path=None if skip_users else Path(users_file), - skip_unknown_users=skip_unknown_users, - skip_missing_issues=skip_missing_issues, - create_missing_issues=create_missing_issues, - include_confidential=include_confidential, - skip_confidential=skip_confidential, - ) - - if mode == "send": - smtp.quit() + try: + run( + smtp=smtp, + delay=delay, + mode=mode, + tracker=tracker, + frm=frm, + export_dir_path=export_dir_path, + gitlab_project_url=args["gitlab_project_url"].rstrip("/"), + labels_file_path=None if skip_labels else Path(labels_file), + skip_unknown_labels=skip_unknown_labels, + users_file_path=None if skip_users else Path(users_file), + skip_unknown_users=skip_unknown_users, + skip_missing_issues=skip_missing_issues, + create_missing_issues=create_missing_issues, + include_confidential=include_confidential, + skip_confidential=skip_confidential, + ) + finally: + if mode == "send": + smtp.quit() if __name__ == "__main__": -- cgit