Subject: bug#62589: [PATCH] gnu: nerd-dictation: Factor out wrapper. Add package variants.

From: Nicolas Graves <[email-masked]>
Date: Sat, 1 Apr 2023 12:05:09 +0200

* gnu/packages/machine-learning.scm (nerd-dictation):
Avoid inputs pulseaudio and ydotool when not necessary.
Factor out wrapper make-nerd-dictation-package.
Add package variants :
- nerd-dictation/xdotool
- nerd-dictation/sox-xdotool
- nerd-dictation/sox-ydotool
- nerd-dictation/sox-wtype
---
 gnu/packages/machine-learning.scm | 88 +++++++++++++++++++++----------
 1 file changed, 60 insertions(+), 28 deletions(-)

diff --git a/gnu/packages/machine-learning.scm b/gnu/packages/machine-learning.scm
index 6c78b14fc6..16a5c1a7c4 100644
--- a/gnu/packages/machine-learning.scm
+++ b/gnu/packages/machine-learning.scm
@@ -17,6 +17,7 @@
 ;;; Copyright © 2020 Edouard Klein <[email-masked]>
 ;;; Copyright © 2020, 2021, 2022, 2023 Vinicius Monego <[email-masked]>
 ;;; Copyright © 2020, 2021, 2022, 2023 Maxim Cournoyer <[email-masked]>
+;;; Copyright © 2022, 2023 Nicolas Graves <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -63,6 +64,7 @@ (define-module (gnu packages machine-learning)
   #:use-module (gnu packages cran)
   #:use-module (gnu packages databases)
   #:use-module (gnu packages dejagnu)
+  #:use-module (gnu packages freedesktop)
   #:use-module (gnu packages gcc)
   #:use-module (gnu packages gettext)
   #:use-module (gnu packages gl)
@@ -106,6 +108,7 @@ (define-module (gnu packages machine-learning)
   #:use-module (gnu packages xml)
   #:use-module (gnu packages xdisorg)
   #:use-module (gnu packages xorg)
+  #:use-module (srfi srfi-45)
   #:use-module (ice-9 match))
 
 (define-public fann
@@ -3864,7 +3867,6 @@ (define-public nerd-dictation
            (add-after 'unpack 'chdir
              (lambda _ (chdir "package/python"))))))
       (propagated-inputs (list python-vosk))
-      (inputs (list pulseaudio xdotool))
       (home-page "https://github.com/ideasman42/nerd-dictation")
       (synopsis "Offline speech-to-text for desktop Linux")
       (description "\
@@ -3876,38 +3878,68 @@ (define-public nerd-dictation
 @code{nerd-dictation begin} and @code{nerd-dictation end} commands.")
       (license license:gpl3+))))
 
-(define-public nerd-dictation/wayland
-  (package
-    (inherit nerd-dictation)
-    (name "nerd-dictation-wayland")
-    (inputs (list bash-minimal nerd-dictation))
-    (propagated-inputs (list ydotool sox))
-    (build-system trivial-build-system)
-    (arguments
-     (list
-      #:modules '((guix build utils))
-      #:builder
-      #~(begin
-          (use-modules (guix build utils))
-          (let* ((exe (string-append #$output "/bin/nerd-dictation"))
-                 (original-exe #$(file-append nerd-dictation
-                                              "/bin/nerd-dictation"))
-                 (bash #$(this-package-input "bash-minimal"))
-                 (bash-exe (string-append bash "/bin/bash")))
-            (mkdir-p (dirname exe))
-            (call-with-output-file exe
-              (lambda (port)
-                (format port "#!~a
+(define* (make-nerd-dictation-package
+          input-tool output-tool
+          #:key (nerd-dictation-package nerd-dictation))
+  "Construct a nerd-dictation package for OUTPUT-TOOL."
+  (match-let* (((input-name output-name)
+                (map (lambda (tool)
+                       (lazy
+                        (delay (package-name (force tool)))))
+                     (list input-tool output-tool))))
+    (package
+      (inherit nerd-dictation-package)
+      (name (string-append "nerd-dictation-"
+                           (if (equal? (force input-name) "sox")
+                               "sox-"
+                              "")
+                           (force output-name)))
+      (build-system trivial-build-system)
+      (arguments
+       (list
+        #:modules '((guix build utils))
+        #:builder
+        #~(begin
+            (use-modules (guix build utils))
+            (let* ((exe (string-append #$output "/bin/nerd-dictation"))
+                   (original-exe #$(file-append
+                                    (this-package-input "nerd-dictation")
+                                    "/bin/nerd-dictation"))
+                   (bash #$(this-package-input "bash-minimal"))
+                   (bash-exe (string-append bash "/bin/bash")))
+              (mkdir-p (dirname exe))
+              (call-with-output-file exe
+                (lambda (port)
+                  (format port "#!~a
 if [ \"$1\" = begin ]
   then
-    exec ~a $@ --input=SOX --simulate-input-tool=YDOTOOL
+    exec ~a $@ --input=~a --simulate-input-tool=~a
   else
     exec ~a $@
 fi"
-                        bash-exe
-                        original-exe
-                        original-exe)))
-            (chmod exe #o555)))))))
+                          bash-exe
+                          original-exe
+                          (if (equal? #$(force input-name) "pulseaudio")
+                              "parec"
+                              (string-upcase #$(force input-name)))
+                          (string-upcase #$(force output-name))
+                          original-exe)))
+              (chmod exe #o555)))))
+      (inputs (list bash-minimal nerd-dictation-package))
+      (propagated-inputs (list (force input-tool) (force output-tool))))))
+
+;; More variants are possible, but wayland without pipewire seems unlikely.
+(define-public nerd-dictation/xdotool
+  (make-nerd-dictation-package (delay pulseaudio) (delay xdotool)))
+
+(define-public nerd-dictation/sox-xdotool
+  (make-nerd-dictation-package (delay sox) (delay xdotool)))
+
+(define-public nerd-dictation/sox-ydotool
+  (make-nerd-dictation-package (delay sox) (delay ydotool)))
+
+(define-public nerd-dictation/sox-wtype
+  (make-nerd-dictation-package (delay sox) (delay wtype)))
 
 (define-public python-brian2
   (package
-- 
2.39.2