trailers: add 'Closes' as recognized link trailer

The Closes tag has been used for quite a long time in the Linux kernel,
mainly by DRM and MPTCP subsystems. It is used by some bug trackers like
GitHub, GitLab and bugzilla.kernel.org to automate the closure of issues
when a patch is accepted.

In Linux 6.3, checkpatch started to complain about this tag because it
has never been described in the documentation. The situation has changed
in Linux 6.4 [1]: I initially just wanted to allow the Closes tag but
some reviewers pointed out that bots reading mailing lists like RegzBot
would be interested to have it instead of the Link tag when any kind of
bug is being closed. So now after a Reported-by, checkpatch.pl now
suggests to add a Closes with a link.

In other words, it is now more common to see this Closes tag in the
Linux kernel. It is certainly used in many other projects than the Linux
kernel.

This Closes tag is treated as a Link tag.

Note that existing test files have been modified. You will probably need
to run "pytest --cache-clear" to avoid using the previous version.

Link: https://lore.kernel.org/all/20230314-doc-checkpatch-closes-tag-v4-0-d26d1fa66f9f@tessares.net/ [1]
Reported-by: Nick Desaulniers <ndesaulniers@google.com>
Closes: https://lore.kernel.org/all/CAKwvOdm=Zk8YhrPptN3k7UQo+1n7Ws=Qox=BwTR9bbjPJJYz8A@mail.gmail.com/
Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Link: https://msgid.link/20230525-closes-tags-v1-2-ed41b1773cb6@tessares.net
Signed-off-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
diff --git a/b4/__init__.py b/b4/__init__.py
index e9e7b64..44deacd 100644
--- a/b4/__init__.py
+++ b/b4/__init__.py
@@ -885,7 +885,7 @@
     addr: Optional[Tuple[str, str]] = None
     lmsg = None
     # Small list of recognized utility trailers
-    _utility: Set[str] = {'fixes', 'link', 'buglink', 'obsoleted-by', 'message-id', 'change-id', 'base-commit'}
+    _utility: Set[str] = {'fixes', 'link', 'buglink', 'closes', 'obsoleted-by', 'message-id', 'change-id', 'base-commit'}
 
     def __init__(self, name: Optional[str] = None, value: Optional[str] = None, extinfo: Optional[str] = None,
                  msg: Optional[email.message.Message] = None):
@@ -1656,7 +1656,7 @@
     def find_trailers(body: str, followup: bool = False) -> Tuple[List[LoreTrailer], List[str]]:
         ignores = {'phone', 'email'}
         headers = {'subject', 'date', 'from'}
-        links = {'link', 'buglink'}
+        links = {'link', 'buglink', 'closes'}
         nonperson = links | {'fixes', 'subject', 'date', 'obsoleted-by', 'change-id', 'base-commit'}
         # Ignore everything below standard email signature marker
         body = body.split('\n-- \n', 1)[0].strip() + '\n'
diff --git a/tests/samples/trailers-thread-with-cover-followup.mbox b/tests/samples/trailers-thread-with-cover-followup.mbox
index bbdeeeb..5c4e64e 100644
--- a/tests/samples/trailers-thread-with-cover-followup.mbox
+++ b/tests/samples/trailers-thread-with-cover-followup.mbox
@@ -226,6 +226,7 @@
 
 Tested-by: Follow Upper <follow.upper@example.org>
 Link: https://example.org
+Closes: https://example.org/bug/1234
 
 -- 
 Follow Upper
diff --git a/tests/samples/trailers-thread-with-cover-followup.verify b/tests/samples/trailers-thread-with-cover-followup.verify
index b42e1ed..acd6278 100644
--- a/tests/samples/trailers-thread-with-cover-followup.verify
+++ b/tests/samples/trailers-thread-with-cover-followup.verify
@@ -5,6 +5,7 @@
 Signed-off-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
 Tested-by: Follow Upper <follow.upper@example.org>
 Link: https://example.org
+Closes: https://example.org/bug/1234
 Reviewed-by: Cover Upper <cover.upper@example.org>
 Signed-off-by: Test Override <test-override@example.com>
 ---