all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues
@ 2023-02-20  1:38 Arun Isaac
  2023-02-20  1:41 ` [bug#61645] [PATCH mumi 1/1] client: " Arun Isaac
                   ` (6 more replies)
  0 siblings, 7 replies; 25+ messages in thread
From: Arun Isaac @ 2023-02-20  1:38 UTC (permalink / raw)
  To: 61645; +Cc: Ricardo Wurmus, Arun Isaac

Hi Ricardo,

This patch adds a mumi CLI client that lets one search for issues from
the command line by calling mumi's GraphQL API. This patch requires a
.mumi/config file in the guix repo with the following contents.

--8<---------------cut here---------------start------------->8---
((debbugs-host . "debbugs.gnu.org")
 (patch-email-address . "guix-patches@gnu.org")
 (mumi-host . "issues.guix.gnu.org"))
--8<---------------cut here---------------end--------------->8---

After adding .mumi/config, you can run search queries like

$ /path/to/mumi/pre-inst-env mumi search zig is:open

This is only the beginning. I have WIP patches that will add a "mumi
send-email" subcommand that will finally free us from our debbugs
dance when sending multiple patches. I will send them separately once
I have tested it more.

Regards,
Arun

Arun Isaac (1):
  client: Add CLI client to search for issues.

 Makefile.am     |   1 +
 mumi/client.scm | 108 ++++++++++++++++++++++++++++++++++++++++++++++++
 scripts/mumi.in |   8 +++-
 3 files changed, 116 insertions(+), 1 deletion(-)
 create mode 100644 mumi/client.scm

-- 
2.38.1





