diff --git a/doc/guix.texi b/doc/guix.texi index 52c992044b..410e6fa37c 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -23,6 +23,7 @@ @title{GNU Guix Reference Manual} @subtitle{Using the GNU Guix Functional Package Manager} @author Ludovic Courtès +@author Nikita Karetnikov @page @vskip 0pt plus 1filll @@ -542,6 +543,14 @@ availability of packages: @table @option +@item --search=@var{regexp} +@itemx -s @var{regexp} +List the available packages whose synopsis or description matches +@var{regexp}. + +For each package, print the following items, separated by tabs: its +name, version, and the source location of its definition. + @item --list-installed[=@var{regexp}] @itemx -I [@var{regexp}] List currently installed packages in the specified profile. When diff --git a/guix-package.in b/guix-package.in index 46d8d66d2e..913872c925 100644 --- a/guix-package.in +++ b/guix-package.in @@ -235,6 +235,31 @@ both when LINK already exists and when it does not." (switch-link))) (else (switch-link))))) ; anything else +(define (find-packages-by-description rx) + "Search in SYNOPSIS and DESCRIPTION using RX. Return a list of +matching packages." + (define (same-location? p1 p2) + ;; Compare locations of two packages. + (equal? (package-location p1) (package-location p2))) + + (delete-duplicates + (sort + (fold-packages (lambda (package result) + (define matches? + (cut regexp-exec rx <>)) + + (if (or (and=> (package-synopsis package) + (compose matches? gettext)) + (and=> (package-description package) + (compose matches? gettext))) + (cons package result) + result)) + '()) + (lambda (p1 p2) + (stringstring (package-location p)))) + (find-packages-by-description regexp)) + #t)) (_ #f)))) (setlocale LC_ALL "") diff --git a/tests/guix-package.sh b/tests/guix-package.sh index bd63c21969..157f863719 100644 --- a/tests/guix-package.sh +++ b/tests/guix-package.sh @@ -1,5 +1,6 @@ # GNU Guix --- Functional package management for GNU # Copyright © 2012, 2013 Ludovic Courtès +# Copyright © 2013 Nikita Karetnikov # # This file is part of GNU Guix. # @@ -68,6 +69,10 @@ then test "`guix-package -p "$profile" -I 'g.*e' | cut -f1`" = "guile-bootstrap" + # Search. + test "`guix-package -s "GNU Hello" | cut -f1`" = "hello" + test "`guix-package -s "n0t4r341p4ck4g3"`" = "" + # Remove a package. guix-package --bootstrap -p "$profile" -r "guile-bootstrap" test -L "$profile-3-link"