summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFulbert <fulbert@bluewin.ch>2022-10-12 07:57:47 +0200
committerGuix Patches Tester <>2022-11-18 12:23:51 +0100
commit8da6a55a2f7d5c634413e694c92488e2be92ba30 (patch)
treed19817663de18b334eaf9c445c0a500771fc962c
parent983906ab72307a5b848a54233b30d9744356de07 (diff)
downloadguix-patches-8da6a55a2f7d5c634413e694c92488e2be92ba30.tar
guix-patches-8da6a55a2f7d5c634413e694c92488e2be92ba30.tar.gz
* doc: guix-cookbook: Add a "Guix API usage examples" chapter.issue-58463
* doc/guix-cookbook.texi ("Guix API usage examples"): New chapter. Transcript of examples given in "Guix REPL - to infinity and beyond" by Simon Tournier at the "10 years of Guix" event.
-rw-r--r--doc/guix-cookbook.texi426
1 files changed, 426 insertions, 0 deletions
diff --git a/doc/guix-cookbook.texi b/doc/guix-cookbook.texi
index f371364746..96d6dd7bda 100644
--- a/doc/guix-cookbook.texi
+++ b/doc/guix-cookbook.texi
@@ -74,6 +74,7 @@ Weblate} (@pxref{Translating Guix,,, guix, GNU Guix reference manual}).
* Containers:: Isolated environments and nested systems
* Advanced package management:: Power to the users!
* Environment management:: Control environment
+* API usage examples:: Using the API via REPL, scripts and extensions.
* Acknowledgments:: Thanks!
* GNU Free Documentation License:: The license of this document.
@@ -103,6 +104,11 @@ System Configuration
* Setting up NGINX with Lua:: Configuring NGINX web-server to load Lua modules.
* Music Server with Bluetooth Audio:: Headless music player with Bluetooth output.
+API usage examples
+
+* API usage examples:: Using Guix through its API via REPL, script and extensions.
+ Transcript of Simon Tournier presentation : Guix REPL - to infinity and beyond
+
@end detailmenu
@end menu
@@ -3576,6 +3582,426 @@ will have predefined environment variables and procedures.
Run @command{direnv allow} to setup the environment for the first time.
@c *********************************************************************
+@node API usage examples
+@chapter API usage examples
+
+This chapter is a transcript of the examples given by Simon Tournier in
+his presentation
+@uref{https://10years.guix.gnu.org/video/guix-repl-to-infinity-and-beyond/,Guix
+REPL - to infinity and beyond} (16 minutes video) at the
+@uref{https://10years.guix.gnu.org/,10 years of Guix} event.
+
+Interactions with Guix as a library through its API via  REPL, script
+and ``guix extension'' (API subject to changes,
+script/extension might break at any update@dots{}).
+
+Throuthout this chapter :
+
+@itemize
+@item
+shell prompt shortened to : @code{'$ '}
+@item
+guix REPL prompt shortened to : @code{'> '}
+@end itemize
+
+@menu
+* Guix REPL::
+* Guix script::
+* Guix extension::
+@end menu
+
+@node Guix REPL
+@section Guix REPL
+@anchor{#guix-repl}
+
+@menu
+* 101::
+* select count packages on criteria::
+* table count/group on criteria::
+@end menu
+
+@node 101
+@subsection 101
+@anchor{#101}
+@quotation Note
+the REPL command @code{,use (module path name)} (shortened
+@code{,u}) can be used as an equivalent for
+@code{(use-modules (module path name))}. @code{,use} alone will list
+currently imported modules.
+@end quotation
+
+Simple Guix REPL session
+@example sh
+$ guix repl
+GNU Guile 3.0.8
+;; [skipped licence preamble]
+> (use-modules (gnu packages base))
+> findutils
+$1 = #<package findutils@@4.8.0 gnu/packages/base.scm:294 7fc88588ddc0>
+> ,use(guix)
+> (package-name findutils)
+$2 = "findutils"
+> (package-version findutils)
+$3 = "4.8.0"
+> (package? findutils)
+$4 = #t
+@end example
+
+@quotation Note
+the REPL command @code{,describe} (can be shortened @code{,d}) :
+Usage: describe OBJ@*
+Show description/documentation. (#f if unavailable)
+@example sh
+> ,d package->derivation
+Return the <derivation> object of PACKAGE for SYSTEM.
+> ,describe package-name
+#f
+@end example
+@end quotation
+
+@quotation Note
+when a module is imported, its exported objects are listed in
+TAB-@dots{} completions.
+
+@example sh
+> package-in<TAB>
+package-input-error? package-input-rewriting/spec
+package-input-rewriting package-inputs
+@end example
+@end quotation
+
+@node select count packages on criteria
+@subsection select count packages on criteria
+@anchor{#select-count-packages-on-criteria}
+(→ 4 min 20 s into Simon Tournier presentation)
+
+In the following REPL session
+
+@itemize
+@item
+count of haskell packages and ;
+
+@item
+count of haskell pacakges using the @code{#:cabal-revision} argument
+@emph{(present in the package ghc-crypthohash-sha1, as shown below, for
+instance)}
+
+@lisp
+(define-public ghc-cryptohash-sha1
+ (package
+ ;; skipped for clarity
+ (build-system haskell-build-system)
+ (arguments
+ `(#:cabal-revision
+ ("6" "10rpxrmqgwihmplczglwxf5q3l13z9j3kvi065z884y4dymmnkgc")
+ ;; …
+@end lisp
+
+@end itemize
+
+REPL session :
+
+@example sh
+$ guix repl
+GNU Guile 3.0.8
+;; [skipped licence preamble]
+> (use-modules
+ (guix)
+ (guix build-system haskell)
+ (gnu)
+ (ice-9 match))
+>
+> (define haskell-packages
+ (fold-packages
+ (lambda (package result)
+ (if (eq? (package-build-system package) haskell-build-system)
+ (cons package result)
+ result))
+ '()))
+> (define (cabal-revision? package)
+ (apply (lambda* (#:key cabal-revision #:allow-other-keys)
+ (match cabal-revision
+ ((revision hash) #t)
+ (_ #f)))
+ (package-arguments package)))
+> (define cabal-revision-packages
+ (filter cabal-revision? haskell-packages))
+> (length haskell-packages)
+$1 = 721
+> (length cabal-revision-packages)
+$2 = 108
+@end example
+
+@node table count/group on criteria
+@subsection table count/group on criteria
+@anchor{#table-countgroup-on-criteria}
+(→ 5 min 20 s into Simon Tournier presentation)
+
+The @code{arguments-vs-import.scm} file shown below demonstrate some
+more sophisticated selection and grouping of packages, and can be passed
+to @code{guix repl} like so :
+@example sh
+$ guix repl -- arguments-vs-import.scm
+@end example
+Its interpretation will output a table similar to the one show below the
+script-file content, giving the number of packages which ``tweak'' their
+arguments to the build and the number of packages which don't, all
+grouped by build-system types.
+
+@code{arguments-vs-import.scm} file content :
+
+@lisp
+(use-modules (guix)
+ (gnu)
+ (ice-9 match))
+
+(define table (make-hash-table))
+
+(fold-packages (lambda (package result)
+ (let ((bs (build-system-name
+ (package-build-system package)))
+ (arg (package-arguments package)))
+ (match (hash-ref result bs)
+ ((tot wo wi)
+ (if (null? arg)
+ (hash-set! result bs (list
+ (1+ tot)
+ (1+ wo)
+ wi))
+ (hash-set! result bs (list
+ (1+ tot)
+ wo
+ (1+ wi)))))
+ (#f (if (null? arg)
+ (hash-set! result bs (list 1 1 0))
+ (hash-set! result bs (list 1 0 1))))
+ (_ (format #t "Error: ~s~%" (package-name package))))
+ result))
+ table)
+
+(define fmt "~13s: ~4s = ~4s = ~4s + ~4s~%")
+(format #t fmt
+ 'key 'tot 'tot 'no-arguments 'arguments)
+(hash-for-each-handle (lambda (kv)
+ (match kv
+ ((key . value)
+ (match value
+ ((tot wo wi)
+ (format #t fmt
+ key
+ (+ wo wi)
+ tot wo wi))))))
+ table)
+@end lisp
+
+call from shell and output :
+
+@example sh
+$ cd ~/tmp/10-years-of-guix
+$ guix repl -- guix-repl-and-beyond.scm
+key : tot = tot = no-arguments + arguments
+ocaml : 57 = 57 = 0 + 57
+haskell : 721 = 721 = 504 + 217
+clojure : 11 = 11 = 0 + 11
+[skipping for clarity]
+meson : 442 = 442 = 89 + 353
+texlive : 143 = 143 = 0 + 143
+python : 2619 = 2619 = 797 + 1822
+binary : 14 = 14 = 0 + 14
+@end example
+
+@node Guix script
+@section Guix script
+@anchor{#guix-script}
+Simon Tournier does not say much about using guix through scripts@dots{}
+probably because there is not much to say and the following links should
+answer most questions.
+
+@itemize
+@item
+@uref{https://www.gnu.org/software/guile/manual/html_node/Running-Guile-Scripts.html#Running-Guile-Scripts,Running
+Guile Scripts (Guile Reference Manual)}
+@item
+@uref{https://www.gnu.org/software/guile/manual/html_node/Guile-Scripting.html#Guile-Scripting,Guile
+Scripting (Guile Reference Manual)}
+@item
+@uref{https://www.gnu.org/software/coreutils/manual/html_node/env-invocation.html#env-invocation,env
+invocation (GNU Coreutils 9.1)}
+@end itemize
+
+Nevertheless, the script ``@code{explore}'', from Ludovic Courtès, used
+in the next section to demonstrate a ``script-to-extension conversion'',
+is probably an interesting example of using the guix API. See the links
+below for more :
+
+@itemize
+@item
+@uref{https://10years.guix.gnu.org/video/explore-your-system/,Ten Years
+of Guix --- Explore your system --- Ludovic Courtès}
+@item
+@uref{https://notabug.org/civodul/guix-explorer,civodul/guix-explorer:
+Exploring Guix System. - NotABug.org: Free code hosting}
+@end itemize
+
+@node Guix extension
+@section Guix extension
+@anchor{#guix-extension}
+(→ 7 min 05 s into Simon Tournier presentation)
+
+@menu
+* minimal example::
+* Ludovic Courtès's explore.scm program::
+@end menu
+
+@node minimal example
+@subsection minimal example
+@anchor{#minimal-example}
+As a minimal example of a guix extension, the following file,
+@code{~/tmp/10-years-of-guix/guix/extensions/hello.scm}, is used :
+
+@lisp
+(define-module (guix extensions hello)
+ #:export (guix-hello))
+
+(define-command (guix-hello . cmd-line)
+ (category plumbing)
+ (synopsis "hello world")
+ (display (G_ "hello folks!")))
+@end lisp
+
+The environment variable @code{GUIX_EXTENSIONS_PATH} has to include the
+path to the scrip file.
+
+With this in place, we can see the @code{hello} extension integrated in
+the @code{guix} CLI, as the following capture shows, with the new
+command ``hello'' added to the ``plumbing'' category :
+
+@example sh
+$ export GUIX_EXTENSIONS_PATH="$HOME/tmp/10-years-of-guix/guix/extensions"
+$ guix help
+Usage: guix OPTION | COMMAND ARGS...
+Run COMMAND with ARGS, if given.
+# [skipping for clarity …]
+ plumbing commands
+ archive manipulate, export, and import normalized archives (nars)
+ copy copy store items remotely over SSH
+ git operate on Git repositories
+ offload set up and operate build offloading
+ processes list currently running sessions
+ repl read-eval-print loop (REPL) for interactive programming
+ hello hello world
+
+Report bugs to: bug-guix@@gnu.org.
+# …
+@end example
+
+@node Ludovic Courtès's explore.scm program
+@subsection Ludovic Courtès's explore.scm program
+@anchor{#ludovic-courtèss-explore.scm-program}
+The @code{explore.scm} script can then be modified as follows to have it work
+as a Guix extension rather than a script.
+
+(→ 9 min 13 s into Simon Tournier presentation)
+
+@itemize
+@item
+removing the shebang call to guile
+
+@example
+@verbatim
+-#!/bin/sh
+-exec "${GUILE:-guile}" -e "(@ (explore) guix-explore)" -s "$0" "$@"
+-!#
+@end verbatim
+@end example
+
+@item
+replacing the module declaration with appropriate path/name
+@example
+@verbatim
+-(define-module (explore)
++(define-module (guix extensions explore)
+@end verbatim
+@end example
+
+@item
+adding the module guix scripts to the use-module list
+@example
+@dots{}
+@verbatim
+ #:use-module (guix ui)
++ #:use-module (guix scripts)
+ #:use-module (guix store)
+@end verbatim
+@dots{}
+@end example
+
+@item
+modifying the guix-explore definition
+@example
+@verbatim
+-(define (guix-explore args)
++(define-command (guix-explore . args)
++ (category extension)
++ (synopsis ``explore your service'')
+(define %user-module @dots{}
+@end verbatim
+@dots{}
+@end example
+@end itemize
+
+@quotation Note on the path to the script
+
+[It seems that] to be used as a guix extension, Guix requires a script
+to live under a
+``[/@dots{}]/guix/extensions[/@dots{}]/<module-name>.scm'' tree
+structure with the corresponding module declaration
+@code{(define-module (guix extensions [@dots{}] <module-name>) @dots{}}.
+
+This will work :
+
+@example sh
+$ pwd
+~/tmp/10-years-of-guix/guix/extensions/test
+$ head -1 hello.scm
+(define-module (guix extensions test hello)
+@end example
+
+@dots{} while this won't work :
+
+@example sh
+$ pwd
+~/tmp/10-years-of-guix/guix/test
+$ head -1 hello.scm
+(define-module (guix test hello)
+@end example
+
+@dots{} nor this :
+
+@example sh
+$ pwd
+~/tmp/10-years-of-guix/nono/
+$ head -1 hello.scm
+(define-module (nono hello)
+@end example
+@end quotation
+
+lauching
+
+@quotation Note
+@code{explore} produces a visual and interactive representation of
+the services used in a OS declaration. The user has to provide a path to
+the OS configuration file to explore.
+@end quotation
+
+All set, explore can now be used as a Guix extension like so :
+
+@example sh
+$ export GUIX_EXTENSIONS_PATH=/path/to/guix/extensions
+$ guix explore -- /path/to/configure.scm
+@end example
+
+@c *********************************************************************
@node Acknowledgments
@chapter Acknowledgments