Subject: Re: [bug#51512] [PATCH v6 3/3]: gnu: Add bash-coding-utils

From: david larsson <[email-masked]>
Date: Tue, 23 May 2023 06:56:25 +0200

From bb7ab11b11058d609a89cad164308b5b52ebadca Mon Sep 17 00:00:00 2001
 From: David Larsson <[email-masked]>
Date: Tue, 23 May 2023 06:42:03 +0200
Subject: [PATCH 3/3] gnu: Add bash-coding-utils

* gnu/packages/bash.scm (bash-coding-utils)
(org-html-themes/methuselah-0): new variables.
---
  gnu/packages/bash.scm | 260 ++++++++++++++++++++++++++++++++++++++++++
  1 file changed, 260 insertions(+)

diff --git a/gnu/packages/bash.scm b/gnu/packages/bash.scm
index 64d6e8d65e..986ec68b3f 100644
--- a/gnu/packages/bash.scm
+++ b/gnu/packages/bash.scm
@@ -31,17 +31,28 @@ (define-module (gnu packages bash)
    #:use-module (gnu packages bootstrap)
    #:use-module (gnu packages compression)
    #:use-module (gnu packages elf)
+  #:use-module (gnu packages file)
+  #:use-module (gnu packages freedesktop)
+  #:use-module (gnu packages gawk)
    #:use-module (gnu packages ncurses)
    #:use-module (gnu packages networking)
    #:use-module (gnu packages readline)
    #:use-module (gnu packages bison)
    #:use-module (gnu packages linux)
    #:use-module (gnu packages libffi)
+  #:use-module (gnu packages lsof)
+  #:use-module (gnu packages pcre)
+  #:use-module (gnu packages perl)
+  #:use-module (gnu packages php)
    #:use-module (gnu packages pkg-config)
    #:use-module (gnu packages python)
+  #:use-module (gnu packages python-xyz)
    #:use-module (gnu packages guile)
    #:use-module (gnu packages guile-xyz)
+  #:use-module (gnu packages search)
    #:use-module (gnu packages version-control)
+  #:use-module (gnu packages web)
+  #:use-module (gnu packages xml)
    #:use-module (gnu packages less)
    #:use-module (guix packages)
    #:use-module (guix download)
@@ -574,3 +585,252 @@ (define-public guile-bash-for-bash-coding-utils
        (inputs (modify-inputs (package-inputs guile2.0-bash)
                  (replace "guile" guile-3.0-latest)))
        (propagated-inputs (list bash)))))
