diff options
-rw-r--r-- | .guix.scm | 46 | ||||
-rw-r--r-- | Documentation/RelNotes/0.5.0.txt | 37 | ||||
-rw-r--r-- | Documentation/piem.texi | 10 | ||||
-rw-r--r-- | Makefile | 16 | ||||
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | piem-b4.el | 6 | ||||
-rw-r--r-- | piem-debbugs.el | 67 | ||||
-rw-r--r-- | piem-elfeed.el | 2 | ||||
-rw-r--r-- | piem-eww.el | 2 | ||||
-rw-r--r-- | piem-gnus.el | 57 | ||||
-rw-r--r-- | piem-notmuch.el | 27 | ||||
-rw-r--r-- | piem.el | 116 | ||||
-rw-r--r-- | tests/piem-rmail-tests.el | 10 | ||||
-rw-r--r-- | tests/piem-tests.el | 28 |
14 files changed, 293 insertions, 133 deletions
@@ -26,55 +26,16 @@ ;; guix environment --load=.guix.scm (use-modules (guix build utils) - (guix build-system emacs) - (guix build-system python) (guix gexp) (guix git-download) - ((guix licenses) #:prefix license:) (guix packages) (gnu packages emacs) (gnu packages emacs-xyz) - (gnu packages python-web) - (gnu packages mail) (gnu packages texinfo) - (gnu packages version-control) (ice-9 popen) (ice-9 rdelim)) -;;; Package definitions that should eventually be polished and -;;; submitted upstream. - -(define-public piem - (package - (name "piem") - (version "0.4.0") - (source - (origin - (method git-fetch) - (uri (git-reference - (url "https://git.kyleam.com/piem.git") - (commit (string-append "v" version)))) - (file-name (string-append name "-" version "-checkout")) - (sha256 - (base32 "07jagfxxnj383k48x8wdps160zggpxqknb65qr9f4k4i7hd8nykf")) - (modules '((guix build utils))) - ;; TODO: Decide how to deal with these optional libraries. - (snippet - '(begin (delete-file "piem-notmuch.el") - (delete-file "piem-elfeed.el") - #t)))) - (build-system emacs-build-system) - (propagated-inputs - `(("b4" ,b4) - ("emacs" ,emacs) - ("emacs-transient" ,emacs-transient))) - (license license:gpl3) - (home-page "https://git.kyleam.com/piem") - (synopsis "") - (description ""))) - - ;;; Development definition for piem (define %source-dir @@ -92,7 +53,7 @@ newspace." (let ((commit (git-output "rev-parse" "--short" "HEAD"))) (package - (inherit piem) + (inherit emacs-piem) (name "piem-dev") (version (string-append "000-" commit)) (source (local-file %source-dir @@ -100,9 +61,6 @@ newspace." #:select? (git-predicate %source-dir))) (propagated-inputs `(("emacs" ,emacs) - ("emacs-elfeed" ,emacs-elfeed) ("emacs-magit" ,emacs-magit) - ("git" ,git) - ("notmuch" ,notmuch) ("texinfo" ,texinfo) - ,@(package-propagated-inputs piem))))) + ,@(package-propagated-inputs emacs-piem))))) diff --git a/Documentation/RelNotes/0.5.0.txt b/Documentation/RelNotes/0.5.0.txt new file mode 100644 index 0000000..0e6c7fc --- /dev/null +++ b/Documentation/RelNotes/0.5.0.txt @@ -0,0 +1,37 @@ +piem v0.5.0 release notes +========================= + +Changes since v0.4.0 +-------------------- + + * New library piem-debbugs.el provides Debbugs mode integration. + + * New :gnu-package property enables mapping a message to an inbox via + the X-GNU-PR-Package header (present on <https://bugs.gnu.org> + messages). + + * An inbox can now be linked to multiple repositories by setting + :coderepo to a list. + + * :url values in piem-inboxes no longer require a trailing slash. + + * piem-inject-thread-into-maildir gained an INBOX argument to enable + Lisp callers to specify an inbox. Thanks to zimoun for the + suggestion. + + * The piem-b4-am transient now includes --cc-trailers (added in b4 + v0.6.0). + + * The logic to insert a Message-ID header when + piem-add-message-id-header is non-nil has been updated to account + for a recent change in how Git spells the header. + + * piem-am now reorders attachments to be more helpful in cases where + the sender attaches the patches out of order. Thanks for Ihor + Radchenko for the suggestion. + +Fixes since v0.4.0 +------------------ + + * piem-gnus-mid-to-thread didn't consider that + gnus-summary-display-article may dump a message in mbox format. diff --git a/Documentation/piem.texi b/Documentation/piem.texi index 26962a4..45c6a5c 100644 --- a/Documentation/piem.texi +++ b/Documentation/piem.texi @@ -1,6 +1,6 @@ \input texinfo @c -*-texinfo-*- -@set VERSION 0.4.0 +@set VERSION 0.5.0 @setfilename piem.info @documentencoding UTF-8 @@ -168,6 +168,12 @@ repository (e.g., if the inbox receives patches for multiple projects, or if you use a few dedicated Git worktrees for different types of patches), set @code{:coderepo} to a list of locations. +@cindex issue tracking +@cindex Debbugs, issue tracking system +When using the Debbugs instance at @uref{https://bugs.gnu.org} to +retrieve messages, an inbox can mapped to each message by setting +@code{:gnu-package} for an inbox. + @findex piem-merged-inboxes @vindex piem-get-inboxes-from-config If you mirror some inboxes locally (e.g., for fast local access or for @@ -216,6 +222,7 @@ command @code{piem-clear-merged-inboxes} to clear the cache. @node Enabling integration libraries @section Enabling integration libraries +@findex piem-debbugs-mode @findex piem-elfeed-mode @findex piem-eww-mode @findex piem-gnus-mode @@ -227,6 +234,7 @@ particular Emacs modes to link a buffer with a registered inbox. piem currently has libraries to support @itemize +@item Debbugs @item EWW @item Elfeed @item Gnus @@ -4,9 +4,10 @@ EMACS = emacs # Rely on EMACSLOADPATH for everything but the current directory. BATCH = $(EMACS) --batch -Q -L . -L tests -EL = piem.el piem-b4.el piem-elfeed.el piem-eww.el piem-gnus.el \ - piem-lei.el piem-maildir.el piem-notmuch.el piem-rmail.el \ - tests/piem-lei-tests.el tests/piem-rmail-tests.el tests/piem-tests.el +EL = piem.el piem-b4.el piem-debbugs.el piem-elfeed.el piem-eww.el \ + piem-gnus.el piem-lei.el piem-maildir.el piem-notmuch.el \ + piem-rmail.el tests/piem-lei-tests.el tests/piem-rmail-tests.el \ + tests/piem-tests.el ELC = $(EL:.el=.elc) all: compile Documentation/piem.info piem-autoloads.el @@ -33,6 +34,7 @@ docs: Documentation/piem.html Documentation/piem.info piem-b4.elc: piem-b4.el piem.elc piem-elfeed.elc: piem-elfeed.el piem.elc +piem-debbugs.elc: piem-debbugs.el piem.elc piem-eww.elc: piem-eww.el piem.elc piem-gnus.elc: piem-gnus.el piem.elc piem-lei.elc: piem-lei.el piem.elc @@ -55,3 +57,11 @@ tests/piem-tests.elc: tests/piem-tests.el piem.elc .texi.html: makeinfo --html --css-ref=manual.css -c TOP_NODE_UP_URL=/ --no-split \ -o $@ $< + +sign-tar: + tag="$$(git describe --abbrev=0)"; \ + object=$$(git archive --format tar \ + --prefix "piem-$${tag#v}/" "$$tag" | \ + gpg --output - --armor --detach-sign | \ + git hash-object -w --stdin); \ + git notes --ref=refs/notes/signatures/tar add -C "$$object" "$$tag" @@ -9,7 +9,7 @@ Should have ability to extract message ID from link (like lei-lcat) and give priority to local sources. ** support piem-am as jumping point to existing branch? -See discussion staring at <8735i0urq7.fsf@localhost>. +See discussion starting at <8735i0urq7.fsf@localhost>. * b4 @@ -73,7 +73,7 @@ This is intended to be used for debugging purposes.") ;; b4's configuration. (unless local-mbox-p (when-let ((url (and (equal mid (piem-mid)) - (piem-inbox-get :url)))) + (piem-inbox-url)))) (ignore-errors (piem-with-url-contents (concat url (piem-escape-mid mid) "/t.mbox.gz") @@ -131,7 +131,7 @@ list of arguments specified via ARGS." (defun piem-b4-am-from-mid (mid &optional args toggle-worktree) "Get the thread for MID, extract an am-ready mbox, and apply it. -Try to generate a thread for the Message-Id MID with +Try to generate a thread for MID with `piem-mid-to-thread-functions'. If that fails, try to download the thread from an inbox URL associated with the current buffer, provided that the current buffer's message ID matches MID. And @@ -250,7 +250,7 @@ this triggers the creation of a new worktree." (piem-b4-am:--outdir) (piem-b4-am:--mbox-name) ("-M" "Save as maildir" "--save-as-maildir") - (7 "-Q" "Save as quilt-read folder" "--quilt-ready") + (7 "-Q" "Save as quilt-ready folder" "--quilt-ready") ;; Hide because this is unlikely to be useful outside of ;; command-line piping to `git am'. (5 "-V" "Do not save cover letter" "--no-cover")] diff --git a/piem-debbugs.el b/piem-debbugs.el new file mode 100644 index 0000000..00b0354 --- /dev/null +++ b/piem-debbugs.el @@ -0,0 +1,67 @@ +;;; piem-debbugs.el --- Debbugs integration for piem -*- lexical-binding: t; -*- + +;; Copyright all piem contributors <piem@inbox.kyleam.com> + +;; Author: Jelle Licht <jlicht@fsfe.org> +;; Keywords: vc, tools +;; Package-Requires: ((emacs "26.3")(debbugs "0.29")) + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This library provides a minor mode, `piem-debbugs-mode', that modifies +;; `piem' variables to teach functions like `piem-inbox' how to +;; extract information from Debbugs buffers. + +;;; Code: + +(require 'debbugs-gnu) +(require 'piem) + +(defgroup piem-debbugs nil + "Debbugs integration for piem." + :group 'piem) + +(defun piem-debbugs-get-inbox () + "Return inbox name from a Debbugs buffer." + (when (and (derived-mode-p 'debbugs-gnu-mode) + (boundp 'debbugs-gnu-local-query)) + (when-let ((gnu-package (alist-get 'package debbugs-gnu-local-query))) + (piem-inbox-by-gnu-package-match gnu-package)))) + +(defun piem-debbugs-get-mid () + "Return the message ID of a Debbugs buffer." + (when (derived-mode-p 'debbugs-gnu-mode) + (let ((msgid (alist-get 'msgid (debbugs-gnu-current-status)))) + (when (stringp msgid) + (string-trim msgid "<" ">"))))) + +;;;###autoload +(define-minor-mode piem-debbugs-mode + "Toggle Debbugs support for piem. +With a prefix argument ARG, enable piem-debbugs mode if ARG is +positive, and disable it otherwise. If called from Lisp, enable +the mode if ARG is omitted or nil." + :global t + :init-value nil + (if piem-debbugs-mode + (progn + (add-hook 'piem-get-inbox-functions #'piem-debbugs-get-inbox) + (add-hook 'piem-get-mid-functions #'piem-debbugs-get-mid)) + (remove-hook 'piem-get-inbox-functions #'piem-debbugs-get-inbox) + (remove-hook 'piem-get-mid-functions #'piem-debbugs-get-mid))) + +;;; piem-debbugs.el ends here +(provide 'piem-debbugs) diff --git a/piem-elfeed.el b/piem-elfeed.el index ce9c75c..eef61e8 100644 --- a/piem-elfeed.el +++ b/piem-elfeed.el @@ -44,7 +44,7 @@ (defun piem-elfeed-get-mid () "Return the message ID of an `elfeed-show-mode' buffer." (when-let ((inbox (piem-elfeed-get-inbox)) - (inbox-url (piem-inbox-get :url inbox)) + (inbox-url (piem-inbox-url inbox)) (link (elfeed-entry-link elfeed-show-entry))) (and (string-match (piem-message-link-re inbox-url) link) (url-unhex-string (match-string 1 link))))) diff --git a/piem-eww.el b/piem-eww.el index 01a9f9d..5769060 100644 --- a/piem-eww.el +++ b/piem-eww.el @@ -43,7 +43,7 @@ (defun piem-eww-get-mid () "Return the message ID of an EWW buffer." (when-let ((inbox (piem-eww-get-inbox)) - (inbox-url (piem-inbox-get :url inbox)) + (inbox-url (piem-inbox-url inbox)) (url (plist-get eww-data :url))) (and (string-match (piem-message-link-re inbox-url) url) (url-unhex-string (match-string 1 url))))) diff --git a/piem-gnus.el b/piem-gnus.el index c62a2e6..b6dc672 100644 --- a/piem-gnus.el +++ b/piem-gnus.el @@ -56,6 +56,21 @@ (match-string 1 mid) mid))))) +(defun piem-gnus--from-line (buffer) + "Split a buffer into from-line and the rest of the message. + +Returns a cons of the first line of BUFFER, if it is an mboxrd +from-line (or nil if none), and the remaining lines of BUFFER." + (with-current-buffer buffer + (let ((start (point-min)) + (end (point-max))) + (goto-char start) + (let* ((eol (line-end-position)) + (line (buffer-substring-no-properties start eol))) + (if (string-match-p "^From " line) + (cons line (buffer-substring-no-properties (+ eol 1) end)) + (cons nil (buffer-substring-no-properties start end))))))) + (defun piem-gnus-mid-to-thread (mid) (when (and (derived-mode-p 'gnus-summary-mode) (string-equal (substring @@ -75,44 +90,48 @@ gnus-break-pages) (mapc (lambda (article) (gnus-summary-display-article article) - (push (format - "From mboxrd@z Thu Jan 1 00:00:00 1970\n%s\n" - (replace-regexp-in-string ; From-munge - "^>*From " - ">\\&" - (with-current-buffer gnus-article-buffer - (buffer-substring-no-properties - (point-min) - (point-max))))) - messages)) + (let ((from-line-cons + (piem-gnus--from-line gnus-article-buffer))) + (push (format + "%s\n%s\n" + (or (car from-line-cons) + "From mboxrd@z Thu Jan 1 00:00:00 1970") + (replace-regexp-in-string + "^>*From " + ">\\&" + (cdr from-line-cons))) + messages))) articles) (lambda () (insert (apply #'concat (nreverse messages)))))))) (defun piem-gnus-am-ready-mbox () "Return a function that inserts an am-ready mbox. + If the buffer has any MIME parts that look like a patch, use -those parts' contents (in order) as the mbox. Otherwise, use the -message itself if it looks like a patch." +those parts' contents as the mbox, ordering the patches based on +the number at the start of the file name. If none of the file +names start with a number, retain the original order of the +attachments. + +If no MIME parts look like a patch, use the message itself if it +looks like a patch." (when (derived-mode-p 'gnus-article-mode 'gnus-summary-mode) (cond (gnus-article-mime-handles (when-let ((patches (delq nil (mapcar #'piem-am-extract-attached-patch gnus-article-mime-handles)))) + (setq patches (sort patches (lambda (x y) (< (car x) (car y))))) (cons (lambda () (dolist (patch patches) - (insert patch))) + (insert (cdr patch)))) "mbox"))) (gnus-article-buffer (when-let ((patch (with-current-buffer gnus-article-buffer (save-restriction (widen) - (and (string-match-p - piem-patch-subject-re - (mail-decode-encoded-word-string - (message-field-value "subject"))) - (buffer-substring-no-properties - (point-min) (point-max))))))) + (buffer-substring-no-properties + (point-min) (point-max)))))) (cons (lambda () (insert patch)) "mbox")))))) diff --git a/piem-notmuch.el b/piem-notmuch.el index 41f2793..9077ec8 100644 --- a/piem-notmuch.el +++ b/piem-notmuch.el @@ -85,31 +85,36 @@ have surrounding brackets." (defun piem-notmuch-am-ready-mbox () "Return a function that inserts an am-ready mbox. + If the buffer has any MIME parts that look like a patch, use -those parts' contents (in order) as the mbox. Otherwise, use the -message itself if it looks like a patch." +those parts' contents as the mbox, ordering the patches based on +the number at the start of the file name. If none of the file +names start with a number, retain the original order of the +attachments. + +If no MIME parts look like a patch, use the message itself if it +looks like a patch." (when (derived-mode-p 'notmuch-show-mode) (let* ((handle (piem-notmuch--with-current-message (mm-dissect-buffer))) (n-attachments (notmuch-count-attachments handle)) patches) (if (= n-attachments 0) - (when (string-match-p piem-patch-subject-re - (notmuch-show-get-subject)) - (let ((id (notmuch-show-get-message-id))) - (lambda () - (call-process notmuch-command nil t nil - "show" "--format=mbox" id)))) + (let ((id (notmuch-show-get-message-id))) + (lambda () + (call-process notmuch-command nil t nil + "show" "--format=mbox" id))) (notmuch-foreach-mime-part (lambda (p) (when-let ((patch (piem-am-extract-attached-patch p))) (push patch patches))) handle) (when patches - (setq patches (nreverse patches)) + (setq patches (sort (nreverse patches) + (lambda (x y) (< (car x) (car y))))) (cons (lambda () (dolist (patch patches) - (insert patch))) + (insert (cdr patch)))) "mbox")))))) (defun piem-notmuch-extract-patch-am-ready-mbox () @@ -118,8 +123,6 @@ Use the message itself if it looks like a patch using notmuch-extract-patch to get the latest patch series from the notmuch thread." (when (and (derived-mode-p 'notmuch-show-mode) - (string-match-p piem-patch-subject-re - (notmuch-show-get-subject)) (= (notmuch-count-attachments (piem-notmuch--with-current-message (mm-dissect-buffer))) @@ -4,7 +4,7 @@ ;; Author: Kyle Meyer <kyle@kyleam.com> ;; Keywords: vc, tools -;; Version: 0.4.0 +;; Version: 0.5.0 ;; Package-Requires: ((emacs "26.3") (transient "0.3.0")) ;; Homepage: https://git.kyleam.com/piem/about/ @@ -80,9 +80,11 @@ list that supports the following properties: repository, with the first value in this list offered as the default. :url - A URL hosting HTTPS archives. This value must end with a slash. + A URL hosting HTTPS archives. :maildir A Maildir directory to inject messages into. + :gnu-package + A GNU Bug Tracker label to match with for the inbox. Here's an example for the public-inbox project itself: @@ -156,10 +158,10 @@ value passed to `git am'. If unspecified, \"mboxrd\" is used." :type 'hook) (defcustom piem-add-message-id-header nil - "Whether to add Message-Id header to non-mail patches. + "Whether to add Message-ID header to non-mail patches. If this value is non-nil and a patch returned by a function in `piem-am-ready-mbox-functions' looks like a patch that was -attached rather than sent inline, add a Message-Id header with +attached rather than sent inline, add a Message-ID header with the return value of `piem-mid'." :type 'boolean) @@ -393,7 +395,9 @@ files." (rx string-start "publicinbox." (group (one-or-more not-newline)) "." (group - (or "address" "coderepo" "listid" "maildir" "url")) + (or "address" "coderepo" + "listid" "maildir" + "url" "gnu-package")) string-end) key) (let* ((inbox-name (match-string 1 key)) @@ -488,27 +492,46 @@ non-nil, make the match specific for that message." (mail-decode-encoded-word-string val))) headers)))) +(defun piem-inbox-by-gnu-package-match (gnu-package) + "Return inbox based on matching :gnu-package properties. +GNU-PACKAGE should be a string. This function is intended to be +used by libraries implementing a function for +`piem-get-inbox-function'." + (when gnu-package + (catch 'hit + (dolist (inbox (piem-merged-inboxes)) + (let* ((info (cdr inbox)) + (p-package (plist-get info :gnu-package))) + (when (and gnu-package + p-package + (string-equal (downcase p-package) + (downcase gnu-package))) + (throw 'hit (car inbox)))))))) + (defun piem-inbox-by-header-match () "Return inbox based on matching message headers. This should be called from a buffer containing a message and is intended to be used by libraries implementing a function for -`piem-get-mid-functions'." - (pcase-let ((`(,listid ,to ,cc) - (piem--message-fetch-decoded-fields '("list-id" "to" "cc")))) - (catch 'hit - (dolist (inbox (piem-merged-inboxes)) - (let* ((info (cdr inbox)) - (p-listid (plist-get info :listid))) - (when (and listid - p-listid - (string-match-p (concat "<" (regexp-quote p-listid) ">") - listid)) - (throw 'hit (car inbox))) - (when-let ((addr (plist-get info :address)) - (to (mapconcat #'identity (list to cc) - " "))) - (when (string-match-p (regexp-quote addr) to) - (throw 'hit (car inbox))))))))) +`piem-get-inbox-functions'." + (pcase-let ((`(,listid ,to ,cc ,gnu-package) + (piem--message-fetch-decoded-fields + '("list-id" "to" "cc" "x-gnu-pr-package")))) + (or (catch 'hit + (dolist (inbox (piem-merged-inboxes)) + (let* ((info (cdr inbox)) + (p-listid (plist-get info :listid))) + (when (and listid + p-listid + (string-match-p + (concat "<" (regexp-quote p-listid) ">") + listid)) + (throw 'hit (car inbox))) + (when-let ((addr (plist-get info :address)) + (to (mapconcat #'identity (list to cc) + " "))) + (when (string-match-p (regexp-quote addr) to) + (throw 'hit (car inbox))))))) + (piem-inbox-by-gnu-package-match gnu-package)))) (defun piem-inbox () "Return the current buffer's inbox." @@ -522,6 +545,13 @@ returned by `piem-inbox'." (when-let ((p (or inbox (piem-inbox)))) (plist-get (cdr (assoc p (piem-merged-inboxes))) key))) +(defun piem-inbox-url (&optional inbox) + "Return URL associated with INBOX. +If INBOX is nil, use the inbox returned by `piem-inbox'." + (when-let ((inbox (or inbox (piem-inbox))) + (url (piem-inbox-get :url inbox))) + (piem--ensure-trailing-slash url))) + (defun piem-inbox-coderepo (&optional inbox) "Return the code repository of current buffer's inbox." (when-let ((inbox (or inbox (piem-inbox))) @@ -601,8 +631,11 @@ public-inbox's configuration), return the value of (rx line-start (zero-or-one space) line-end)))) (cond ((looking-at-p + ;; git-format-patch switched to "Message-ID" spelling + ;; in v2.41. (rx line-start - "Message-Id: <" (one-or-more not-newline) ">" + "Message-" (or "Id" "ID") + ": <" (one-or-more not-newline) ">" line-end)) (throw 'has-message-id nil)) ((looking-at-p @@ -612,7 +645,7 @@ public-inbox's configuration), return the value of (when (= header-count 3) ;; Found all the expected headers before hitting a ;; blank line. Assume we're in a header. - (insert (format "Message-Id: <%s>\n" mid)))))))) + (insert (format "Message-ID: <%s>\n" mid)))))))) (defun piem-am-ready-mbox (&optional buffer-name) "Generate a buffer containing an am-ready mbox. @@ -662,10 +695,9 @@ The URL for INBOX may be defined in `piem-inboxes' or public-inbox's configuration. If INBOX is nil, use the inbox returned by `piem-inbox'." (concat - (piem--ensure-trailing-slash - (or (piem-inbox-get :url inbox) - (user-error "Couldn't find URL for %s" - (or inbox "current buffer")))) + (or (piem-inbox-url inbox) + (user-error "Couldn't find URL for %s" + (or inbox "current buffer"))) (piem-escape-mid mid))) ;;;###autoload @@ -756,7 +788,7 @@ is used as the value of `browse-url-browser-function'." (save-excursion (message-narrow-to-head-1) (message-fetch-field "message-id" t))) - (error "Message lacks Message-Id header"))))))) + (error "Message lacks Message-ID header"))))))) (cl-incf n-skipped) (let ((case-fold-search nil)) (while (re-search-forward @@ -817,17 +849,21 @@ message for MID, not the entire thread." ;;;; Patch handling (defun piem-am-extract-attached-patch (handle) - "Return content for HANDLE if it looks like a patch." - (and (listp handle) - (let ((type (mm-handle-media-type handle)) - (filename (mm-handle-filename handle))) - (or (member type '("text/x-diff" "text/x-patch")) - (and filename - (equal type "text/plain") - (string-suffix-p ".patch" filename t)))) - (with-temp-buffer - (mm-display-inline handle) - (buffer-substring-no-properties (point-min) (point-max))))) + "Get the content for HANDLE if it looks like a patch. +The return value is of the form (N . CONTENT), where N is the +number at the start of the file name." + (when (listp handle) + (let ((type (mm-handle-media-type handle)) + (filename (mm-handle-filename handle))) + (and (or (member type '("text/x-diff" "text/x-patch")) + (and filename + (equal type "text/plain") + (string-suffix-p ".patch" filename t))) + (with-temp-buffer + (mm-display-inline handle) + (cons + (string-to-number filename) + (buffer-substring-no-properties (point-min) (point-max)))))))) (defun piem-extract-mbox-info (&optional buffer) "Collect information from message in BUFFER. diff --git a/tests/piem-rmail-tests.el b/tests/piem-rmail-tests.el index a9b397b..7ee0a55 100644 --- a/tests/piem-rmail-tests.el +++ b/tests/piem-rmail-tests.el @@ -38,7 +38,7 @@ To: A <a@example.com> Cc: i@inbox.example.com Subject: Re: test Date: Sun, 23 May 2021 02:26:51 -0400 -Message-Id: <456@example.com> +Message-ID: <456@example.com> In-Reply-To: <123@example.com> References: <123@example.com> @@ -47,12 +47,16 @@ References: <123@example.com> no thanks ") +(defun piem-rmail-tests-rmail-mode () + (cl-letf (((symbol-function #'message) (lambda (&rest _)))) + (rmail-mode))) + (ert-deftest piem-rmail-get-inbox () (should (equal "foo" (with-temp-buffer (insert piem-rmail-tests-mbox-text) - (rmail-mode) + (piem-rmail-tests-rmail-mode) (let ((piem-get-inboxes-from-config nil) (piem-inboxes '(("foo" :address "i@inbox.example.com")))) (piem-rmail-get-inbox)))))) @@ -62,7 +66,7 @@ no thanks (equal (list "123@example.com" "456@example.com") (with-temp-buffer (insert piem-rmail-tests-mbox-text) - (rmail-mode) + (piem-rmail-tests-rmail-mode) (rmail-first-message) (let ((piem-get-inboxes-from-config nil) (piem-inboxes '(("foo" :address "i@inbox.example.com")))) diff --git a/tests/piem-tests.el b/tests/piem-tests.el index 79d8591..b612b96 100644 --- a/tests/piem-tests.el +++ b/tests/piem-tests.el @@ -74,7 +74,7 @@ (piem-merged-inboxes)))) (let ((piem-get-inboxes-from-config nil) (piem-inboxes '(("inbox" :url "inbox-url")))) - (should (equal (piem-inbox-get :url "inbox") "inbox-url")))) + (should (equal (piem-inbox-url "inbox") "inbox-url/")))) (ert-deftest piem-merged-inboxes:from-config () (piem-clear-merged-inboxes) @@ -83,8 +83,8 @@ (piem-tests-with-pi-config piem-tests-sample-pi-config (should (equal (piem-inbox-get :address "foo") "foo@example.com")) - (should (equal (piem-inbox-get :url "foo") - "https://example.com/foo")) + (should (equal (piem-inbox-url "foo") + "https://example.com/foo/")) (should (equal (piem-inbox-coderepo "foo") "/code/foo/"))) (piem-tests-with-pi-config "" @@ -179,12 +179,30 @@ (should-not (with-temp-buffer (piem--insert-message-id-header "msg@id"))) + (should-not + (string-match-p + "Message-ID: <msg@id>" + (with-temp-buffer + (insert "\ +From 0d732713af1f3fb48b37430e2cd0a3033cea14f3 Mon Sep 17 00:00:00 2001 +From: Foo Bar <f@example.com> +Message-ID: <existing@id> +Date: Fri, 22 Jan 2021 22:35:58 -0500 +Subject: [PATCH] a + +--- + a | 1 + + 1 file changed, 1 insertion(+) + create mode 100644 a") + (goto-char (point-min)) + (piem--insert-message-id-header "msg@id") + (buffer-string)))) (should (string-match-p (concat - (rx "Subject: [PATCH 1/2] a\nMessage-Id: <msg@id>\n" + (rx "Subject: [PATCH 1/2] a\nMessage-ID: <msg@id>\n" (one-or-more anychar) - "Subject: [PATCH 2/2] b\nMessage-Id: <msg@id>\n")) + "Subject: [PATCH 2/2] b\nMessage-ID: <msg@id>\n")) (with-temp-buffer (insert "\ From 0d732713af1f3fb48b37430e2cd0a3033cea14f3 Mon Sep 17 00:00:00 2001 |