guix-package: Gracefully handle multiple installs of the same path.
authorLudovic Courtès <ludo@gnu.org>
Tue, 11 Dec 2012 23:01:17 +0000 (00:01 +0100)
committerLudovic Courtès <ludo@gnu.org>
Tue, 11 Dec 2012 23:01:17 +0000 (00:01 +0100)
* guix-package.in (guix-package)[process-actions]: Compute PACKAGES such
  that packages listed in INSTALL* are first removed from the remainder
  of the list.  When PROF is equal to the previous profile's store path,
  do nothing.  Reported by Andreas Enge <andreas@enge.fr>.
* tests/guix-package.sh: Test the behavior of installing the same store
  path twice.  When removing a package, omit its version number.

guix-package.in
tests/guix-package.sh

index dab5871..7bc32f8 100644 (file)
@@ -359,10 +359,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 +375,22 @@ 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 (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
index 2bc8c57..8310860 100644 (file)
@@ -30,6 +30,12 @@ guix-package -b -p "$profile"                                                \
 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"
 
 guix-package -b -p "$profile"                                          \
     -i `guix-build -e '(@@ (distro packages base) gnu-make-boot0)'`
@@ -53,7 +59,7 @@ esac
 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"