+
+(define org-html-themes/methuselah-0
+  ;; A form of https://github.com/fniessen/org-html-themes but not
+  ;; drop-in compatible (using that would break the BCU docs).
+  (let ((commit "cce6e288649d6555cb74583f3c02a1e4e97fa1f8")
+        (revision "0"))
+    (package
+      (name "org-html-themes")
+      (version (git-version "0.0.0" revision commit))
+      (source
+       (origin
+         (method git-fetch)
+         (uri (git-reference
+               (commit commit)
+               (url 
"https://gitlab.com/methuselah-0/org-html-themes.git")))
+         (file-name (git-file-name name version))
+         (sha256
+          (base32 
"1ka40r5a7xc522wc03v3rwfwq3abb8c1h8sr3hw5v1gsws9s18y9"))))
+      (build-system copy-build-system)
+      (home-page "https://gitlab.com/methuselah-0/org-html-themes")
+      (synopsis "Export Org mode files to HTML")
+      (description
+       "The Org-HMTL framework provides cross-browser themes for 
exporting Org
+documents to cross-browser HTML mark-up.")
+      (license license:gpl3))))
+
+(define-public bash-coding-utils
+  (let ((commit "f1f0ed8bc39db2d5a2b6d3c5aca3e5cbadebfb29")
+        (revision "0"))
+    (package
+      (name "bash-coding-utils")
+      (version (git-version "0.3.0" revision commit))
+      (source
+       (origin
+         (method git-fetch)
+         (uri
+          (git-reference
+           (commit commit)
+           (url "https://git.sr.ht/~methuselah-0/bash-coding-utils")
+           (recursive? #t))          )
+         (sha256
+          (base32 
"1vpp91nsp0gyp5n4kkq0cjsndry9wclxrcr5y41fi1g35vw3m3zz"))
+         (file-name (git-file-name name version))))
+      (build-system trivial-build-system)
+      (arguments
+       (list #:modules '((guix build utils))
+             #:builder
+             #~(begin
+                 (use-modules (guix build utils)
+                              (ice-9 ftw)
+                              (ice-9 match)
+                              (srfi srfi-26))
+                 (let* ((bash #$(this-package-input "bash"))
+                        (bin (string-append #$output "/bin"))
+                        (bcu.sh (string-append bin "/bcu.sh"))
+                        (share (string-append #$output "/share"))
+                        (doc (string-append share "/doc/" #$name))
+                        ;; Everything but bcu.sh itself is only ever 
accessed
+                        ;; internally by bcu, so put it all in share/.
+                        (bcu-root (string-append share "/bcu"))
+                        ;; XXX We should honour the without-tests 
transformation!
+                        (tests? (not #$(%current-target-system))))
+
+                   ;; Copy the ‘source’ to the output and replace 
submodules.
+                   (let ((source #$(package-source this-package)))
+                     (with-directory-excursion source
+                       (mkdir-p (string-append bcu-root "/submodules"))
+                       (for-each (lambda (file)
+                                   (copy-recursively file
+                                                     (string-append 
bcu-root
+                                                                    "/" 
file)))
+                                 (list "bcu.sh"
+                                       "dependency_paths.sh"
+                                       "bcu-test.sh"
+                                       "docs"
+                                       "src"))
+                       (copy-recursively
+                        #$(package-source (this-package-input
+                                           "org-html-themes"))
+                        (string-append bcu-root
+                                       
"/submodules/org-html-themes"))))
+                   ;; Patch absolute file name references.
+                   (let* ((original-path (getenv "PATH"))
+                          (shebang-inputs '(#$@(map (lambda (name)
+                                                      
(this-package-input name))
+                                                    '("guile"
+                                                      "python"))))
+                          (shebang-path (string-join
+                                         (map (cut string-append <> 
"/bin")
+                                              (cons bash 
shebang-inputs))
+                                         ":")))
+                     (setenv "PATH" shebang-path)
+                     (for-each patch-shebang
+                               (find-files #$output "\\.(sh|scm|py)$"))
+                     (setenv "PATH" original-path))
+
+                   ;; Add paths to dependencies - defined in
+                   ;; dependency_paths.sh, except the libguile-bash.so
+                   ;; file.
+                   (substitute* (find-files #$output "\\.sh$")
+                     (("[^ ]*(/lib/bash/libguile-bash\\.so)" _ library)
+                      (string-append
+                       #$(this-package-input 
"guile-bash-for-bash-coding-utils")
+                       library)))
+
+                   (substitute* (find-files #$output 
"dependency_paths\\.sh$")
+                     (("=ctypes.sh") (string-append "=" 
#$(this-package-input "bash-ctypes") "/bin/ctypes.sh"))
+                     (("=diff") (string-append "=" 
#$(this-package-input "diffutils") "/bin/diff"))
+                     (("=ping") (string-append "=" 
"/run/setuid-programs/ping"))
+                     (("=ps") (string-append "=" #$(this-package-input 
"procps") "/bin/ps"))
+                     (("=file") (string-append "=" 
#$(this-package-input "findutils") "/bin/file"))
+                     (("=find") (string-append "=" 
#$(this-package-input "findutils") "/bin/find"))
+                     (("=flock") (string-append "=" 
#$(this-package-input "util-linux") "/bin/flock"))
+                     (("=gawk") (string-append "=" 
#$(this-package-input "gawk") "/bin/gawk"))
+                     (("=ugrep") (string-append "=" 
#$(this-package-input "ugrep") "/bin/ugrep"))
+                     (("=jq") (string-append "=" #$(this-package-input 
"jq") "/bin/jq"))
+                     (("=lsof") (string-append "=" 
#$(this-package-input "lsof") "/bin/lsof"))
+                     (("=nmap") (string-append "=" 
#$(this-package-input "nmap") "/bin/nmap"))
+                     (("=perl") (string-append "=" 
#$(this-package-input "perl") "/bin/perl"))
+                     (("=php") (string-append "=" #$(this-package-input 
"php") "/bin/php"))
+                     (("=ps") (string-append "=" #$(this-package-input 
"procps") "/bin/ps"))
+                     (("=pydaemon.sh") (string-append "=" 
#$(this-package-input "pydaemon") "/bin/pydaemon.sh"))
+                     (("=sed") (string-append "=" #$(this-package-input 
"sed") "/bin/sed"))
+                     (("=socat") (string-append "=" 
#$(this-package-input "socat") "/bin/socat"))
+                     (("=tree") (string-append "=" 
#$(this-package-input "tree") "/bin/tree"))
+                     (("=pcre2grep") (string-append "=" 
#$(this-package-input "pcre2") "/bin/pcre2grep"))
+                     (("=which") (string-append "=" 
#$(this-package-input "which") "/bin/which"))
+                     (("=xargs") (string-append "=" 
#$(this-package-input "findutils") "/bin/xargs"))
+                     (("=xdg-open") (string-append "=" 
#$(this-package-input "xdg-utils") "/bin/xdg-open"))
+                     (("=xmllint") (string-append "=" 
#$(this-package-input "libxml2-xpath0") "/bin/xmllint"))
+                     (("export GUILE_LOAD_PATH=(.*)$")
+                      (string-append "export GUILE_LOAD_PATH=\""
+                                     (string-join
+                                      '(#$@(map (lambda (name)
+                                                  (file-append 
(this-package-input name)
+                                                               
"/share/guile/site/"
+                                                               
(version-major+minor
+                                                                
(package-version
+                                                                 
(this-package-input
+                                                                  
"guile")))))
+                                                
'("guile-bash-for-bash-coding-utils")))
+                                      ":")
+                                     
"${GUILE_LOAD_PATH:+:}${GUILE_LOAD_PATH}\"\n"))
+                     (("export BCUPYTHONVERSION=(.*)$" _)
+                      (string-append "export BCUPYTHONVERSION="
+                                     #$(version-major+minor
+                                        (package-version
+                                         (this-package-input
+                                          "python")))))
+                     (("export BCUPYTHON=python(.*)$" _)
+                      (string-append "export BCUPYTHON="
+                                     #$(file-append (this-package-input 
"python")
+                                                    "/bin/python"
+                                                    
(version-major+minor
+                                                     (package-version
+                                                      
(this-package-input
+                                                       "python"))))
+                                     "\n"))
+                     (("export PYTHONPATH=.*" all)
+                      (string-append "export PYTHONPATH=\""
+                                     (string-join
+                                      '(#$@(map (lambda (name)
+                                                  (file-append 
(this-package-input name)
+                                                               
"/lib/python"
+                                                               
(version-major+minor
+                                                                
(package-version
+                                                                 
(this-package-input
+                                                                  
"python")))
+                                                               
"/site-packages"))
+                                                '("python"
+                                                  "python-elementpath"
+                                                  "python-lxml"
+                                                  "python-netaddr")))
+                                      ":")
+                                     
"${PYTHONPATH:+:}${PYTHONPATH}\"\n"))
+                     (("export XDG_DATA_DIRS=(.*)$")
+                      (string-append
+                       "[[ -e /run/current-system/profile/share ]] && "
+                       "export XDG_DATA_DIRS="
+                       "/run/current-system/profile/share"
+                       "${XDG_DATA_DIRS:+:}${XDG_DATA_DIRS}\n")))
+
+                   ;; Symlink to bcu.sh from the output bin directory.
+                   (mkdir-p bin)
+                   (symlink (string-append bcu-root "/bcu.sh") bcu.sh)
+                   (chmod bcu.sh #o555)
+
+                   ;; Disable network and gui tests, and one test for 
setopts which
+                   ;; doesn't work inside the Guix build environment.
+                   (with-output-to-file (string-append bcu-root 
"/disabled_tests.txt")
+                     (lambda _
+                       (format #t "~{~a~%~}"
+                               (list "ip_of_test_1"
+                                     "setopts_test_4"
+                                     "web_media_server_test_1"
+                                     "web_api_server_test_1"
+                                     "find_gui_test_1"))))
+
+                   ;; Set up a minimal test environment & run the 
tests.
+                   (when tests?
+                     (setenv "PATH" (string-append bin ":"
+                                                   bash "/bin:"
+                                                   (getenv "PATH")))
+                     (setenv "SHELL"
+                             (string-append bash "/bin/bash"))
+                     (for-each (lambda (test-input)
+                                 (setenv "PATH"
+                                         (string-append
+                                          (assoc-ref %build-inputs 
test-input)
+                                          "/bin:" (getenv "PATH"))))
+                               (list "coreutils"))
+                     (setenv "HOME" "/tmp")
+                     (with-directory-excursion bcu-root
+                       (invoke "./bcu-test.sh")
+                       ;; No need to keep passed tests in the final 
output
+                       (for-each delete-file
+                                 (list "bcu-test.sh"
+                                       "disabled_tests.txt"))))))))
+      (inputs (list bash bash-ctypes coreutils
+                    diffutils file findutils
+                    gawk guile-3.0 guile-bash-for-bash-coding-utils
+                    jq libxml2-xpath0
+                    lsof
+                    nmap
+                    ;; org-html-themes is bundled upstream as a git 
submodule,
+                    ;; but we package it separately and copy it 
manually above.
+                    org-html-themes/methuselah-0
+                    pcre2 perl php
+                    procps
+                    pydaemon python python-elementpath python-lxml
+                    python-netaddr python-yq
+                    sed
+                    socat
+                    tree ugrep util-linux which
+                    xdg-utils ))
+      ;; the bash shell needs to be the same version
+      ;; as guile-bash is compiled against
+      (propagated-inputs (list bash))
+      (home-page "https://git.sr.ht/~methuselah-0/bash-coding-utils")
+      (synopsis "Functions and tools for software prototyping in Bash")
+      (description
+       "Bash-Coding-Utils is a library of Bash functions and wrappers 
that can
+be useful when writing quick implementations of new programs.  It helps 
you
+work with JSON, XML, API's and parallelization, and installs some 
helper
+programs commonly used in Bash scripting.  Just run @command{. bcu.sh}, 
type
+@command{bcu__}, hit @key{TAB} to see available functions and give any 
of them
+the @code{--help} flag to see how to use it, or run @command{bcu__docs} 
for
+the full HTML documentation.")
+      (license license:gpl3))))
--
2.39.1
From bb7ab11b11058d609a89cad164308b5b52ebadca Mon Sep 17 00:00:00 2001
From: David Larsson <[email-masked]>
Date: Tue, 23 May 2023 06:42:03 +0200
Subject: [PATCH 3/3] gnu: Add bash-coding-utils

* gnu/packages/bash.scm (bash-coding-utils)
(org-html-themes/methuselah-0): new variables.
---
 gnu/packages/bash.scm | 260 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 260 insertions(+)

diff --git a/gnu/packages/bash.scm b/gnu/packages/bash.scm
index 64d6e8d65e..986ec68b3f 100644
--- a/gnu/packages/bash.scm
+++ b/gnu/packages/bash.scm
@@ -31,17 +31,28 @@ (define-module (gnu packages bash)
   #:use-module (gnu packages bootstrap)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages elf)
+  #:use-module (gnu packages file)
+  #:use-module (gnu packages freedesktop)
+  #:use-module (gnu packages gawk)
   #:use-module (gnu packages ncurses)
   #:use-module (gnu packages networking)
   #:use-module (gnu packages readline)
   #:use-module (gnu packages bison)
   #:use-module (gnu packages linux)
   #:use-module (gnu packages libffi)
+  #:use-module (gnu packages lsof)
+  #:use-module (gnu packages pcre)
+  #:use-module (gnu packages perl)
+  #:use-module (gnu packages php)
   #:use-module (gnu packages pkg-config)
   #:use-module (gnu packages python)
+  #:use-module (gnu packages python-xyz)
   #:use-module (gnu packages guile)
   #:use-module (gnu packages guile-xyz)
+  #:use-module (gnu packages search)
   #:use-module (gnu packages version-control)
+  #:use-module (gnu packages web)
+  #:use-module (gnu packages xml)
   #:use-module (gnu packages less)
   #:use-module (guix packages)
   #:use-module (guix download)
@@ -574,3 +585,252 @@ (define-public guile-bash-for-bash-coding-utils
       (inputs (modify-inputs (package-inputs guile2.0-bash)
                 (replace "guile" guile-3.0-latest)))
       (propagated-inputs (list bash)))))
+
+(define org-html-themes/methuselah-0
+  ;; A form of https://github.com/fniessen/org-html-themes but not
+  ;; drop-in compatible (using that would break the BCU docs).
+  (let ((commit "cce6e288649d6555cb74583f3c02a1e4e97fa1f8")
+        (revision "0"))
+    (package
+      (name "org-html-themes")
+      (version (git-version "0.0.0" revision commit))
+      (source
+       (origin
+         (method git-fetch)
+         (uri (git-reference
+               (commit commit)
+               (url "https://gitlab.com/methuselah-0/org-html-themes.git")))
+         (file-name (git-file-name name version))
+         (sha256
+          (base32 "1ka40r5a7xc522wc03v3rwfwq3abb8c1h8sr3hw5v1gsws9s18y9"))))
+      (build-system copy-build-system)
+      (home-page "https://gitlab.com/methuselah-0/org-html-themes")
+      (synopsis "Export Org mode files to HTML")
+      (description
+       "The Org-HMTL framework provides cross-browser themes for exporting Org
+documents to cross-browser HTML mark-up.")
+      (license license:gpl3))))
+
+(define-public bash-coding-utils
+  (let ((commit "f1f0ed8bc39db2d5a2b6d3c5aca3e5cbadebfb29")
+        (revision "0"))
+    (package
+      (name "bash-coding-utils")
+      (version (git-version "0.3.0" revision commit))
+      (source
+       (origin
+         (method git-fetch)
+         (uri
+          (git-reference
+           (commit commit)
+           (url "https://git.sr.ht/~methuselah-0/bash-coding-utils")
+           (recursive? #t))          )
+         (sha256
+          (base32 "1vpp91nsp0gyp5n4kkq0cjsndry9wclxrcr5y41fi1g35vw3m3zz"))
+         (file-name (git-file-name name version))))
+      (build-system trivial-build-system)
+      (arguments
+       (list #:modules '((guix build utils))
+             #:builder
+             #~(begin
+                 (use-modules (guix build utils)
+                              (ice-9 ftw)
+                              (ice-9 match)
+                              (srfi srfi-26))
+                 (let* ((bash #$(this-package-input "bash"))
+                        (bin (string-append #$output "/bin"))
+                        (bcu.sh (string-append bin "/bcu.sh"))
+                        (share (string-append #$output "/share"))
+                        (doc (string-append share "/doc/" #$name))
+                        ;; Everything but bcu.sh itself is only ever accessed
+                        ;; internally by bcu, so put it all in share/.
+                        (bcu-root (string-append share "/bcu"))
+                        ;; XXX We should honour the without-tests transformation!
+                        (tests? (not #$(%current-target-system))))
+
+                   ;; Copy the ‘source’ to the output and replace submodules.
+                   (let ((source #$(package-source this-package)))
+                     (with-directory-excursion source
+                       (mkdir-p (string-append bcu-root "/submodules"))
+                       (for-each (lambda (file)
+                                   (copy-recursively file
+                                                     (string-append bcu-root
+                                                                    "/" file)))
+                                 (list "bcu.sh"
+                                       "dependency_paths.sh"
+                                       "bcu-test.sh"
+                                       "docs"
+                                       "src"))
+                       (copy-recursively
+                        #$(package-source (this-package-input
+                                           "org-html-themes"))
+                        (string-append bcu-root
+                                       "/submodules/org-html-themes"))))
+                   ;; Patch absolute file name references.
+                   (let* ((original-path (getenv "PATH"))
+                          (shebang-inputs '(#$@(map (lambda (name)
+                                                      (this-package-input name))
+                                                    '("guile"
+                                                      "python"))))
+                          (shebang-path (string-join
+                                         (map (cut string-append <> "/bin")
+                                              (cons bash shebang-inputs))
+                                         ":")))
+                     (setenv "PATH" shebang-path)
+                     (for-each patch-shebang
+                               (find-files #$output "\\.(sh|scm|py)$"))
+                     (setenv "PATH" original-path))
+
+                   ;; Add paths to dependencies - defined in
+                   ;; dependency_paths.sh, except the libguile-bash.so
+                   ;; file.
+                   (substitute* (find-files #$output "\\.sh$")
+                     (("[^ ]*(/lib/bash/libguile-bash\\.so)" _ library)
+                      (string-append
+                       #$(this-package-input "guile-bash-for-bash-coding-utils")
+                       library)))
+
+                   (substitute* (find-files #$output "dependency_paths\\.sh$")
+                     (("=ctypes.sh") (string-append "=" #$(this-package-input "bash-ctypes") "/bin/ctypes.sh"))
+                     (("=diff") (string-append "=" #$(this-package-input "diffutils") "/bin/diff"))
+                     (("=ping") (string-append "=" "/run/setuid-programs/ping"))
+                     (("=ps") (string-append "=" #$(this-package-input "procps") "/bin/ps"))
+                     (("=file") (string-append "=" #$(this-package-input "findutils") "/bin/file"))
+                     (("=find") (string-append "=" #$(this-package-input "findutils") "/bin/find"))
+                     (("=flock") (string-append "=" #$(this-package-input "util-linux") "/bin/flock"))
+                     (("=gawk") (string-append "=" #$(this-package-input "gawk") "/bin/gawk"))
+                     (("=ugrep") (string-append "=" #$(this-package-input "ugrep") "/bin/ugrep"))
+                     (("=jq") (string-append "=" #$(this-package-input "jq") "/bin/jq"))
+                     (("=lsof") (string-append "=" #$(this-package-input "lsof") "/bin/lsof"))
+                     (("=nmap") (string-append "=" #$(this-package-input "nmap") "/bin/nmap"))
+                     (("=perl") (string-append "=" #$(this-package-input "perl") "/bin/perl"))
+                     (("=php") (string-append "=" #$(this-package-input "php") "/bin/php"))
+                     (("=ps") (string-append "=" #$(this-package-input "procps") "/bin/ps"))
+                     (("=pydaemon.sh") (string-append "=" #$(this-package-input "pydaemon") "/bin/pydaemon.sh"))
+                     (("=sed") (string-append "=" #$(this-package-input "sed") "/bin/sed"))
+                     (("=socat") (string-append "=" #$(this-package-input "socat") "/bin/socat"))
+                     (("=tree") (string-append "=" #$(this-package-input "tree") "/bin/tree"))
+                     (("=pcre2grep") (string-append "=" #$(this-package-input "pcre2") "/bin/pcre2grep"))
+                     (("=which") (string-append "=" #$(this-package-input "which") "/bin/which"))
+                     (("=xargs") (string-append "=" #$(this-package-input "findutils") "/bin/xargs"))
+                     (("=xdg-open") (string-append "=" #$(this-package-input "xdg-utils") "/bin/xdg-open"))
+                     (("=xmllint") (string-append "=" #$(this-package-input "libxml2-xpath0") "/bin/xmllint"))
+                     (("export GUILE_LOAD_PATH=(.*)$")
+                      (string-append "export GUILE_LOAD_PATH=\""
+                                     (string-join
+                                      '(#$@(map (lambda (name)
+                                                  (file-append (this-package-input name)
+                                                               "/share/guile/site/"
+                                                               (version-major+minor
+                                                                (package-version
+                                                                 (this-package-input
+                                                                  "guile")))))
+                                                '("guile-bash-for-bash-coding-utils")))
+                                      ":")
+                                     "${GUILE_LOAD_PATH:+:}${GUILE_LOAD_PATH}\"\n"))
+                     (("export BCUPYTHONVERSION=(.*)$" _)
+                      (string-append "export BCUPYTHONVERSION="
+                                     #$(version-major+minor
+                                        (package-version
+                                         (this-package-input
+                                          "python")))))
+                     (("export BCUPYTHON=python(.*)$" _)
+                      (string-append "export BCUPYTHON="
+                                     #$(file-append (this-package-input "python")
+                                                    "/bin/python"
+                                                    (version-major+minor
+                                                     (package-version
+                                                      (this-package-input
+                                                       "python"))))
+                                     "\n"))
+                     (("export PYTHONPATH=.*" all)
+                      (string-append "export PYTHONPATH=\""
+                                     (string-join
+                                      '(#$@(map (lambda (name)
+                                                  (file-append (this-package-input name)
+                                                               "/lib/python"
+                                                               (version-major+minor
+                                                                (package-version
+                                                                 (this-package-input
+                                                                  "python")))
+                                                               "/site-packages"))
+                                                '("python"
+                                                  "python-elementpath"
+                                                  "python-lxml"
+                                                  "python-netaddr")))
+                                      ":")
+                                     "${PYTHONPATH:+:}${PYTHONPATH}\"\n"))
+                     (("export XDG_DATA_DIRS=(.*)$")
+                      (string-append
+                       "[[ -e /run/current-system/profile/share ]] && "
+                       "export XDG_DATA_DIRS="
+                       "/run/current-system/profile/share"
+                       "${XDG_DATA_DIRS:+:}${XDG_DATA_DIRS}\n")))
+
+                   ;; Symlink to bcu.sh from the output bin directory.
+                   (mkdir-p bin)
+                   (symlink (string-append bcu-root "/bcu.sh") bcu.sh)
+                   (chmod bcu.sh #o555)
+
+                   ;; Disable network and gui tests, and one test for setopts which
+                   ;; doesn't work inside the Guix build environment.
+                   (with-output-to-file (string-append bcu-root "/disabled_tests.txt")
+                     (lambda _
+                       (format #t "~{~a~%~}"
+                               (list "ip_of_test_1"
+                                     "setopts_test_4"
+                                     "web_media_server_test_1"
+                                     "web_api_server_test_1"
+                                     "find_gui_test_1"))))
+
+                   ;; Set up a minimal test environment & run the tests.
+                   (when tests?
+                     (setenv "PATH" (string-append bin ":"
+                                                   bash "/bin:"
+                                                   (getenv "PATH")))
+                     (setenv "SHELL"
+                             (string-append bash "/bin/bash"))
+                     (for-each (lambda (test-input)
+                                 (setenv "PATH"
+                                         (string-append
+                                          (assoc-ref %build-inputs test-input)
+                                          "/bin:" (getenv "PATH"))))
+                               (list "coreutils"))
+                     (setenv "HOME" "/tmp")
+                     (with-directory-excursion bcu-root
+                       (invoke "./bcu-test.sh")
+                       ;; No need to keep passed tests in the final output
+                       (for-each delete-file
+                                 (list "bcu-test.sh"
+                                       "disabled_tests.txt"))))))))
+      (inputs (list bash bash-ctypes coreutils
+                    diffutils file findutils
+                    gawk guile-3.0 guile-bash-for-bash-coding-utils
+                    jq libxml2-xpath0
+                    lsof
+                    nmap
+                    ;; org-html-themes is bundled upstream as a git submodule,
+                    ;; but we package it separately and copy it manually above.
+                    org-html-themes/methuselah-0
+                    pcre2 perl php
+                    procps
+                    pydaemon python python-elementpath python-lxml
+                    python-netaddr python-yq
+                    sed
+                    socat
+                    tree ugrep util-linux which
+                    xdg-utils ))
+      ;; the bash shell needs to be the same version
+      ;; as guile-bash is compiled against
+      (propagated-inputs (list bash))
+      (home-page "https://git.sr.ht/~methuselah-0/bash-coding-utils")
+      (synopsis "Functions and tools for software prototyping in Bash")
+      (description
+       "Bash-Coding-Utils is a library of Bash functions and wrappers that can
+be useful when writing quick implementations of new programs.  It helps you
+work with JSON, XML, API's and parallelization, and installs some helper
+programs commonly used in Bash scripting.  Just run @command{. bcu.sh}, type
+@command{bcu__}, hit @key{TAB} to see available functions and give any of them
+the @code{--help} flag to see how to use it, or run @command{bcu__docs} for
+the full HTML documentation.")
+      (license license:gpl3))))
-- 
2.39.1