~ruther/guix-local

db5a94445f3b21b307c73ea72ed495bda891ef28 — Ludovic Courtès 10 years ago d28ef43
guix package: Allow multiple '--search' flags.

* guix/scripts/package.scm (find-packages-by-description): Change 'rx'
parameter to 'regexps'.
[matches-all?, matches-one?]: New procedures.
Use them.
(process-query): Collect regexps from all 'search' queries, and pass
them to 'find-packages-by-description'.
* tests/guix-package.sh: Add tests.
* doc/guix.texi (Invoking guix package): Document it.
3 files changed, 53 insertions(+), 17 deletions(-)

M doc/guix.texi
M guix/scripts/package.scm
M tests/guix-package.sh
M doc/guix.texi => doc/guix.texi +16 -1
@@ 10,7 10,7 @@
@include version.texi

@copying
Copyright @copyright{} 2012, 2013, 2014, 2015 Ludovic Courtès@*
Copyright @copyright{} 2012, 2013, 2014, 2015, 2016 Ludovic Courtès@*
Copyright @copyright{} 2013, 2014 Andreas Enge@*
Copyright @copyright{} 2013 Nikita Karetnikov@*
Copyright @copyright{} 2015 Mathieu Lirzin@*


@@ 1462,6 1462,21 @@ name: gmp
@dots{}
@end example

It is also possible to refine search results using several @code{-s}
flags.  For example, the following command returns a list of board
games:

@example
$ guix package -s '\<board\>' -s game | recsel -p name
name: gnubg
@dots{}
@end example

If we were to omit @code{-s game}, we would also get software packages
that deal with printed circuit boards; removing the angle brackets
around @code{board} would further add packages that have to do with
keyboards.

@item --show=@var{package}
Show details about @var{package}, taken from the list of available packages, in
@code{recutils} format (@pxref{Top, GNU recutils databases,, recutils, GNU

M guix/scripts/package.scm => guix/scripts/package.scm +20 -13
@@ 1,5 1,5 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
;;; Copyright © 2013, 2015 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2014 Alex Kost <alezost@gmail.com>


@@ 230,21 230,24 @@ specified in MANIFEST, a manifest object."
;;; Package specifications.
;;;

(define (find-packages-by-description rx)
  "Return the list of packages whose name, synopsis, or description matches
RX."
(define (find-packages-by-description regexps)
  "Return the list of packages whose name matches one of REGEXPS, or whose
synopsis or description matches all of REGEXPS."
  (define version<? (negate version>=?))

  (define (matches-all? str)
    (every (cut regexp-exec <> str) regexps))

  (define (matches-one? str)
    (find (cut regexp-exec <> str) regexps))

  (sort
   (fold-packages (lambda (package result)
                    (define matches?
                      (cut regexp-exec rx <>))

                    (if (or (matches? (package-name package))
                    (if (or (matches-one? (package-name package))
                            (and=> (package-synopsis package)
                                   (compose matches? P_))
                                   (compose matches-all? P_))
                            (and=> (package-description package)
                                   (compose matches? P_)))
                                   (compose matches-all? P_)))
                        (cons package result)
                        result))
                  '())


@@ 696,11 699,15 @@ processed, #f otherwise."
                                      (package-name p2))))))
         #t))

      (('search regexp)
       (let ((regexp (make-regexp* regexp regexp/icase)))
      (('search _)
       (let* ((patterns (filter-map (match-lambda
                                      (('query 'search rx) rx)
                                      (_                   #f))
                                    opts))
              (regexps  (map (cut make-regexp* <> regexp/icase) patterns)))
         (leave-on-EPIPE
          (for-each (cute package->recutils <> (current-output-port))
                    (find-packages-by-description regexp)))
                    (find-packages-by-description regexps)))
         #t))

      (('show requested-name)

M tests/guix-package.sh => tests/guix-package.sh +17 -3
@@ 1,5 1,5 @@
# GNU Guix --- Functional package management for GNU
# Copyright © 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
# Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
# Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
#
# This file is part of GNU Guix.


@@ 30,9 30,10 @@ readlink_base ()

module_dir="t-guix-package-$$"
profile="t-profile-$$"
rm -f "$profile"
tmpfile="t-guix-package-file-$$"
rm -f "$profile" "$tmpfile"

trap 'rm -f "$profile" "$profile-"[0-9]* ; rm -rf "$module_dir" t-home-'"$$" EXIT
trap 'rm -f "$profile" "$profile-"[0-9]* "$tmpfile"; rm -rf "$module_dir" t-home-'"$$" EXIT

# Use `-e' with a non-package expression.
if guix package --bootstrap -e +;


@@ 96,6 97,19 @@ test "`guix package -s "An example GNU package" | grep ^name:`" = \
    "name: hello"
test -z "`guix package -s "n0t4r341p4ck4g3"`"

# Search with one and then two regexps.
# First we get printed circuit boards *and* board games.
guix package -s '\<board\>' > "$tmpfile"
grep '^name: pcb' "$tmpfile"
grep '^name: gnubg' "$tmpfile"

# Second we get only board games.
guix package -s '\<board\>' -s game > "$tmpfile"
grep -v '^name: pcb' "$tmpfile" > /dev/null
grep '^name: gnubg' "$tmpfile"

rm -f "$tmpfile"

# Make sure `--search' can display all the packages.
guix package --search="" > /dev/null