From 09c8f87c90a161f1b5882b0adbefb30b75531604 Mon Sep 17 00:00:00 2001 From: Nicolas Cantu Date: Thu, 23 Apr 2026 15:32:00 +0200 Subject: [PATCH] Unify git-issues mail stderr hints via IMAP_SMTP_CONFIG_DOC_REF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Motivations:** - Replace per-path messages with canonical doc reference from LeCoffre imap_common. **Evolutions:** - mail_common re-exports IMAP_SMTP_CONFIG_DOC_REF; mail-*.py and tickets-fetch-inbox use it for IMAP/SMTP/Gitea token errors. **Page affectées:** - git-issues/mail_common.py, mail-list-unread.py, mail-get-thread.py, mail-mark-read.py, mail-send-reply.py, mail-to-issue.py, mail-create-issue-from-email.py, tickets-fetch-inbox.py --- git-issues/mail-create-issue-from-email.py | 6 +++--- git-issues/mail-get-thread.py | 6 ++---- git-issues/mail-list-unread.py | 11 +++++++---- git-issues/mail-mark-read.py | 5 ++--- git-issues/mail-send-reply.py | 6 ++---- git-issues/mail-to-issue.py | 6 +++--- git-issues/mail_common.py | 7 ++++++- git-issues/tickets-fetch-inbox.py | 3 ++- 8 files changed, 27 insertions(+), 23 deletions(-) diff --git a/git-issues/mail-create-issue-from-email.py b/git-issues/mail-create-issue-from-email.py index 9091e09..b24243f 100755 --- a/git-issues/mail-create-issue-from-email.py +++ b/git-issues/mail-create-issue-from-email.py @@ -17,10 +17,10 @@ from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) from mail_common import ( + IMAP_SMTP_CONFIG_DOC_REF, create_gitea_issue, load_gitea_config, load_imap_config, - repo_root, sanitize_title, ) @@ -62,14 +62,14 @@ def main() -> None: cfg = load_imap_config() if not cfg["user"] or not cfg["password"]: - root = repo_root() - env_path = root / ".secrets" / "git-issues" / "imap-bridge.env" print("[git-issues] ERROR: IMAP_USER and IMAP_PASSWORD required.", file=sys.stderr) + print(f"[git-issues] {IMAP_SMTP_CONFIG_DOC_REF}", file=sys.stderr) sys.exit(1) gitea = load_gitea_config() if not gitea["token"]: print("[git-issues] ERROR: GITEA_TOKEN not set.", file=sys.stderr) + print(f"[git-issues] {IMAP_SMTP_CONFIG_DOC_REF}", file=sys.stderr) sys.exit(1) mail = imaplib.IMAP4(cfg["host"], int(cfg["port"])) diff --git a/git-issues/mail-get-thread.py b/git-issues/mail-get-thread.py index afd1152..2cae381 100644 --- a/git-issues/mail-get-thread.py +++ b/git-issues/mail-get-thread.py @@ -17,7 +17,7 @@ from email.header import decode_header from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) -from mail_common import imap_since_date, load_imap_config, repo_root, imap_ssl_context +from mail_common import IMAP_SMTP_CONFIG_DOC_REF, imap_since_date, imap_ssl_context, load_imap_config def decode_header_value(header: str | None) -> str: @@ -142,13 +142,11 @@ def main() -> int: cfg = load_imap_config() if not cfg["user"] or not cfg["password"]: - root = repo_root() - env_path = root / ".secrets" / "git-issues" / "imap-bridge.env" print( "[git-issues] ERROR: IMAP_USER and IMAP_PASSWORD required.", file=sys.stderr, ) - print(f"[git-issues] Set env or create {env_path}", file=sys.stderr) + print(f"[git-issues] {IMAP_SMTP_CONFIG_DOC_REF}", file=sys.stderr) return 1 mail = imaplib.IMAP4(cfg["host"], int(cfg["port"])) diff --git a/git-issues/mail-list-unread.py b/git-issues/mail-list-unread.py index 3a5a124..827868c 100755 --- a/git-issues/mail-list-unread.py +++ b/git-issues/mail-list-unread.py @@ -16,7 +16,12 @@ from pathlib import Path # Add git-issues to path for mail_common sys.path.insert(0, str(Path(__file__).resolve().parent)) -from mail_common import imap_search_criterion_unseen, load_imap_config, repo_root, imap_ssl_context +from mail_common import ( + IMAP_SMTP_CONFIG_DOC_REF, + imap_search_criterion_unseen, + imap_ssl_context, + load_imap_config, +) def decode_header_value(header: str | None) -> str: @@ -64,10 +69,8 @@ def is_sent_to_alias(msg: email.message.Message, filter_to: str) -> bool: def main() -> None: cfg = load_imap_config() if not cfg["user"] or not cfg["password"]: - root = repo_root() - env_path = root / ".secrets" / "git-issues" / "imap-bridge.env" print("[git-issues] ERROR: IMAP_USER and IMAP_PASSWORD required.", file=sys.stderr) - print(f"[git-issues] Set env or create {env_path}", file=sys.stderr) + print(f"[git-issues] {IMAP_SMTP_CONFIG_DOC_REF}", file=sys.stderr) sys.exit(1) mail = imaplib.IMAP4(cfg["host"], int(cfg["port"])) diff --git a/git-issues/mail-mark-read.py b/git-issues/mail-mark-read.py index 36bc8d0..09f8df3 100755 --- a/git-issues/mail-mark-read.py +++ b/git-issues/mail-mark-read.py @@ -11,7 +11,7 @@ import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) -from mail_common import load_imap_config, repo_root, imap_ssl_context +from mail_common import IMAP_SMTP_CONFIG_DOC_REF, imap_ssl_context, load_imap_config def main() -> None: @@ -22,9 +22,8 @@ def main() -> None: cfg = load_imap_config() if not cfg["user"] or not cfg["password"]: - root = repo_root() - env_path = root / ".secrets" / "git-issues" / "imap-bridge.env" print("[git-issues] ERROR: IMAP_USER and IMAP_PASSWORD required.", file=sys.stderr) + print(f"[git-issues] {IMAP_SMTP_CONFIG_DOC_REF}", file=sys.stderr) sys.exit(1) mail = imaplib.IMAP4(cfg["host"], int(cfg["port"])) diff --git a/git-issues/mail-send-reply.py b/git-issues/mail-send-reply.py index 9d5d1a4..19c7a35 100755 --- a/git-issues/mail-send-reply.py +++ b/git-issues/mail-send-reply.py @@ -15,7 +15,7 @@ from email.mime.text import MIMEText from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) -from mail_common import load_smtp_config, repo_root, imap_ssl_context +from mail_common import IMAP_SMTP_CONFIG_DOC_REF, imap_ssl_context, load_smtp_config DEFAULT_SIGNATURE = """-- Support IA du projet Lecoffre.io @@ -68,10 +68,8 @@ def main() -> None: cfg = load_smtp_config() if not cfg["user"] or not cfg["password"]: - root = repo_root() - env_path = root / ".secrets" / "git-issues" / "imap-bridge.env" print("[git-issues] ERROR: SMTP_USER and SMTP_PASSWORD required.", file=sys.stderr) - print(f"[git-issues] Set env or create {env_path}", file=sys.stderr) + print(f"[git-issues] {IMAP_SMTP_CONFIG_DOC_REF}", file=sys.stderr) sys.exit(1) body = args.body diff --git a/git-issues/mail-to-issue.py b/git-issues/mail-to-issue.py index 33652b9..7f15584 100755 --- a/git-issues/mail-to-issue.py +++ b/git-issues/mail-to-issue.py @@ -27,11 +27,11 @@ from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) from mail_common import ( + IMAP_SMTP_CONFIG_DOC_REF, create_gitea_issue, imap_search_criterion_unseen, load_gitea_config, load_imap_config, - repo_root, sanitize_title, ) @@ -66,13 +66,13 @@ def _get_text_body(msg: email.message.Message) -> str: def main() -> None: imap_cfg = load_imap_config() if not imap_cfg["user"] or not imap_cfg["password"]: - root = repo_root() - env_path = root / ".secrets" / "git-issues" / "imap-bridge.env" print("[git-issues] ERROR: IMAP_USER and IMAP_PASSWORD required.", file=sys.stderr) + print(f"[git-issues] {IMAP_SMTP_CONFIG_DOC_REF}", file=sys.stderr) sys.exit(1) gitea_cfg = load_gitea_config() if not gitea_cfg["token"]: print("[git-issues] ERROR: GITEA_TOKEN not set.", file=sys.stderr) + print(f"[git-issues] {IMAP_SMTP_CONFIG_DOC_REF}", file=sys.stderr) sys.exit(1) mail = imaplib.IMAP4(imap_cfg["host"], int(imap_cfg["port"])) diff --git a/git-issues/mail_common.py b/git-issues/mail_common.py index 3ee45c3..536a242 100644 --- a/git-issues/mail_common.py +++ b/git-issues/mail_common.py @@ -11,6 +11,9 @@ from pathlib import Path from urllib.error import HTTPError, URLError from urllib.request import Request, urlopen +# Must match automation/imap-bridge/imap_common.IMAP_SMTP_CONFIG_DOC_REF (used before imap_common is importable). +_BOOTSTRAP_IMAP_DOC_REF = "voir automation/imap-bridge/README.md" + def _imap_bridge_python_dir() -> Path: if os.environ.get("LECOFFRE_REPO_ROOT"): @@ -24,7 +27,8 @@ def _imap_bridge_python_dir() -> Path: return sibling raise ImportError( "imap_common not found: set LECOFFRE_REPO_ROOT to the LeCoffre monorepo root " - "or clone lecoffre_ng_test beside ia_dev (../lecoffre_ng_test/automation/imap-bridge/imap_common.py)." + "or clone lecoffre_ng_test beside ia_dev (../lecoffre_ng_test/automation/imap-bridge/imap_common.py). " + + _BOOTSTRAP_IMAP_DOC_REF ) @@ -33,6 +37,7 @@ if str(_pkg) not in sys.path: sys.path.insert(0, str(_pkg)) from imap_common import ( + IMAP_SMTP_CONFIG_DOC_REF, MAIL_SINCE_DATE_DEFAULT, imap_search_criterion_all, imap_search_criterion_unseen, diff --git a/git-issues/tickets-fetch-inbox.py b/git-issues/tickets-fetch-inbox.py index 1dba2eb..7893358 100644 --- a/git-issues/tickets-fetch-inbox.py +++ b/git-issues/tickets-fetch-inbox.py @@ -26,7 +26,7 @@ from email.utils import parsedate_to_datetime from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) -from mail_common import imap_search_criterion_all, load_imap_config, imap_ssl_context +from mail_common import IMAP_SMTP_CONFIG_DOC_REF, imap_search_criterion_all, imap_ssl_context, load_imap_config from project_config import ( data_issues_dir_for_project, ia_dev_root, @@ -168,6 +168,7 @@ def main() -> int: cfg = load_imap_config() if not cfg["user"] or not cfg["password"]: print("[tickets-fetch-inbox] IMAP_USER and IMAP_PASSWORD required.", file=sys.stderr) + print(f"[tickets-fetch-inbox] {IMAP_SMTP_CONFIG_DOC_REF}", file=sys.stderr) return 1 # Spool is per-project; each message is routed by its To address to projects//data/issues/