summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--distro/packages/lout.scm3
-rw-r--r--doc/guix.texi20
-rw-r--r--guix-package.in41
-rw-r--r--guix/derivations.scm13
-rw-r--r--guix/licenses.scm42
-rw-r--r--guix/utils.scm10
-rw-r--r--tests/guix-package.sh11
7 files changed, 113 insertions, 27 deletions
diff --git a/distro/packages/lout.scm b/distro/packages/lout.scm
index 0ea3b0887d..77228eb6e1 100644
--- a/distro/packages/lout.scm
+++ b/distro/packages/lout.scm
@@ -88,7 +88,8 @@
                "12gkyqrn0kaa8xq7sc7v3wm407pz2fxg9ngc75aybhi5z825b9vq"))))
     (build-system gnu-build-system)               ; actually, just a makefile
     (outputs '("out" "doc"))
-    (inputs `(("ghostscript" ,(nixpkgs-derivation "ghostscript"))))
+    (inputs `(("ghostscript" ,(lambda _    ; FIXME: replace with our own
+                                (nixpkgs-derivation "ghostscript")))))
     (arguments `(#:modules ((guix build utils)
                             (guix build gnu-build-system)
                             (srfi srfi-1))        ; we need SRFI-1
diff --git a/doc/guix.texi b/doc/guix.texi
index b01aa961c1..b8ab94f5ad 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -160,7 +160,7 @@ packages.  It operates on those per-user profiles, and can be used
 
 The command provides the obvious install, remove, and upgrade
 operations.  Each invocation is actually a @emph{transaction}: either
-the specified operations succeed, or nothing happens.  Thus, if the
+the specified operation succeeds, or nothing happens.  Thus, if the
 @command{guix-package} processed is terminated during the transaction,
 or if a power outage occurs during the transaction, then the user's
 profile remains in its previous state, and remains usable.
@@ -192,7 +192,7 @@ builds the package from source, locally.
 @node Invoking guix-package
 @section Invoking @command{guix-package}
 
-The @command{guix-package} command it the tool that allows users to
+The @command{guix-package} command is the tool that allows users to
 install, upgrade, and remove packages, as well as rolling back to
 previous configurations.  It operates only on the user's own profile,
 and works with normal user privileges (@pxref{Features}).  Its syntax
@@ -202,7 +202,7 @@ is:
 guix-package @var{options}
 @end example
 
-Primarily, @var{options} specify the operations to be performed during
+Primarily, @var{options} specifies the operations to be performed during
 the transaction.  Upon completion, a new profile is created, but
 previous generations of the profile remain available, should the user
 want to roll back.
@@ -223,8 +223,8 @@ colon, followed by the name of one of the outputs of the package, as in
 @itemx -r @var{package}
 Remove @var{package}.
 
-@item --upgrade=@var{REGEXP}
-@itemx -u @var{REGEXP}
+@item --upgrade=@var{regexp}
+@itemx -u @var{regexp}
 Upgrade all the installed packages matching @var{regexp}.
 
 @item --profile=@var{profile}
@@ -235,6 +235,10 @@ Use @var{profile} instead of the user's default profile.
 @itemx -n
 Show what would be done without actually doing it.
 
+@item --verbose
+Produce verbose output.  In particular, emit the environment's build log
+on the standard error port.
+
 @item --bootstrap
 Use the bootstrap Guile to build the profile.  This option is only
 useful to distribution developers.
@@ -283,7 +287,7 @@ familiar packaging concepts, such as the name and version of a package,
 its build system, and its dependencies.  These definitions can then be
 turned into concrete build actions.
 
-Build actions are performed the Guix daemon, on behalf of users.  In a
+Build actions are performed by the Guix daemon, on behalf of users.  In a
 standard setup, the daemon has write access to the store---the
 @file{/nix/store} directory---whereas users do not.  The recommended
 setup also has the daemon perform builds in chroots, under a specific
@@ -369,7 +373,7 @@ object.
 Naturally, @var{gnu-build-system} represents the familiar GNU Build
 System, and variants thereof (@pxref{Configuration, configuration and
 makefile conventions,, standards, GNU Coding Standards}).  In a
-nutshell, packages using the GNU Build System may be configured, build,
+nutshell, packages using the GNU Build System may be configured, built,
 and installed with the usual @code{./configure && make && make check &&
 make install} command sequence.  This is what @var{gnu-build-system}
 does.
@@ -420,7 +424,7 @@ tool (@pxref{Invoking guix-build}).
 Behind the scenes, a derivation corresponding to the @code{<package>}
 object is first computed by the @code{package-derivation} procedure.
 That derivation is stored in a @code{.drv} file under @file{/nix/store}.
-The build actions is prescribes may then be realized by using the
+The build actions it prescribes may then be realized by using the
 @code{build-derivations} procedure (@pxref{The Store}).
 
 @deffn {Scheme Procedure} package-derivation @var{store} @var{package} [@var{system}]
diff --git a/guix-package.in b/guix-package.in
index dab58719c3..ff7f38383e 100644
--- a/guix-package.in
+++ b/guix-package.in
@@ -200,6 +200,8 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
   -n, --dry-run          show what would be done without actually doing it"))
   (display (_ "
   -b, --bootstrap        use the bootstrap Guile to build the profile"))
+  (display (_ "
+      --verbose          produce verbose output"))
   (newline)
   (display (_ "
   -I, --list-installed[=REGEXP]
@@ -242,6 +244,9 @@ Report bugs to: ~a.~%") "@PACKAGE_BUGREPORT@"))
         (option '(#\b "bootstrap") #f #f
                 (lambda (opt name arg result)
                   (alist-cons 'bootstrap? #t result)))
+        (option '("verbose") #f #f
+                (lambda (opt name arg result)
+                  (alist-cons 'verbose? #t result)))
         (option '(#\I "list-installed") #f #t
                 (lambda (opt name arg result)
                   (cons `(query list-installed ,(or arg ""))
@@ -321,6 +326,7 @@ Report bugs to: ~a.~%") "@PACKAGE_BUGREPORT@"))
   (define (process-actions opts)
     ;; Process any install/remove/upgrade action from OPTS.
     (let* ((dry-run? (assoc-ref opts 'dry-run?))
+           (verbose? (assoc-ref opts 'verbose?))
            (profile  (assoc-ref opts 'profile))
            (install  (filter-map (match-lambda
                                   (('install . (? store-path?))
@@ -359,10 +365,15 @@ Report bugs to: ~a.~%") "@PACKAGE_BUGREPORT@"))
                                   (_ #f))
                                  opts))
            (packages (append install*
-                             (fold alist-delete
-                                   (manifest-packages
-                                    (profile-manifest profile))
-                                   remove))))
+                             (fold (lambda (package result)
+                                     (match package
+                                       ((name _ ...)
+                                        (alist-delete name result))))
+                                   (fold alist-delete
+                                         (manifest-packages
+                                          (profile-manifest profile))
+                                         remove)
+                                   install*))))
 
       (show-what-to-build drv dry-run?)
 
@@ -370,16 +381,26 @@ Report bugs to: ~a.~%") "@PACKAGE_BUGREPORT@"))
           (and (build-derivations %store drv)
                (let* ((prof-drv (profile-derivation %store packages))
                       (prof     (derivation-path->output-path prof-drv))
+                      (old-drv  (profile-derivation
+                                 %store (manifest-packages
+                                         (profile-manifest profile))))
+                      (old-prof (derivation-path->output-path old-drv))
                       (number   (latest-profile-number profile))
                       (name     (format #f "~a/~a-~a-link"
                                         (dirname profile)
                                         (basename profile) (+ 1 number))))
-                 (and (build-derivations %store (list prof-drv))
-                      (begin
-                        (symlink prof name)
-                        (when (file-exists? profile)
-                          (delete-file profile))
-                        (symlink name profile))))))))
+                 (if (string=? old-prof prof)
+                     (format (current-error-port) (_ "nothing to be done~%"))
+                     (and (parameterize ((current-build-output-port
+                                          (if verbose?
+                                              (current-error-port)
+                                              (%make-void-port "w"))))
+                            (build-derivations %store (list prof-drv)))
+                          (begin
+                            (symlink prof name)
+                            (when (file-exists? profile)
+                              (delete-file profile))
+                            (symlink name profile)))))))))
 
   (define (process-query opts)
     ;; Process any query specified by OPTS.  Return #t when a query was
diff --git a/guix/derivations.scm b/guix/derivations.scm
index b1f54232bc..6fbce14da0 100644
--- a/guix/derivations.scm
+++ b/guix/derivations.scm
@@ -364,6 +364,15 @@ the derivation called NAME with hash HASH."
 store path and <derivation> object.  When HASH, HASH-ALGO, and HASH-MODE
 are given, a fixed-output derivation is created---i.e., one whose result is
 known in advance, such as a file download."
+  (define direct-store-path?
+    (let ((len (+ 1 (string-length (%store-prefix)))))
+      (lambda (p)
+        ;; Return #t if P is a store path, and not a sub-directory of a
+        ;; store path.  This predicate is needed because files *under* a
+        ;; store path are not valid inputs.
+        (and (store-path? p)
+             (not (string-index (substring p len) #\/))))))
+
   (define (add-output-paths drv)
     ;; Return DRV with an actual store path for each of its output and the
     ;; corresponding environment variable.
@@ -411,9 +420,9 @@ known in advance, such as a file download."
                                   (make-derivation-output "" hash-algo hash)))
                           outputs))
          (inputs     (map (match-lambda
-                           (((? store-path? input))
+                           (((? direct-store-path? input))
                             (make-derivation-input input '("out")))
-                           (((? store-path? input) sub-drvs ...)
+                           (((? direct-store-path? input) sub-drvs ...)
                             (make-derivation-input input sub-drvs))
                            ((input . _)
                             (let ((path (add-to-store store
diff --git a/guix/licenses.scm b/guix/licenses.scm
index 9c1b7249e1..cc2369bb8e 100644
--- a/guix/licenses.scm
+++ b/guix/licenses.scm
@@ -22,14 +22,15 @@
   #:export (license? license-name license-uri license-comment
             asl2.0
             boost1.0
-            bsd-2 bsd-3 bsd-4
+            bsd-2 bsd-3 bsd-4 bsd-style
             cddl1.0
             cpl1.0
             epl1.0
-            gpl2 gpl2+ gpl3 gpl3+
+            expat
+            gpl1 gpl1+ gpl2 gpl2+ gpl3 gpl3+
             ijg
             ibmpl1.0
-            lgpl2.1 lgpl2.1+ lgpl3 lgpl3+
+            lgpl2.0 lgpl2.0+ lgpl2.1 lgpl2.1+ lgpl3 lgpl3+
             mpl2.0
             openssl
             public-domain
@@ -78,6 +79,16 @@
            "http://directory.fsf.org/wiki/License:BSD_4Clause"
            "https://www.gnu.org/licenses/license-list#OriginalBSD"))
 
+(define* (bsd-style uri #:optional (comment ""))
+  "Return a BSD-style license, whose full text can be found at URI,
+which may be a file:// URI pointing the package's tree."
+  (license "BSD-style"
+           uri
+           (string-append
+            "This is a BSD-style, non-copyleft free software license.  "
+            "Check the URI for details.  "
+            comment)))
+
 (define cddl1.0
   (license "CDDL 1.0"
            "http://directory.fsf.org/wiki/License:CDDLv1.0"
@@ -93,6 +104,21 @@
            "http://directory.fsf.org/wiki/License:EPLv1.0"
            "https://www.gnu.org/licenses/license-list#EPL"))
 
+(define expat
+  (license "Expat"
+           "http://directory.fsf.org/wiki/License:Expat"
+           "https://www.gnu.org/licenses/license-list.html#Expat"))
+
+(define gpl1
+  (license "GPL 1"
+           "https://www.gnu.org/licenses/old-licenses/gpl-1.0.html"
+           #f))
+
+(define gpl1+
+  (license "GPL 1+"
+           "https://www.gnu.org/licenses/old-licenses/gpl-1.0.html"
+           #f))
+
 (define gpl2
   (license "GPL 2"
            "https://www.gnu.org/licenses/old-licenses/gpl-2.0.html"
@@ -123,6 +149,16 @@
            "http://directory.fsf.org/wiki/License:IBMPLv1.0"
            "https://www.gnu.org/licenses/license-list#IBMPL"))
 
+(define lgpl2.0
+  (license "LGPL 2.0"
+           "https://www.gnu.org/licenses/old-licenses/lgpl-2.0.html"
+           "https://www.gnu.org/licenses/why-not-lgpl.html"))
+
+(define lgpl2.0+
+  (license "LGPL 2.0+"
+           "https://www.gnu.org/licenses/old-licenses/lgpl-2.0.html"
+           "https://www.gnu.org/licenses/why-not-lgpl.html"))
+
 (define lgpl2.1
   (license "LGPL 2.1"
            "https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
diff --git a/guix/utils.scm b/guix/utils.scm
index 4089b11cb1..ad50c20cce 100644
--- a/guix/utils.scm
+++ b/guix/utils.scm
@@ -156,7 +156,15 @@ evaluate to a simple datum."
 (define %nixpkgs-directory
   (make-parameter
    ;; Capture the build-time value of $NIXPKGS.
-   (or %nixpkgs (getenv "NIXPKGS"))))
+   (or %nixpkgs
+       (and=> (getenv "NIXPKGS")
+              (lambda (val)
+                ;; Bail out when passed an empty string, otherwise
+                ;; `nix-instantiate' will sit there and attempt to read
+                ;; from its standard input.
+                (if (string=? val "")
+                    #f
+                    val))))))
 
 (define* (nixpkgs-derivation attribute #:optional (system (%current-system)))
   "Return the derivation path of ATTRIBUTE in Nixpkgs."
diff --git a/tests/guix-package.sh b/tests/guix-package.sh
index 598ea62aaa..60a0394f1c 100644
--- a/tests/guix-package.sh
+++ b/tests/guix-package.sh
@@ -25,11 +25,19 @@ guix-package --version
 profile="t-profile-$$"
 rm -f "$profile"
 
+trap 'rm "$profile" "$profile-"[0-9]*' EXIT
+
 guix-package -b -p "$profile"						\
     -i `guix-build -e '(@@ (distro packages base) %bootstrap-guile)'`
 test -L "$profile" && test -L "$profile-1-link"
 test -f "$profile/bin/guile"
 
+# Installing the same package a second time does nothing.
+guix-package -b -p "$profile"						\
+    -i `guix-build -e '(@@ (distro packages base) %bootstrap-guile)'`
+test -L "$profile" && test -L "$profile-1-link"
+! test -f "$profile-2-link"
+test -f "$profile/bin/guile"
 
 # Check whether we have network access.
 if guile -c '(getaddrinfo "www.gnu.org" "80" AI_NUMERICSERV)' 2> /dev/null
@@ -56,7 +64,7 @@ then
     test "`guix-package -p "$profile" -I 'g.*e' | cut -f1`" = "guile-bootstrap"
 
     # Remove a package.
-    guix-package -b -p "$profile" -r "guile-bootstrap-2.0"
+    guix-package -b -p "$profile" -r "guile-bootstrap"
     test -L "$profile-3-link"
     test -f "$profile/bin/make" && ! test -f "$profile/bin/guile"
 fi
@@ -67,4 +75,3 @@ guix-package -b -i "libsigsegv:lib" -n
 # Check whether `--list-available' returns something sensible.
 guix-package -A 'gui.*e' | grep guile
 
-rm "$profile" "$profile-"[0-9]*