feat(branch): créer la branche depuis la carte (issue #3)
slugify + branch_name_for (issue-<n>-<slug>, reconnu par #1/#2);
client create_branch; POST /api/issues/{o}/{r}/{n}/branch (nom
libre validé, idempotent si existante); la carte passe en En
cours, journalisée source branch, étiquette synchronisée;
formulaire dans la section Code lié du panneau détail.
This commit is contained in:
@@ -7,6 +7,7 @@ a token in a branch name (`feature/12-login`, `issue-12`, `12-fix`).
|
||||
"""
|
||||
|
||||
import re
|
||||
import unicodedata
|
||||
|
||||
_REF_RE = re.compile(r"(?<![\w#])#(\d+)\b")
|
||||
_BRANCH_TOKEN_RE = re.compile(r"(?:^|[-_/])(\d+)(?:[-_/]|$)")
|
||||
@@ -27,6 +28,26 @@ def branch_issue_number(branch_name: str | None) -> int | None:
|
||||
return int(m.group(1)) if m else None
|
||||
|
||||
|
||||
def slugify_title(title: str, max_len: int = 40) -> str:
|
||||
"""ASCII slug for a branch name: 'Créer la branche !' -> 'creer-la-branche'."""
|
||||
normalized = unicodedata.normalize("NFKD", title or "")
|
||||
ascii_text = normalized.encode("ascii", "ignore").decode("ascii")
|
||||
slug = re.sub(r"[^a-z0-9]+", "-", ascii_text.lower()).strip("-")
|
||||
slug = re.sub(r"-{2,}", "-", slug)
|
||||
if len(slug) > max_len:
|
||||
slug = slug[:max_len].rstrip("-")
|
||||
return slug or "issue"
|
||||
|
||||
|
||||
def branch_name_for(number: int, title: str) -> str:
|
||||
"""The branch a card would create (issue #3): issue-<n>-<slug>.
|
||||
|
||||
The name is recognized back by branch_issue_number, which is
|
||||
what links the future PR to this card (issue #2).
|
||||
"""
|
||||
return f"issue-{number}-{slugify_title(title)}"
|
||||
|
||||
|
||||
def find_code_links(
|
||||
branches: list[dict],
|
||||
pulls: list[dict],
|
||||
|
||||
Reference in New Issue
Block a user