^ permalink raw reply	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH mumi 1/1] client: Add CLI client to search for issues.
  2023-02-20  1:38 [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Arun Isaac
@ 2023-02-20  1:41 ` Arun Isaac
  2023-02-21  0:32 ` [bug#61645] [PATCH v2 0/4] Add mumi CLI client Arun Isaac
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 25+ messages in thread
From: Arun Isaac @ 2023-02-20  1:41 UTC (permalink / raw)
  To: 61645; +Cc: Ricardo Wurmus, Arun Isaac

* mumi/client.scm: New file.
* scripts/mumi.in: Import (mumi client).
(show-mumi-usage): Document search subcommand.
(main): Add search subcommand.
* Makefile.am (SOURCES): Add mumi/client.scm.
---
 Makefile.am     |   1 +
 mumi/client.scm | 108 ++++++++++++++++++++++++++++++++++++++++++++++++
 scripts/mumi.in |   8 +++-
 3 files changed, 116 insertions(+), 1 deletion(-)
 create mode 100644 mumi/client.scm

diff --git a/Makefile.am b/Makefile.am
index 8182fc3..a8c11a1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,6 +49,7 @@ SOURCES =							\
   mumi/messages.scm					\
   mumi/jobs.scm						\
   mumi/send-email.scm				\
+  mumi/client.scm				\
   mumi/config.scm					\
   mumi/debbugs.scm					\
   mumi/test-utils.scm				\
diff --git a/mumi/client.scm b/mumi/client.scm
new file mode 100644
index 0000000..e4a0123
--- /dev/null
+++ b/mumi/client.scm
@@ -0,0 +1,108 @@
+;;; mumi -- Mediocre, uh, mail interface
+;;; Copyright © 2023 Arun Isaac <arunisaac@systemreboot.net>
+;;;
+;;; This file is part of mumi.
+;;;
+;;; mumi 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.
+;;;
+;;; mumi 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 mumi.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (mumi client)
+  #:use-module (srfi srfi-19)
+  #:use-module (srfi srfi-43)
+  #:use-module (term ansi-color)
+  #:use-module (web uri)
+  #:use-module (kolam http)
+  #:use-module (mumi config)
+  #:use-module (mumi web view utils)
+  #:export (search))
+
+(define (git-top-level)
+  "Return the top-level directory of the current git repository."
+  (let loop ((curdir (getcwd)))
+    (cond
+     ((file-exists? (string-append curdir "/.git"))
+      curdir)
+     ((string=? curdir "/")
+      (error "No git top level found"))
+     (else
+      (loop (dirname curdir))))))
+
+(define (client-config-directory)
+  "Return client configuration directory."
+  (string-append (git-top-level) "/.mumi"))
+
+(define (client-config key)
+  "Return client configuration value corresponding to KEY."
+  (or (assq-ref (call-with-input-file (string-append (client-config-directory)
+                                                     "/config")
+                  read)
+                key)
+      (case key
+        ((mumi-scheme) 'https)
+        (else (format (current-error-port)
+                      "Key '~a not configured for mumi client.~%"
+                      key)))))
+
+(define (graphql-endpoint)
+  "Return GraphQL endpoint."
+  (uri->string
+   (build-uri (client-config 'mumi-scheme)
+              #:host (client-config 'mumi-host)
+              #:path "/graphql")))
+
+(define (iso8601->date str)
+  "Convert ISO-8601 date/time+zone string to date object."
+  (string->date str "~Y-~m-~dT~H:~M:~S~z"))
+
+(define (list-issue issue)
+  "List issue described by ISSUE association list."
+  (display (colorize-string
+            (string-append "#"
+                           (number->string (assoc-ref issue "number")))
+            'YELLOW))
+  (display " ")
+  (unless (assoc-ref issue "open")
+    (display (colorize-string "✓" 'BOLD 'GREEN))
+    (display " "))
+  (display (colorize-string
+            (assoc-ref issue "title")
+            'MAGENTA 'UNDERLINE))
+  (newline)
+  (display (string-append
+            "opened "
+            (colorize-string (time->string
+                              (iso8601->date (assoc-ref issue "date")))
+                             'CYAN)
+            " by "
+            (colorize-string
+             (let ((submitter (assoc-ref issue "submitter")))
+               (if (eq? (assoc-ref submitter "name") 'null)
+                   (assoc-ref submitter "address")
+                   (assoc-ref submitter "name")))
+             'CYAN)))
+  (newline))
+
+(define (search query)
+  "Search for issues with QUERY and list results."
+  (vector-for-each (lambda (_ issue)
+                     (list-issue issue))
+                   (assoc-ref
+                    (graphql-http-get (graphql-endpoint)
+                                      `(document
+                                        (query (#(issues #:search ,query)
+                                                number
+                                                title
+                                                open
+                                                date
+                                                (submitter name address)))))
+                    "issues")))
diff --git a/scripts/mumi.in b/scripts/mumi.in
index 755dfb3..9b61729 100644
--- a/scripts/mumi.in
+++ b/scripts/mumi.in
@@ -4,7 +4,7 @@
 !#
 ;;; mumi -- Mediocre, uh, mail interface
 ;;; Copyright © 2016, 2017, 2019, 2020 Ricardo Wurmus <rekado@elephly.net>
-;;; Copyright © 2018, 2021 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2018, 2021, 2023 Arun Isaac <arunisaac@systemreboot.net>
 ;;;
 ;;; This file is part of mumi.
 ;;;
@@ -26,6 +26,7 @@
              (system repl server)
              (ice-9 match)
              (ice-9 format)
+             ((mumi client) #:prefix client:)
              (mumi config)
              ((mumi debbugs)
               #:select (extract-bug-numbers))
@@ -116,6 +117,9 @@
 (define (show-mumi-usage)
   (format (current-error-port)
           "
+    `mumi search QUERY':
+         search mumi for issues.
+
     `mumi web [--address=address] [--port=port] [--listen-repl[=port]] [--disable-mailer]':
          start the application web server.
 
@@ -132,6 +136,8 @@
   (exit 1))
 
 (match (cdr (program-arguments))
+  (("search" . query-strings)
+   (client:search (string-join query-strings)))
   (("mailer" . rest)
    (let* ((opts (parse-options rest))
           (sender (assoc-ref opts 'sender))
-- 
2.38.1





^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH v2 0/4] Add mumi CLI client.
  2023-02-20  1:38 [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Arun Isaac
  2023-02-20  1:41 ` [bug#61645] [PATCH mumi 1/1] client: " Arun Isaac
@ 2023-02-21  0:32 ` Arun Isaac
  2023-02-21  0:33 ` [bug#61645] [PATCH v2 1/4] client: Add CLI client to search for issues Arun Isaac
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 25+ messages in thread
From: Arun Isaac @ 2023-02-21  0:32 UTC (permalink / raw)
  To: 61645; +Cc: Ricardo Wurmus, Arun Isaac

On second thoughts, I think I'll also include the mumi send-email
patches in this bug report. To test this patchset, do the following.

The following needs to be put in .mumi/config in the guix git repo.
--8<---------------cut here---------------start------------->8---
((debbugs-host . "debbugs.gnu.org")
 (patch-email-address . "guix-patches@gnu.org")
 (mumi-host . "issues.guix.gnu.org"))
--8<---------------cut here---------------end--------------->8---

Then, from the guix git repo, it is possible to search for issues with

$ mumi search zig is:open

Set a "current issue" with

$ mumi current 61645

The "current issue" is client-side state that represents the current
issue one is working on. It is used to automatically infer such things
as the email address to send patches to.

Send patches to the current issue with

$ mumi send-email file1.patch file2.patch

`mumi send-email' also works correctly with new issues. We first open
a new issue with

$ mumi new

Then, we send patches using `mumi send-email'. The first patch is sent
to guix-patches@gnu.org and the remaining patches to the bug specific
address---our usual debbugs dance, in other words.

$ mumi send-email file1.patch file2.patch

I think this patchset works, but it would be nice if someone
independently verified it and provided some feedback before it is
applied.

Arun Isaac (4):
  client: Add CLI client to search for issues.
  client: Support checking in to a specific issue.
  client: Support sending email to issues.
  Set only GUILE_LOAD_PATH when running tests.

 Makefile.am      |   5 +-
 mumi/client.scm  | 257 +++++++++++++++++++++++++++++++++++++++++++++++
 scripts/mumi.in  |  32 +++++-
 tests/client.scm |  93 +++++++++++++++++
 4 files changed, 384 insertions(+), 3 deletions(-)
 create mode 100644 mumi/client.scm
 create mode 100644 tests/client.scm

-- 
2.38.1





^ permalink raw reply	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH v2 1/4] client: Add CLI client to search for issues.
  2023-02-20  1:38 [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Arun Isaac
  2023-02-20  1:41 ` [bug#61645] [PATCH mumi 1/1] client: " Arun Isaac
  2023-02-21  0:32 ` [bug#61645] [PATCH v2 0/4] Add mumi CLI client Arun Isaac
@ 2023-02-21  0:33 ` Arun Isaac
  2023-02-21  0:33 ` [bug#61645] [PATCH v2 2/4] client: Support checking in to a specific issue Arun Isaac
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 25+ messages in thread
From: Arun Isaac @ 2023-02-21  0:33 UTC (permalink / raw)
  To: 61645; +Cc: Ricardo Wurmus, Arun Isaac

* mumi/client.scm: New file.
* scripts/mumi.in: Import (mumi client).
(show-mumi-usage): Document search subcommand.
(main): Add search subcommand.
* Makefile.am (SOURCES): Add mumi/client.scm.
---
 Makefile.am     |   1 +
 mumi/client.scm | 108 ++++++++++++++++++++++++++++++++++++++++++++++++
 scripts/mumi.in |   8 +++-
 3 files changed, 116 insertions(+), 1 deletion(-)
 create mode 100644 mumi/client.scm

diff --git a/Makefile.am b/Makefile.am
index 8182fc3..a8c11a1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,6 +49,7 @@ SOURCES =							\
   mumi/messages.scm					\
   mumi/jobs.scm						\
   mumi/send-email.scm				\
+  mumi/client.scm				\
   mumi/config.scm					\
   mumi/debbugs.scm					\
   mumi/test-utils.scm				\
diff --git a/mumi/client.scm b/mumi/client.scm
new file mode 100644
index 0000000..e4a0123
--- /dev/null
+++ b/mumi/client.scm
@@ -0,0 +1,108 @@
+;;; mumi -- Mediocre, uh, mail interface
+;;; Copyright © 2023 Arun Isaac <arunisaac@systemreboot.net>
+;;;
+;;; This file is part of mumi.
+;;;
+;;; mumi 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.
+;;;
+;;; mumi 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 mumi.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (mumi client)
+  #:use-module (srfi srfi-19)
+  #:use-module (srfi srfi-43)
+  #:use-module (term ansi-color)
+  #:use-module (web uri)
+  #:use-module (kolam http)
+  #:use-module (mumi config)
+  #:use-module (mumi web view utils)
+  #:export (search))
+
+(define (git-top-level)
+  "Return the top-level directory of the current git repository."
+  (let loop ((curdir (getcwd)))
+    (cond
+     ((file-exists? (string-append curdir "/.git"))
+      curdir)
+     ((string=? curdir "/")
+      (error "No git top level found"))
+     (else
+      (loop (dirname curdir))))))
+
+(define (client-config-directory)
+  "Return client configuration directory."
+  (string-append (git-top-level) "/.mumi"))
+
+(define (client-config key)
+  "Return client configuration value corresponding to KEY."
+  (or (assq-ref (call-with-input-file (string-append (client-config-directory)
+                                                     "/config")
+                  read)
+                key)
+      (case key
+        ((mumi-scheme) 'https)
+        (else (format (current-error-port)
+                      "Key '~a not configured for mumi client.~%"
+                      key)))))
+
+(define (graphql-endpoint)
+  "Return GraphQL endpoint."
+  (uri->string
+   (build-uri (client-config 'mumi-scheme)
+              #:host (client-config 'mumi-host)
+              #:path "/graphql")))
+
+(define (iso8601->date str)
+  "Convert ISO-8601 date/time+zone string to date object."
+  (string->date str "~Y-~m-~dT~H:~M:~S~z"))
+
+(define (list-issue issue)
+  "List issue described by ISSUE association list."
+  (display (colorize-string
+            (string-append "#"
+                           (number->string (assoc-ref issue "number")))
+            'YELLOW))
+  (display " ")
+  (unless (assoc-ref issue "open")
+    (display (colorize-string "✓" 'BOLD 'GREEN))
+    (display " "))
+  (display (colorize-string
+            (assoc-ref issue "title")
+            'MAGENTA 'UNDERLINE))
+  (newline)
+  (display (string-append
+            "opened "
+            (colorize-string (time->string
+                              (iso8601->date (assoc-ref issue "date")))
+                             'CYAN)
+            " by "
+            (colorize-string
+             (let ((submitter (assoc-ref issue "submitter")))
+               (if (eq? (assoc-ref submitter "name") 'null)
+                   (assoc-ref submitter "address")
+                   (assoc-ref submitter "name")))
+             'CYAN)))
+  (newline))
+
+(define (search query)
+  "Search for issues with QUERY and list results."
+  (vector-for-each (lambda (_ issue)
+                     (list-issue issue))
+                   (assoc-ref
+                    (graphql-http-get (graphql-endpoint)
+                                      `(document
+                                        (query (#(issues #:search ,query)
+                                                number
+                                                title
+                                                open
+                                                date
+                                                (submitter name address)))))
+                    "issues")))
diff --git a/scripts/mumi.in b/scripts/mumi.in
index 755dfb3..9b61729 100644
--- a/scripts/mumi.in
+++ b/scripts/mumi.in
@@ -4,7 +4,7 @@
 !#
 ;;; mumi -- Mediocre, uh, mail interface
 ;;; Copyright © 2016, 2017, 2019, 2020 Ricardo Wurmus <rekado@elephly.net>
-;;; Copyright © 2018, 2021 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2018, 2021, 2023 Arun Isaac <arunisaac@systemreboot.net>
 ;;;
 ;;; This file is part of mumi.
 ;;;
@@ -26,6 +26,7 @@
              (system repl server)
              (ice-9 match)
              (ice-9 format)
+             ((mumi client) #:prefix client:)
              (mumi config)
              ((mumi debbugs)
               #:select (extract-bug-numbers))
@@ -116,6 +117,9 @@
 (define (show-mumi-usage)
   (format (current-error-port)
           "
+    `mumi search QUERY':
+         search mumi for issues.
+
     `mumi web [--address=address] [--port=port] [--listen-repl[=port]] [--disable-mailer]':
          start the application web server.
 
@@ -132,6 +136,8 @@
   (exit 1))
 
 (match (cdr (program-arguments))
+  (("search" . query-strings)
+   (client:search (string-join query-strings)))
   (("mailer" . rest)
    (let* ((opts (parse-options rest))
           (sender (assoc-ref opts 'sender))
-- 
2.38.1





^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH v2 2/4] client: Support checking in to a specific issue.
  2023-02-20  1:38 [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Arun Isaac
                   ` (2 preceding siblings ...)
  2023-02-21  0:33 ` [bug#61645] [PATCH v2 1/4] client: Add CLI client to search for issues Arun Isaac
@ 2023-02-21  0:33 ` Arun Isaac
  2023-02-21  0:33 ` [bug#61645] [PATCH v2 3/4] client: Support sending email to issues Arun Isaac
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 25+ messages in thread
From: Arun Isaac @ 2023-02-21  0:33 UTC (permalink / raw)
  To: 61645; +Cc: Ricardo Wurmus, Arun Isaac

* mumi/client.scm: Import (srfi srfi-26).
(current-issue-file, current-issue-number): New functions.
(print-current-issue, set-current-issue!, clear-current-issue!): New
public functions.
* scripts/mumi.in (show-mumi-usage): Document current and new
subcommands.
(main): Add current and new subcommands.
---
 mumi/client.scm | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
 scripts/mumi.in | 20 ++++++++++++++++++++
 2 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/mumi/client.scm b/mumi/client.scm
index e4a0123..ae3a0a9 100644
--- a/mumi/client.scm
+++ b/mumi/client.scm
@@ -18,13 +18,17 @@
 
 (define-module (mumi client)
   #:use-module (srfi srfi-19)
+  #:use-module (srfi srfi-26)
   #:use-module (srfi srfi-43)
   #:use-module (term ansi-color)
   #:use-module (web uri)
   #:use-module (kolam http)
   #:use-module (mumi config)
   #:use-module (mumi web view utils)
-  #:export (search))
+  #:export (search
+            print-current-issue
+            set-current-issue!
+            clear-current-issue!))
 
 (define (git-top-level)
   "Return the top-level directory of the current git repository."
@@ -106,3 +110,45 @@
                                                 date
                                                 (submitter name address)))))
                     "issues")))
+
+(define (current-issue-file)
+  "Return path to current issue number file."
+  (string-append (client-config-directory) "/current-issue"))
+
+(define (current-issue-number)
+  "Return current issue number."
+  (let ((issue-file (current-issue-file)))
+    (and (file-exists? issue-file)
+         (call-with-input-file issue-file
+           read))))
+
+(define (print-current-issue)
+  "Print current issue."
+  (let ((issue-number (current-issue-number)))
+    (if issue-number
+        (list-issue
+         (assoc-ref
+          (graphql-http-get (graphql-endpoint)
+                            `(document
+                              (query (#(issue #:number ,issue-number)
+                                      number
+                                      title
+                                      open
+                                      date
+                                      (submitter name address)))))
+          "issue"))
+        (begin
+          (format (current-error-port) "No current issue!~%")
+          (exit #f)))))
+
+(define (set-current-issue! issue-number)
+  "Set current issue number."
+  ;; TODO: Write file atomically.
+  (call-with-output-file (current-issue-file)
+    (cut write issue-number <>)))
+
+(define (clear-current-issue!)
+  "Clear current issue."
+  (let ((issue-file (current-issue-file)))
+    (when (file-exists? issue-file)
+      (delete-file issue-file))))
diff --git a/scripts/mumi.in b/scripts/mumi.in
index 9b61729..dfd082d 100644
--- a/scripts/mumi.in
+++ b/scripts/mumi.in
@@ -120,6 +120,12 @@
     `mumi search QUERY':
          search mumi for issues.
 
+    `mumi current [ISSUE-NUMBER]':
+         print or set current issue.
+
+    `mumi new':
+         clear current issue presumably to open a new one.
+
     `mumi web [--address=address] [--port=port] [--listen-repl[=port]] [--disable-mailer]':
          start the application web server.
 
@@ -138,6 +144,20 @@
 (match (cdr (program-arguments))
   (("search" . query-strings)
    (client:search (string-join query-strings)))
+  (("current")
+   (client:print-current-issue))
+  (("current" issue-number-string)
+   (let ((issue-number (string->number issue-number-string)))
+     (if issue-number
+         (client:set-current-issue! issue-number)
+         (begin
+           (format (current-error-port)
+                   "Invalid issue number `~a'~%"
+                   issue-number-string)
+           (exit #f))))
+   (client:print-current-issue))
+  (("new")
+   (client:clear-current-issue!))
   (("mailer" . rest)
    (let* ((opts (parse-options rest))
           (sender (assoc-ref opts 'sender))
-- 
2.38.1





^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH v2 3/4] client: Support sending email to issues.
  2023-02-20  1:38 [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Arun Isaac
                   ` (3 preceding siblings ...)
  2023-02-21  0:33 ` [bug#61645] [PATCH v2 2/4] client: Support checking in to a specific issue Arun Isaac
@ 2023-02-21  0:33 ` Arun Isaac
  2023-02-21  0:33 ` [bug#61645] [PATCH v2 4/4] Set only GUILE_LOAD_PATH when running tests Arun Isaac
  2023-03-08 12:05 ` [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Ludovic Courtès
  6 siblings, 0 replies; 25+ messages in thread
From: Arun Isaac @ 2023-02-21  0:33 UTC (permalink / raw)
  To: 61645; +Cc: Ricardo Wurmus, Arun Isaac

* mumi/client.scm: Import (rnrs io ports), (srfi srfi-71), (srfi
srfi-171), (ice-9 match), (ice-9 popen), (web client), (web response)
and (email email).
(issue-number-of-message, call-with-input-pipe, git-send-email): New
functions.
(send-email): New public function.
* scripts/mumi.in (show-mumi-usage): Document send-email subcommand.
(main): Add send-email subcommand.
* tests/client.scm: New file.
* Makefile.am (SCM_TESTS): Add tests/client.scm.
---
 Makefile.am      |   1 +
 mumi/client.scm  | 105 ++++++++++++++++++++++++++++++++++++++++++++++-
 scripts/mumi.in  |   5 +++
 tests/client.scm |  93 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 203 insertions(+), 1 deletion(-)
 create mode 100644 tests/client.scm

diff --git a/Makefile.am b/Makefile.am
index a8c11a1..86ba4f0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -58,6 +58,7 @@ SOURCES =							\
 TEST_EXTENSIONS = .scm
 
 SCM_TESTS = \
+  tests/client.scm  \
   tests/debbugs.scm \
   tests/xapian.scm
 
diff --git a/mumi/client.scm b/mumi/client.scm
index ae3a0a9..09f83ee 100644
--- a/mumi/client.scm
+++ b/mumi/client.scm
@@ -17,18 +17,27 @@
 ;;; along with mumi.  If not, see <http://www.gnu.org/licenses/>.
 
 (define-module (mumi client)
+  #:use-module (rnrs io ports)
   #:use-module (srfi srfi-19)
   #:use-module (srfi srfi-26)
   #:use-module (srfi srfi-43)
+  #:use-module (srfi srfi-71)
+  #:use-module (srfi srfi-171)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 popen)
   #:use-module (term ansi-color)
+  #:use-module (web client)
+  #:use-module (web response)
   #:use-module (web uri)
+  #:use-module (email email)
   #:use-module (kolam http)
   #:use-module (mumi config)
   #:use-module (mumi web view utils)
   #:export (search
             print-current-issue
             set-current-issue!
-            clear-current-issue!))
+            clear-current-issue!
+            send-email))
 
 (define (git-top-level)
   "Return the top-level directory of the current git repository."
@@ -152,3 +161,97 @@
   (let ((issue-file (current-issue-file)))
     (when (file-exists? issue-file)
       (delete-file issue-file))))
+
+(define* (issue-number-of-message message-id #:optional (retries 15))
+  "Return issue number that MESSAGE-ID belongs to. Retry RETRIES number
+of times with an interval of 60 seconds between retries."
+  ;; TODO: Re-implement this using our GraphQL endpoint once it
+  ;; supports retrieving the issue from a message ID. Later,
+  ;; re-implement this using a GraphQL subscription when kolam
+  ;; supports it.
+  (define (poll-issue-number-of-message message-id)
+    (let ((response _ (http-get (build-uri (client-config 'mumi-scheme)
+                                           #:host (client-config 'mumi-host)
+                                           #:path (string-append "/msgid/" message-id)))))
+      (and (>= (response-code response) 300)
+           (< (response-code response) 400)
+           (match (split-and-decode-uri-path
+                   (uri-path (response-location response)))
+             (("issue" issue-number)
+              (string->number issue-number))))))
+
+  (let loop ((i retries))
+    (if (zero? i)
+        (begin
+          (format (current-error-port)
+                  "Mail not acknowledged by issue tracker. Giving up.~%")
+          (exit #f))
+        (or (poll-issue-number-of-message message-id)
+            (begin
+              (let ((retry-interval 60))
+                (format (current-error-port)
+                        "Trial ~a/~a: Server has not yet received our email. Will retry in ~a seconds.~%"
+                        (1+ i) retries retry-interval)
+                (sleep retry-interval))
+              (loop (1- retries)))))))
+
+(define (call-with-input-pipe command proc)
+  "Call PROC with input pipe to COMMAND. COMMAND is a list of program
+arguments."
+  (match command
+    ((prog args ...)
+     (let ((port #f))
+       (dynamic-wind
+         (lambda ()
+           (set! port (apply open-pipe* OPEN_READ prog args)))
+         (cut proc port)
+         (cut close-pipe port))))))
+
+(define (git-send-email to patch)
+  "Send email using git send-email and return the message ID of the sent
+email."
+  (let ((command (list "git" "send-email"
+                       (string-append "--to=" to)
+                       patch)))
+    (display (string-join command))
+    (newline)
+    (call-with-input-pipe command
+      (lambda (port)
+        ;; FIXME: This messes up the order of stdout and stderr.
+        (let ((message-id
+               ;; Read till you get the Message ID.
+               (port-transduce (tlog (lambda (_ line)
+                                       (display line)
+                                       (newline)))
+                               (rany (lambda (line)
+                                       (and (string-prefix-ci? "Message-ID:" line)
+                                            (assq-ref
+                                             (parse-email-headers
+                                              (string-append line "\n"))
+                                             'message-id))))
+                               get-line
+                               port)))
+          ;; Pass through the rest.
+          (display (get-string-all port))
+          message-id)))))
+
+(define (send-email patches)
+  "Send PATCHES via email."
+  (match patches
+    ((first-patch other-patches ...)
+     ;; If an issue is current, send patches to that issue's email
+     ;; address. Else, send first patch to the patch email address and
+     ;; get an issue number. Then, send the remaining patches to that
+     ;; issue's email address.
+     (for-each (cute git-send-email
+                     (string-append (number->string
+                                     (or (current-issue-number)
+                                         (issue-number-of-message
+                                          (git-send-email (client-config 'patch-email-address)
+                                                          first-patch))))
+                                    "@"
+                                    (client-config 'debbugs-host))
+                     <>)
+               (if (current-issue-number)
+                   patches
+                   other-patches)))))
diff --git a/scripts/mumi.in b/scripts/mumi.in
index dfd082d..2295328 100644
--- a/scripts/mumi.in
+++ b/scripts/mumi.in
@@ -126,6 +126,9 @@
     `mumi new':
          clear current issue presumably to open a new one.
 
+    `mumi send-email':
+         send patches to debbugs.
+
     `mumi web [--address=address] [--port=port] [--listen-repl[=port]] [--disable-mailer]':
          start the application web server.
 
@@ -158,6 +161,8 @@
    (client:print-current-issue))
   (("new")
    (client:clear-current-issue!))
+  (("send-email" . patches)
+   (client:send-email patches))
   (("mailer" . rest)
    (let* ((opts (parse-options rest))
           (sender (assoc-ref opts 'sender))
diff --git a/tests/client.scm b/tests/client.scm
new file mode 100644
index 0000000..2948aed
--- /dev/null
+++ b/tests/client.scm
@@ -0,0 +1,93 @@
+;;; mumi -- Mediocre, uh, mail interface
+;;; Copyright © 2023 Arun Isaac <arunisaac@systemreboot.net>
+;;;
+;;; This program is free software: you can redistribute it and/or
+;;; modify it under the terms of the GNU Affero 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
+;;; Affero General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU Affero General Public
+;;; License along with this program.  If not, see
+;;; <http://www.gnu.org/licenses/>.
+
+(use-modules (srfi srfi-26)
+             (srfi srfi-64)
+             (ice-9 match))
+
+(define (with-variable variable value thunk)
+  "Set VARIABLE to VALUE, run THUNK and restore the old value of
+VARIABLE. Return the value returned by THUNK."
+  (let ((old-value (variable-ref variable)))
+    (dynamic-wind
+      (cut variable-set! variable value)
+      thunk
+      (cut variable-set! variable old-value))))
+
+(define (with-variables variable-bindings thunk)
+  "Set VARIABLE-BINDINGS, run THUNK and restore the old values of the
+variables. Return the value returned by THUNK. VARIABLE-BINDINGS is a
+list of pairs mapping variables to their values."
+  (match variable-bindings
+    (((variable . value) tail ...)
+     (with-variable variable value
+       (cut with-variables tail thunk)))
+    (() (thunk))))
+
+(define-syntax-rule (var@@ module-name variable-name)
+  (module-variable (resolve-module 'module-name)
+                   'variable-name))
+
+(define (trace-calls function-variable thunk)
+  "Run THUNK and return a list of argument lists FUNCTION-VARIABLE is
+called with."
+  (let ((args-list (list)))
+    (with-variable function-variable (lambda args
+                                       (set! args-list
+                                             (cons args args-list)))
+      thunk)
+    (reverse args-list)))
+
+(define client-config-stub
+  (cons (var@@ (mumi client) client-config)
+        (lambda (key)
+          (case key
+            ((debbugs-host) "example.com")
+            ((patch-email-address) "foo@patches.com")
+            (else (error "Key unimplemented in stub" key))))))
+
+(test-begin "client")
+
+(test-equal "send patches to new issue"
+  '(("git" "send-email" "--to=foo@patches.com" "foo.patch")
+    ("git" "send-email" "--to=12345@example.com" "bar.patch")
+    ("git" "send-email" "--to=12345@example.com" "foobar.patch"))
+  (map (match-lambda
+         ((command _) command))
+       (trace-calls (var@@ (mumi client) call-with-input-pipe)
+         (lambda ()
+           (with-variables (list (cons (var@@ (mumi client) issue-number-of-message)
+                                       (const 12345))
+                                 client-config-stub)
+             (cut (@@ (mumi client) send-email)
+                  (list "foo.patch" "bar.patch" "foobar.patch")))))))
+
+(test-equal "send patches to existing issue"
+  '(("git" "send-email" "--to=12345@example.com" "foo.patch")
+    ("git" "send-email" "--to=12345@example.com" "bar.patch")
+    ("git" "send-email" "--to=12345@example.com" "foobar.patch"))
+  (map (match-lambda
+         ((command _) command))
+       (trace-calls (var@@ (mumi client) call-with-input-pipe)
+         (lambda ()
+           (with-variables (list (cons (var@@ (mumi client) current-issue-number)
+                                       (const 12345))
+                                 client-config-stub)
+             (cut (@@ (mumi client) send-email)
+                  (list "foo.patch" "bar.patch" "foobar.patch")))))))
+
+(test-end "client")
-- 
2.38.1





^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH v2 4/4] Set only GUILE_LOAD_PATH when running tests.
  2023-02-20  1:38 [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Arun Isaac
                   ` (4 preceding siblings ...)
  2023-02-21  0:33 ` [bug#61645] [PATCH v2 3/4] client: Support sending email to issues Arun Isaac
@ 2023-02-21  0:33 ` Arun Isaac
  2023-03-08 12:05 ` [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Ludovic Courtès
  6 siblings, 0 replies; 25+ messages in thread
From: Arun Isaac @ 2023-02-21  0:33 UTC (permalink / raw)
  To: 61645; +Cc: Ricardo Wurmus, Arun Isaac

Somehow, the stubs in tests/client.scm do not work when compiled
modules are found. This could be a guile bug.

* Makefile.am (SCM_LOG_DRIVER): Do not use pre-inst-env. Set only the
load path.
---
 Makefile.am | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 86ba4f0..3e57e63 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -70,8 +70,7 @@ EXTRA_DIST += $(TESTS) \
 AM_TESTS_ENVIRONMENT = abs_top_srcdir="$(abs_top_srcdir)" GUILE_AUTO_COMPILE=0
 
 SCM_LOG_DRIVER =                                          \
-  $(top_builddir)/pre-inst-env                            \
-  $(GUILE) --no-auto-compile -e main                      \
+  $(GUILE) --no-auto-compile -L $(top_srcdir) -e main     \
       $(top_srcdir)/build-aux/test-driver.scm
 
 AM_SCM_LOG_DRIVER_FLAGS = --brief=yes
-- 
2.38.1





^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues
  2023-02-20  1:38 [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Arun Isaac
                   ` (5 preceding siblings ...)
  2023-02-21  0:33 ` [bug#61645] [PATCH v2 4/4] Set only GUILE_LOAD_PATH when running tests Arun Isaac
@ 2023-03-08 12:05 ` Ludovic Courtès
  2023-03-08 13:28   ` Arun Isaac
  6 siblings, 1 reply; 25+ messages in thread
From: Ludovic Courtès @ 2023-03-08 12:05 UTC (permalink / raw)
  To: Arun Isaac; +Cc: Ricardo Wurmus, 61645

Hi Arun,

Arun Isaac <arunisaac@systemreboot.net> skribis:

> This patch adds a mumi CLI client that lets one search for issues from
> the command line by calling mumi's GraphQL API. This patch requires a
> .mumi/config file in the guix repo with the following contents.
>
> ((debbugs-host . "debbugs.gnu.org")
>  (patch-email-address . "guix-patches@gnu.org")
>  (mumi-host . "issues.guix.gnu.org"))
>
> After adding .mumi/config, you can run search queries like
>
> $ /path/to/mumi/pre-inst-env mumi search zig is:open

Yay, this is great!!

> This is only the beginning. I have WIP patches that will add a "mumi
> send-email" subcommand that will finally free us from our debbugs
> dance when sending multiple patches. I will send them separately once
> I have tested it more.

Woow, sounds really nice.  I’m all for it!

Thanks,
Ludo’.




^ permalink raw reply	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues
  2023-03-08 12:05 ` [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Ludovic Courtès
@ 2023-03-08 13:28   ` Arun Isaac
  2023-03-08 15:36     ` [bug#61645] [mumi v3 0/4] Add mumi CLI client Arun Isaac
                       ` (5 more replies)
  0 siblings, 6 replies; 25+ messages in thread
From: Arun Isaac @ 2023-03-08 13:28 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: Ricardo Wurmus, 61645


>> This is only the beginning. I have WIP patches that will add a "mumi
>> send-email" subcommand that will finally free us from our debbugs
>> dance when sending multiple patches. I will send them separately once
>> I have tested it more.

I've already sent these patches as a v2 to this same issue. Waiting for
Ricardo to merge it now.

> Woow, sounds really nice.  I’m all for it!

Yep, it's going to be awesome! :-)




^ permalink raw reply	[flat|nested] 25+ messages in thread

* [bug#61645] [mumi v3 0/4] Add mumi CLI client
  2023-03-08 13:28   ` Arun Isaac
@ 2023-03-08 15:36     ` Arun Isaac
  2023-03-08 15:36     ` [bug#61645] [mumi v3 1/4] client: Add CLI client to search for issues Arun Isaac
                       ` (4 subsequent siblings)
  5 siblings, 0 replies; 25+ messages in thread
From: Arun Isaac @ 2023-03-08 15:36 UTC (permalink / raw)
  To: 61645, Ludovic Courtès; +Cc: Ricardo Wurmus, Arun Isaac

Here is a v3 of the patchset.

This patchset reduces the number of `git send-email' invocations to a
maximum of 2 even when there are n patches. The first patch is sent
using a `git send-email' invocation and the remaining n-1 patches are
sent using another `git send-email' invocation.

With this patchset, when sending a single patch, the mumi server is
not polled for the issue number since that's not necessary.

I also fixed a bug to do with printing the number of retries left.

Arun Isaac (4):
  client: Add CLI client to search for issues.
  client: Support checking in to a specific issue.
  client: Support sending email to issues.
  Set only GUILE_LOAD_PATH when running tests.

 Makefile.am      |   5 +-
 mumi/client.scm  | 264 +++++++++++++++++++++++++++++++++++++++++++++++
 scripts/mumi.in  |  33 +++++-
 tests/client.scm | 118 +++++++++++++++++++++
 4 files changed, 417 insertions(+), 3 deletions(-)
 create mode 100644 mumi/client.scm
 create mode 100644 tests/client.scm

-- 
2.39.1





^ permalink raw reply	[flat|nested] 25+ messages in thread

* [bug#61645] [mumi v3 1/4] client: Add CLI client to search for issues.
  2023-03-08 13:28   ` Arun Isaac
  2023-03-08 15:36     ` [bug#61645] [mumi v3 0/4] Add mumi CLI client Arun Isaac
@ 2023-03-08 15:36     ` Arun Isaac
  2023-03-08 15:36     ` [bug#61645] [mumi v3 2/4] client: Support checking in to a specific issue Arun Isaac
                       ` (3 subsequent siblings)
  5 siblings, 0 replies; 25+ messages in thread
From: Arun Isaac @ 2023-03-08 15:36 UTC (permalink / raw)
  To: 61645, Ludovic Courtès; +Cc: Ricardo Wurmus, Arun Isaac

* mumi/client.scm: New file.
* scripts/mumi.in: Import (mumi client).
(show-mumi-usage): Document search subcommand.
(main): Add search subcommand.
* Makefile.am (SOURCES): Add mumi/client.scm.
---
 Makefile.am     |   1 +
 mumi/client.scm | 108 ++++++++++++++++++++++++++++++++++++++++++++++++
 scripts/mumi.in |   8 +++-
 3 files changed, 116 insertions(+), 1 deletion(-)
 create mode 100644 mumi/client.scm

diff --git a/Makefile.am b/Makefile.am
index 8182fc3..a8c11a1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,6 +49,7 @@ SOURCES =							\
   mumi/messages.scm					\
   mumi/jobs.scm						\
   mumi/send-email.scm				\
+  mumi/client.scm				\
   mumi/config.scm					\
   mumi/debbugs.scm					\
   mumi/test-utils.scm				\
diff --git a/mumi/client.scm b/mumi/client.scm
new file mode 100644
index 0000000..e4a0123
--- /dev/null
+++ b/mumi/client.scm
@@ -0,0 +1,108 @@
+;;; mumi -- Mediocre, uh, mail interface
+;;; Copyright © 2023 Arun Isaac <arunisaac@systemreboot.net>
+;;;
+;;; This file is part of mumi.
+;;;
+;;; mumi 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.
+;;;
+;;; mumi 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 mumi.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (mumi client)
+  #:use-module (srfi srfi-19)
+  #:use-module (srfi srfi-43)
+  #:use-module (term ansi-color)
+  #:use-module (web uri)
+  #:use-module (kolam http)
+  #:use-module (mumi config)
+  #:use-module (mumi web view utils)
+  #:export (search))
+
+(define (git-top-level)
+  "Return the top-level directory of the current git repository."
+  (let loop ((curdir (getcwd)))
+    (cond
+     ((file-exists? (string-append curdir "/.git"))
+      curdir)
+     ((string=? curdir "/")
+      (error "No git top level found"))
+     (else
+      (loop (dirname curdir))))))
+
+(define (client-config-directory)
+  "Return client configuration directory."
+  (string-append (git-top-level) "/.mumi"))
+
+(define (client-config key)
+  "Return client configuration value corresponding to KEY."
+  (or (assq-ref (call-with-input-file (string-append (client-config-directory)
+                                                     "/config")
+                  read)
+                key)
+      (case key
+        ((mumi-scheme) 'https)
+        (else (format (current-error-port)
+                      "Key '~a not configured for mumi client.~%"
+                      key)))))
+
+(define (graphql-endpoint)
+  "Return GraphQL endpoint."
+  (uri->string
+   (build-uri (client-config 'mumi-scheme)
+              #:host (client-config 'mumi-host)
+              #:path "/graphql")))
+
+(define (iso8601->date str)
+  "Convert ISO-8601 date/time+zone string to date object."
+  (string->date str "~Y-~m-~dT~H:~M:~S~z"))
+
+(define (list-issue issue)
+  "List issue described by ISSUE association list."
+  (display (colorize-string
+            (string-append "#"
+                           (number->string (assoc-ref issue "number")))
+            'YELLOW))
+  (display " ")
+  (unless (assoc-ref issue "open")
+    (display (colorize-string "✓" 'BOLD 'GREEN))
+    (display " "))
+  (display (colorize-string
+            (assoc-ref issue "title")
+            'MAGENTA 'UNDERLINE))
+  (newline)
+  (display (string-append
+            "opened "
+            (colorize-string (time->string
+                              (iso8601->date (assoc-ref issue "date")))
+                             'CYAN)
+            " by "
+            (colorize-string
+             (let ((submitter (assoc-ref issue "submitter")))
+               (if (eq? (assoc-ref submitter "name") 'null)
+                   (assoc-ref submitter "address")
+                   (assoc-ref submitter "name")))
+             'CYAN)))
+  (newline))
+
+(define (search query)
+  "Search for issues with QUERY and list results."
+  (vector-for-each (lambda (_ issue)
+                     (list-issue issue))
+                   (assoc-ref
+                    (graphql-http-get (graphql-endpoint)
+                                      `(document
+                                        (query (#(issues #:search ,query)
+                                                number
+                                                title
+                                                open
+                                                date
+                                                (submitter name address)))))
+                    "issues")))
diff --git a/scripts/mumi.in b/scripts/mumi.in
index 755dfb3..9b61729 100644
--- a/scripts/mumi.in
+++ b/scripts/mumi.in
@@ -4,7 +4,7 @@
 !#
 ;;; mumi -- Mediocre, uh, mail interface
 ;;; Copyright © 2016, 2017, 2019, 2020 Ricardo Wurmus <rekado@elephly.net>
-;;; Copyright © 2018, 2021 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2018, 2021, 2023 Arun Isaac <arunisaac@systemreboot.net>
 ;;;
 ;;; This file is part of mumi.
 ;;;
@@ -26,6 +26,7 @@
              (system repl server)
              (ice-9 match)
              (ice-9 format)
+             ((mumi client) #:prefix client:)
              (mumi config)
              ((mumi debbugs)
               #:select (extract-bug-numbers))
@@ -116,6 +117,9 @@
 (define (show-mumi-usage)
   (format (current-error-port)
           "
+    `mumi search QUERY':
+         search mumi for issues.
+
     `mumi web [--address=address] [--port=port] [--listen-repl[=port]] [--disable-mailer]':
          start the application web server.
 
@@ -132,6 +136,8 @@
   (exit 1))
 
 (match (cdr (program-arguments))
+  (("search" . query-strings)
+   (client:search (string-join query-strings)))
   (("mailer" . rest)
    (let* ((opts (parse-options rest))
           (sender (assoc-ref opts 'sender))
-- 
2.39.1





^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [bug#61645] [mumi v3 2/4] client: Support checking in to a specific issue.
  2023-03-08 13:28   ` Arun Isaac
  2023-03-08 15:36     ` [bug#61645] [mumi v3 0/4] Add mumi CLI client Arun Isaac
  2023-03-08 15:36     ` [bug#61645] [mumi v3 1/4] client: Add CLI client to search for issues Arun Isaac
@ 2023-03-08 15:36     ` Arun Isaac
  2023-03-08 15:36     ` [bug#61645] [mumi v3 3/4] client: Support sending email to issues Arun Isaac
                       ` (2 subsequent siblings)
  5 siblings, 0 replies; 25+ messages in thread
From: Arun Isaac @ 2023-03-08 15:36 UTC (permalink / raw)
  To: 61645, Ludovic Courtès; +Cc: Ricardo Wurmus, Arun Isaac

* mumi/client.scm: Import (srfi srfi-26).
(current-issue-file, current-issue-number): New functions.
(print-current-issue, set-current-issue!, clear-current-issue!): New
public functions.
* scripts/mumi.in (show-mumi-usage): Document current and new
subcommands.
(main): Add current and new subcommands.
---
 mumi/client.scm | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
 scripts/mumi.in | 20 ++++++++++++++++++++
 2 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/mumi/client.scm b/mumi/client.scm
index e4a0123..ae3a0a9 100644
--- a/mumi/client.scm
+++ b/mumi/client.scm
@@ -18,13 +18,17 @@
 
 (define-module (mumi client)
   #:use-module (srfi srfi-19)
+  #:use-module (srfi srfi-26)
   #:use-module (srfi srfi-43)
   #:use-module (term ansi-color)
   #:use-module (web uri)
   #:use-module (kolam http)
   #:use-module (mumi config)
   #:use-module (mumi web view utils)
-  #:export (search))
+  #:export (search
+            print-current-issue
+            set-current-issue!
+            clear-current-issue!))
 
 (define (git-top-level)
   "Return the top-level directory of the current git repository."
@@ -106,3 +110,45 @@
                                                 date
                                                 (submitter name address)))))
                     "issues")))
+
+(define (current-issue-file)
+  "Return path to current issue number file."
+  (string-append (client-config-directory) "/current-issue"))
+
+(define (current-issue-number)
+  "Return current issue number."
+  (let ((issue-file (current-issue-file)))
+    (and (file-exists? issue-file)
+         (call-with-input-file issue-file
+           read))))
+
+(define (print-current-issue)
+  "Print current issue."
+  (let ((issue-number (current-issue-number)))
+    (if issue-number
+        (list-issue
+         (assoc-ref
+          (graphql-http-get (graphql-endpoint)
+                            `(document
+                              (query (#(issue #:number ,issue-number)
+                                      number
+                                      title
+                                      open
+                                      date
+                                      (submitter name address)))))
+          "issue"))
+        (begin
+          (format (current-error-port) "No current issue!~%")
+          (exit #f)))))
+
+(define (set-current-issue! issue-number)
+  "Set current issue number."
+  ;; TODO: Write file atomically.
+  (call-with-output-file (current-issue-file)
+    (cut write issue-number <>)))
+
+(define (clear-current-issue!)
+  "Clear current issue."
+  (let ((issue-file (current-issue-file)))
+    (when (file-exists? issue-file)
+      (delete-file issue-file))))
diff --git a/scripts/mumi.in b/scripts/mumi.in
index 9b61729..dfd082d 100644
--- a/scripts/mumi.in
+++ b/scripts/mumi.in
@@ -120,6 +120,12 @@
     `mumi search QUERY':
          search mumi for issues.
 
+    `mumi current [ISSUE-NUMBER]':
+         print or set current issue.
+
+    `mumi new':
+         clear current issue presumably to open a new one.
+
     `mumi web [--address=address] [--port=port] [--listen-repl[=port]] [--disable-mailer]':
          start the application web server.
 
@@ -138,6 +144,20 @@
 (match (cdr (program-arguments))
   (("search" . query-strings)
    (client:search (string-join query-strings)))
+  (("current")
+   (client:print-current-issue))
+  (("current" issue-number-string)
+   (let ((issue-number (string->number issue-number-string)))
+     (if issue-number
+         (client:set-current-issue! issue-number)
+         (begin
+           (format (current-error-port)
+                   "Invalid issue number `~a'~%"
+                   issue-number-string)
+           (exit #f))))
+   (client:print-current-issue))
+  (("new")
+   (client:clear-current-issue!))
   (("mailer" . rest)
    (let* ((opts (parse-options rest))
           (sender (assoc-ref opts 'sender))
-- 
2.39.1





^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [bug#61645] [mumi v3 3/4] client: Support sending email to issues.
  2023-03-08 13:28   ` Arun Isaac
                       ` (2 preceding siblings ...)
  2023-03-08 15:36     ` [bug#61645] [mumi v3 2/4] client: Support checking in to a specific issue Arun Isaac
@ 2023-03-08 15:36     ` Arun Isaac
  2023-03-08 15:36     ` [bug#61645] [mumi v3 4/4] Set only GUILE_LOAD_PATH when running tests Arun Isaac
  2023-03-30 20:47     ` [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Ludovic Courtès
  5 siblings, 0 replies; 25+ messages in thread
From: Arun Isaac @ 2023-03-08 15:36 UTC (permalink / raw)
  To: 61645, Ludovic Courtès; +Cc: Ricardo Wurmus, Arun Isaac

* mumi/client.scm: Import (rnrs io ports), (srfi srfi-71), (srfi
srfi-171), (ice-9 match), (ice-9 popen), (web client), (web response)
and (email email).
(issue-number-of-message, call-with-input-pipe, git-send-email): New
functions.
(send-email): New public function.
* scripts/mumi.in (show-mumi-usage): Document send-email subcommand.
(main): Add send-email subcommand.
* tests/client.scm: New file.
* Makefile.am (SCM_TESTS): Add tests/client.scm.
---
 Makefile.am      |   1 +
 mumi/client.scm  | 112 +++++++++++++++++++++++++++++++++++++++++++-
 scripts/mumi.in  |   5 ++
 tests/client.scm | 118 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 235 insertions(+), 1 deletion(-)
 create mode 100644 tests/client.scm

diff --git a/Makefile.am b/Makefile.am
index a8c11a1..86ba4f0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -58,6 +58,7 @@ SOURCES =							\
 TEST_EXTENSIONS = .scm
 
 SCM_TESTS = \
+  tests/client.scm  \
   tests/debbugs.scm \
   tests/xapian.scm
 
diff --git a/mumi/client.scm b/mumi/client.scm
index ae3a0a9..b8d588b 100644
--- a/mumi/client.scm
+++ b/mumi/client.scm
@@ -17,18 +17,27 @@
 ;;; along with mumi.  If not, see <http://www.gnu.org/licenses/>.
 
 (define-module (mumi client)
+  #:use-module (rnrs io ports)
   #:use-module (srfi srfi-19)
   #:use-module (srfi srfi-26)
   #:use-module (srfi srfi-43)
+  #:use-module (srfi srfi-71)
+  #:use-module (srfi srfi-171)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 popen)
   #:use-module (term ansi-color)
+  #:use-module (web client)
+  #:use-module (web response)
   #:use-module (web uri)
+  #:use-module (email email)
   #:use-module (kolam http)
   #:use-module (mumi config)
   #:use-module (mumi web view utils)
   #:export (search
             print-current-issue
             set-current-issue!
-            clear-current-issue!))
+            clear-current-issue!
+            send-email))
 
 (define (git-top-level)
   "Return the top-level directory of the current git repository."
@@ -152,3 +161,104 @@
   (let ((issue-file (current-issue-file)))
     (when (file-exists? issue-file)
       (delete-file issue-file))))
+
+(define* (issue-number-of-message message-id #:optional (retries 15))
+  "Return issue number that MESSAGE-ID belongs to. Retry RETRIES number
+of times with an interval of 60 seconds between retries."
+  ;; TODO: Re-implement this using our GraphQL endpoint once it
+  ;; supports retrieving the issue from a message ID. Later,
+  ;; re-implement this using a GraphQL subscription when kolam
+  ;; supports it.
+  (define (poll-issue-number-of-message message-id)
+    (let ((response _ (http-get (build-uri (client-config 'mumi-scheme)
+                                           #:host (client-config 'mumi-host)
+                                           #:path (string-append "/msgid/" message-id)))))
+      (and (>= (response-code response) 300)
+           (< (response-code response) 400)
+           (match (split-and-decode-uri-path
+                   (uri-path (response-location response)))
+             (("issue" issue-number)
+              (string->number issue-number))))))
+
+  (let loop ((i retries))
+    (if (zero? i)
+        (begin
+          (format (current-error-port)
+                  "Mail not acknowledged by issue tracker. Giving up.~%")
+          (exit #f))
+        (or (poll-issue-number-of-message message-id)
+            (begin
+              (let ((retry-interval 60))
+                (format (current-error-port)
+                        "Server has not yet received our email. Will retry in ~a seconds. ~a retries remaining.~%"
+                        retry-interval (1- i))
+                (sleep retry-interval))
+              (loop (1- i)))))))
+
+(define (call-with-input-pipe command proc)
+  "Call PROC with input pipe to COMMAND. COMMAND is a list of program
+arguments."
+  (match command
+    ((prog args ...)
+     (let ((port #f))
+       (dynamic-wind
+         (lambda ()
+           (set! port (apply open-pipe* OPEN_READ prog args)))
+         (cut proc port)
+         (cut close-pipe port))))))
+
+(define (git-send-email to patches)
+  "Send PATCHES using git send-email to the TO address and return the
+message ID of the first email sent."
+  (let ((command (cons* "git" "send-email"
+                        (string-append "--to=" to)
+                        patches)))
+    (display (string-join command))
+    (newline)
+    (call-with-input-pipe command
+      (lambda (port)
+        ;; FIXME: This messes up the order of stdout and stderr.
+        (let ((message-id
+               ;; Read till you get the Message ID.
+               (port-transduce (tlog (lambda (_ line)
+                                       (display line)
+                                       (newline)))
+                               (rany (lambda (line)
+                                       (and (string-prefix-ci? "Message-ID:" line)
+                                            (assq-ref
+                                             (parse-email-headers
+                                              (string-append line "\n"))
+                                             'message-id))))
+                               get-line
+                               port)))
+          ;; Pass through the rest.
+          (display (get-string-all port))
+          message-id)))))
+
+(define (send-email patches)
+  "Send PATCHES via email."
+  (if (current-issue-number)
+      ;; If an issue is current, send patches to that issue's email
+      ;; address.
+      (git-send-email (string-append (number->string (current-issue-number))
+                                     "@"
+                                     (client-config 'debbugs-host))
+                      patches)
+      (match patches
+        ;; If it's a single patch, send it to the patch email address
+        ;; and be done with it
+        ((patch)
+         (git-send-email (client-config 'patch-email-address)
+                         (list patch)))
+        ;; Else, send first patch to the patch email address and get an
+        ;; issue number. Then, send the remaining patches to that
+        ;; issue's email address.
+        ((first-patch other-patches ...)
+         (git-send-email
+          (string-append (number->string
+                          (issue-number-of-message
+                           (git-send-email (client-config 'patch-email-address)
+                                           (list first-patch))))
+                         "@"
+                         (client-config 'debbugs-host))
+          other-patches)))))
diff --git a/scripts/mumi.in b/scripts/mumi.in
index dfd082d..2295328 100644
--- a/scripts/mumi.in
+++ b/scripts/mumi.in
@@ -126,6 +126,9 @@
     `mumi new':
          clear current issue presumably to open a new one.
 
+    `mumi send-email':
+         send patches to debbugs.
+
     `mumi web [--address=address] [--port=port] [--listen-repl[=port]] [--disable-mailer]':
          start the application web server.
 
@@ -158,6 +161,8 @@
    (client:print-current-issue))
   (("new")
    (client:clear-current-issue!))
+  (("send-email" . patches)
+   (client:send-email patches))
   (("mailer" . rest)
    (let* ((opts (parse-options rest))
           (sender (assoc-ref opts 'sender))
diff --git a/tests/client.scm b/tests/client.scm
new file mode 100644
index 0000000..fb03713
--- /dev/null
+++ b/tests/client.scm
@@ -0,0 +1,118 @@
+;;; mumi -- Mediocre, uh, mail interface
+;;; Copyright © 2023 Arun Isaac <arunisaac@systemreboot.net>
+;;;
+;;; This program is free software: you can redistribute it and/or
+;;; modify it under the terms of the GNU Affero 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
+;;; Affero General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU Affero General Public
+;;; License along with this program.  If not, see
+;;; <http://www.gnu.org/licenses/>.
+
+(use-modules (srfi srfi-26)
+             (srfi srfi-64)
+             (ice-9 match))
+
+(define (with-variable variable value thunk)
+  "Set VARIABLE to VALUE, run THUNK and restore the old value of
+VARIABLE. Return the value returned by THUNK."
+  (let ((old-value (variable-ref variable)))
+    (dynamic-wind
+      (cut variable-set! variable value)
+      thunk
+      (cut variable-set! variable old-value))))
+
+(define (with-variables variable-bindings thunk)
+  "Set VARIABLE-BINDINGS, run THUNK and restore the old values of the
+variables. Return the value returned by THUNK. VARIABLE-BINDINGS is a
+list of pairs mapping variables to their values."
+  (match variable-bindings
+    (((variable . value) tail ...)
+     (with-variable variable value
+       (cut with-variables tail thunk)))
+    (() (thunk))))
+
+(define-syntax-rule (var@@ module-name variable-name)
+  (module-variable (resolve-module 'module-name)
+                   'variable-name))
+
+(define (trace-calls function-variable thunk)
+  "Run THUNK and return a list of argument lists FUNCTION-VARIABLE is
+called with."
+  (let ((args-list (list)))
+    (with-variable function-variable (lambda args
+                                       (set! args-list
+                                             (cons args args-list)))
+      thunk)
+    (reverse args-list)))
+
+(define client-config-stub
+  (cons (var@@ (mumi client) client-config)
+        (lambda (key)
+          (case key
+            ((debbugs-host) "example.com")
+            ((patch-email-address) "foo@patches.com")
+            (else (error "Key unimplemented in stub" key))))))
+
+(test-begin "client")
+
+(test-equal "send patches to new issue"
+  '(("git" "send-email" "--to=foo@patches.com" "foo.patch")
+    ("git" "send-email" "--to=12345@example.com" "bar.patch" "foobar.patch"))
+  (map (match-lambda
+         ((command _) command))
+       (trace-calls (var@@ (mumi client) call-with-input-pipe)
+         (lambda ()
+           (with-variables (list (cons (var@@ (mumi client) issue-number-of-message)
+                                       (const 12345))
+                                 client-config-stub)
+             (cut (@@ (mumi client) send-email)
+                  (list "foo.patch" "bar.patch" "foobar.patch")))))))
+
+(test-equal "send patches to existing issue"
+  '(("git" "send-email" "--to=12345@example.com" "foo.patch" "bar.patch" "foobar.patch"))
+  (map (match-lambda
+         ((command _) command))
+       (trace-calls (var@@ (mumi client) call-with-input-pipe)
+         (lambda ()
+           (with-variables (list (cons (var@@ (mumi client) current-issue-number)
+                                       (const 12345))
+                                 client-config-stub)
+             (cut (@@ (mumi client) send-email)
+                  (list "foo.patch" "bar.patch" "foobar.patch")))))))
+
+(test-equal "send single patch to new issue"
+  '(("git" "send-email" "--to=foo@patches.com" "foo.patch"))
+  (map (match-lambda
+         ((command _) command))
+       (trace-calls (var@@ (mumi client) call-with-input-pipe)
+         (lambda ()
+           (with-variables (list (cons (var@@ (mumi client) issue-number-of-message)
+                                       (lambda _
+                                         (error "Do not poll server for issue number")))
+                                 client-config-stub)
+             (cut (@@ (mumi client) send-email)
+                  (list "foo.patch")))))))
+
+(test-equal "send single patch to existing issue"
+  '(("git" "send-email" "--to=12345@example.com" "foo.patch"))
+  (map (match-lambda
+         ((command _) command))
+       (trace-calls (var@@ (mumi client) call-with-input-pipe)
+         (lambda ()
+           (with-variables (list (cons (var@@ (mumi client) current-issue-number)
+                                       (const 12345))
+                                 (cons (var@@ (mumi client) issue-number-of-message)
+                                       (lambda _
+                                         (error "Do not poll server for issue number")))
+                                 client-config-stub)
+             (cut (@@ (mumi client) send-email)
+                  (list "foo.patch")))))))
+
+(test-end "client")
-- 
2.39.1





^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [bug#61645] [mumi v3 4/4] Set only GUILE_LOAD_PATH when running tests.
  2023-03-08 13:28   ` Arun Isaac
                       ` (3 preceding siblings ...)
  2023-03-08 15:36     ` [bug#61645] [mumi v3 3/4] client: Support sending email to issues Arun Isaac
@ 2023-03-08 15:36     ` Arun Isaac
  2023-03-30 20:47     ` [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Ludovic Courtès
  5 siblings, 0 replies; 25+ messages in thread
From: Arun Isaac @ 2023-03-08 15:36 UTC (permalink / raw)
  To: 61645, Ludovic Courtès; +Cc: Ricardo Wurmus, Arun Isaac

Somehow, the stubs in tests/client.scm do not work when compiled
modules are found. This could be a guile bug.

* Makefile.am (SCM_LOG_DRIVER): Do not use pre-inst-env. Set only the
load path.
---
 Makefile.am | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 86ba4f0..3e57e63 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -70,8 +70,7 @@ EXTRA_DIST += $(TESTS) \
 AM_TESTS_ENVIRONMENT = abs_top_srcdir="$(abs_top_srcdir)" GUILE_AUTO_COMPILE=0
 
 SCM_LOG_DRIVER =                                          \
-  $(top_builddir)/pre-inst-env                            \
-  $(GUILE) --no-auto-compile -e main                      \
+  $(GUILE) --no-auto-compile -L $(top_srcdir) -e main     \
       $(top_srcdir)/build-aux/test-driver.scm
 
 AM_SCM_LOG_DRIVER_FLAGS = --brief=yes
-- 
2.39.1





^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues
  2023-03-08 13:28   ` Arun Isaac
                       ` (4 preceding siblings ...)
  2023-03-08 15:36     ` [bug#61645] [mumi v3 4/4] Set only GUILE_LOAD_PATH when running tests Arun Isaac
@ 2023-03-30 20:47     ` Ludovic Courtès
  2023-03-30 20:57       ` Ricardo Wurmus
  5 siblings, 1 reply; 25+ messages in thread
From: Ludovic Courtès @ 2023-03-30 20:47 UTC (permalink / raw)
  To: Arun Isaac; +Cc: Ricardo Wurmus, 61645

Hello,

Arun Isaac <arunisaac@systemreboot.net> skribis:

>>> This is only the beginning. I have WIP patches that will add a "mumi
>>> send-email" subcommand that will finally free us from our debbugs
>>> dance when sending multiple patches. I will send them separately once
>>> I have tested it more.
>
> I've already sent these patches as a v2 to this same issue. Waiting for
> Ricardo to merge it now.

I suspect Ricardo is busy with other things.  :-)

Should we set up a repo on Savannah (possibly within the ‘guix’ project)
or on notabug.org, sr.ht, codeberg.org or whatever to make it easier to
distribute permissions?

Ludo’.




^ permalink raw reply	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues
  2023-03-30 20:47     ` [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Ludovic Courtès
@ 2023-03-30 20:57       ` Ricardo Wurmus
  2023-03-30 21:57         ` bug#61645: " Ricardo Wurmus
  2023-03-31 12:15         ` [bug#61645] " Ludovic Courtès
  0 siblings, 2 replies; 25+ messages in thread
From: Ricardo Wurmus @ 2023-03-30 20:57 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 61645, Arun Isaac


Ludovic Courtès <ludo@gnu.org> writes:

> Arun Isaac <arunisaac@systemreboot.net> skribis:
>
>>>> This is only the beginning. I have WIP patches that will add a "mumi
>>>> send-email" subcommand that will finally free us from our debbugs
>>>> dance when sending multiple patches. I will send them separately once
>>>> I have tested it more.
>>
>> I've already sent these patches as a v2 to this same issue. Waiting for
>> Ricardo to merge it now.
>
> I suspect Ricardo is busy with other things.  :-)

Oof, indeed!  Very sorry about that.

Arun, thank you for the patches!

I have applied the patches locally, but ever since I moved
git.elephly.net to gitile on the rockpro64 I haven’t been able to push
to my repos.  I hadn’t been able to make any time to diagnose this
problem as yet.  (Probably related to nginx rewrite rules.)

> Should we set up a repo on Savannah (possibly within the ‘guix’ project)
> or on notabug.org, sr.ht, codeberg.org or whatever to make it easier to
> distribute permissions?

Whichever you decide on: it has my blessing.

-- 
Ricardo




^ permalink raw reply	[flat|nested] 25+ messages in thread

* bug#61645: [PATCH mumi 0/1] Add CLI client to search for issues
  2023-03-30 20:57       ` Ricardo Wurmus
@ 2023-03-30 21:57         ` Ricardo Wurmus
  2023-03-31 12:15         ` [bug#61645] " Ludovic Courtès
  1 sibling, 0 replies; 25+ messages in thread
From: Ricardo Wurmus @ 2023-03-30 21:57 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: Arun Isaac, 61645-done


Ricardo Wurmus <rekado@elephly.net> writes:

> I have applied the patches locally, but ever since I moved
> git.elephly.net to gitile on the rockpro64 I haven’t been able to push
> to my repos.  I hadn’t been able to make any time to diagnose this
> problem as yet.  (Probably related to nginx rewrite rules.)

Fixed and pushed.

-- 
Ricardo




^ permalink raw reply	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues
  2023-03-30 20:57       ` Ricardo Wurmus
  2023-03-30 21:57         ` bug#61645: " Ricardo Wurmus
@ 2023-03-31 12:15         ` Ludovic Courtès
  2023-03-31 20:32           ` Arun Isaac
  1 sibling, 1 reply; 25+ messages in thread
From: Ludovic Courtès @ 2023-03-31 12:15 UTC (permalink / raw)
  To: Ricardo Wurmus; +Cc: 61645, Arun Isaac

Hi!

Ricardo Wurmus <rekado@elephly.net> skribis:

> Ludovic Courtès <ludo@gnu.org> writes:

[...]

>> Should we set up a repo on Savannah (possibly within the ‘guix’ project)
>> or on notabug.org, sr.ht, codeberg.org or whatever to make it easier to
>> distribute permissions?
>
> Whichever you decide on: it has my blessing.

Awesome (I hope that suggestion didn’t come out as harsh!).

Arun, would you like to handle this?  :-)  To have it under the Guix
umbrella on Savannah, you need to file a “support request” on Savannah
asking for a new Git repo.  If you choose something else, well, it’s
different (I’d personally recommend against git{hub,lab}.com).

Ludo’.




^ permalink raw reply	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues
  2023-03-31 12:15         ` [bug#61645] " Ludovic Courtès
@ 2023-03-31 20:32           ` Arun Isaac
  2023-03-31 22:15             ` Ludovic Courtès
  0 siblings, 1 reply; 25+ messages in thread
From: Arun Isaac @ 2023-03-31 20:32 UTC (permalink / raw)
  To: Ludovic Courtès, Ricardo Wurmus; +Cc: 61645


Hi Ludo and Ricardo,

> Arun, would you like to handle this?  :-)  To have it under the Guix
> umbrella on Savannah, you need to file a “support request” on Savannah
> asking for a new Git repo.

Done! See https://savannah.nongnu.org/support/?110861

> If you choose something else, well, it’s different (I’d personally
> recommend against git{hub,lab}.com).

Definitely! I am no big fan of git{hub,lab} either.

From time to time, I need to update the running instance of mumi on the
server and refresh the xapian index. So, it might also help if I could
have access to the server running mumi. Would it be appropriate for me
to have access?

Thanks!
Arun




^ permalink raw reply	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues
  2023-03-31 20:32           ` Arun Isaac
@ 2023-03-31 22:15             ` Ludovic Courtès
  2023-03-31 22:51               ` Arun Isaac
  2023-04-01 17:32               ` Arun Isaac
  0 siblings, 2 replies; 25+ messages in thread
From: Ludovic Courtès @ 2023-03-31 22:15 UTC (permalink / raw)
  To: Arun Isaac; +Cc: Ricardo Wurmus, 61645

Hello!

Arun Isaac <arunisaac@systemreboot.net> skribis:

>> Arun, would you like to handle this?  :-)  To have it under the Guix
>> umbrella on Savannah, you need to file a “support request” on Savannah
>> asking for a new Git repo.
>
> Done! See https://savannah.nongnu.org/support/?110861

Yay!

>> If you choose something else, well, it’s different (I’d personally
>> recommend against git{hub,lab}.com).
>
> Definitely! I am no big fan of git{hub,lab} either.
>
> From time to time, I need to update the running instance of mumi on the
> server and refresh the xapian index. So, it might also help if I could
> have access to the server running mumi. Would it be appropriate for me
> to have access?

I think so!  Could you email guix-sysadmin@gnu.org so everyone involved
has a chance to see your request?

Thank you,
Ludo’.




^ permalink raw reply	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues
  2023-03-31 22:15             ` Ludovic Courtès
@ 2023-03-31 22:51               ` Arun Isaac
  2023-04-01 17:32               ` Arun Isaac
  1 sibling, 0 replies; 25+ messages in thread
From: Arun Isaac @ 2023-03-31 22:51 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: Ricardo Wurmus, 61645


> I think so!  Could you email guix-sysadmin@gnu.org so everyone involved
> has a chance to see your request?

Done, thanks!




^ permalink raw reply	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues
  2023-03-31 22:15             ` Ludovic Courtès
  2023-03-31 22:51               ` Arun Isaac
@ 2023-04-01 17:32               ` Arun Isaac
  2023-04-24 14:41                 ` Arun Isaac
  1 sibling, 1 reply; 25+ messages in thread
From: Arun Isaac @ 2023-04-01 17:32 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: Ricardo Wurmus, 61645


Hi Ludo,

>>> Arun, would you like to handle this?  :-)  To have it under the Guix
>>> umbrella on Savannah, you need to file a “support request” on Savannah
>>> asking for a new Git repo.
>>
>> Done! See https://savannah.nongnu.org/support/?110861

They want an admin of the Guix project to confirm my request. Could you
please go to the support request page and do so?

Thanks!
Arun




^ permalink raw reply	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues
  2023-04-01 17:32               ` Arun Isaac
@ 2023-04-24 14:41                 ` Arun Isaac
  2023-04-24 20:01                   ` Ludovic Courtès
  0 siblings, 1 reply; 25+ messages in thread
From: Arun Isaac @ 2023-04-24 14:41 UTC (permalink / raw)
  To: Ludovic Courtès, Ricardo Wurmus; +Cc: 61645


Hi,

I have pushed a copy of the mumi repo to Savannah and updated our mumi
package to the latest commit of mumi. I will send out a separate email
to guix-devel explaining how to use the new mumi client.

At some point in the near future, we should consider making a mumi 0.1.0
release.

Regards,
Arun




^ permalink raw reply	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues
  2023-04-24 14:41                 ` Arun Isaac
@ 2023-04-24 20:01                   ` Ludovic Courtès
  2023-04-25 12:28                     ` Arun Isaac
  0 siblings, 1 reply; 25+ messages in thread
From: Ludovic Courtès @ 2023-04-24 20:01 UTC (permalink / raw)
  To: Arun Isaac; +Cc: Ricardo Wurmus, 61645

Hi,

Arun Isaac <arunisaac@systemreboot.net> skribis:

> I have pushed a copy of the mumi repo to Savannah and updated our mumi
> package to the latest commit of mumi. I will send out a separate email
> to guix-devel explaining how to use the new mumi client.

Yay!

> At some point in the near future, we should consider making a mumi 0.1.0
> release.

Maybe consider 1.0, even?  After all, it does the job, right?

  https://0ver.org/

Ludo’.




^ permalink raw reply	[flat|nested] 25+ messages in thread

* [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues
  2023-04-24 20:01                   ` Ludovic Courtès
@ 2023-04-25 12:28                     ` Arun Isaac
  0 siblings, 0 replies; 25+ messages in thread
From: Arun Isaac @ 2023-04-25 12:28 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: Ricardo Wurmus, 61645


>> At some point in the near future, we should consider making a mumi 0.1.0
>> release.
>
> Maybe consider 1.0, even?  After all, it does the job, right?

Sure, 1.0.0 is good too!




^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2023-04-25 12:29 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-20  1:38 [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Arun Isaac
2023-02-20  1:41 ` [bug#61645] [PATCH mumi 1/1] client: " Arun Isaac
2023-02-21  0:32 ` [bug#61645] [PATCH v2 0/4] Add mumi CLI client Arun Isaac
2023-02-21  0:33 ` [bug#61645] [PATCH v2 1/4] client: Add CLI client to search for issues Arun Isaac
2023-02-21  0:33 ` [bug#61645] [PATCH v2 2/4] client: Support checking in to a specific issue Arun Isaac
2023-02-21  0:33 ` [bug#61645] [PATCH v2 3/4] client: Support sending email to issues Arun Isaac
2023-02-21  0:33 ` [bug#61645] [PATCH v2 4/4] Set only GUILE_LOAD_PATH when running tests Arun Isaac
2023-03-08 12:05 ` [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Ludovic Courtès
2023-03-08 13:28   ` Arun Isaac
2023-03-08 15:36     ` [bug#61645] [mumi v3 0/4] Add mumi CLI client Arun Isaac
2023-03-08 15:36     ` [bug#61645] [mumi v3 1/4] client: Add CLI client to search for issues Arun Isaac
2023-03-08 15:36     ` [bug#61645] [mumi v3 2/4] client: Support checking in to a specific issue Arun Isaac
2023-03-08 15:36     ` [bug#61645] [mumi v3 3/4] client: Support sending email to issues Arun Isaac
2023-03-08 15:36     ` [bug#61645] [mumi v3 4/4] Set only GUILE_LOAD_PATH when running tests Arun Isaac
2023-03-30 20:47     ` [bug#61645] [PATCH mumi 0/1] Add CLI client to search for issues Ludovic Courtès
2023-03-30 20:57       ` Ricardo Wurmus
2023-03-30 21:57         ` bug#61645: " Ricardo Wurmus
2023-03-31 12:15         ` [bug#61645] " Ludovic Courtès
2023-03-31 20:32           ` Arun Isaac
2023-03-31 22:15             ` Ludovic Courtès
2023-03-31 22:51               ` Arun Isaac
2023-04-01 17:32               ` Arun Isaac
2023-04-24 14:41                 ` Arun Isaac
2023-04-24 20:01                   ` Ludovic Courtès
2023-04-25 12:28                     ` Arun Isaac

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.