From mboxrd@z Thu Jan 1 00:00:00 1970 From: Nikita Karetnikov Subject: Re: guix-package --roll-back Date: Wed, 16 Jan 2013 16:34:42 -0500 Message-ID: <87622whkvn.fsf@karetnikov.org> References: <871uejyq9z.fsf@karetnikov.org> <874nj4sbfe.fsf@karetnikov.org> <87y5gf8sm1.fsf@gnu.org> <87hamy4yaj.fsf@karetnikov.org> <87pq1m5nxy.fsf@gnu.org> <87obh43j7r.fsf@karetnikov.org> <87vcbbqvw1.fsf@gnu.org> <87fw2ai3e1.fsf@karetnikov.org> <8738y8ekst.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/signed; boundary="==-=-="; micalg=pgp-sha1; protocol="application/pgp-signature" Return-path: Received: from eggs.gnu.org ([208.118.235.92]:57366) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tvad8-0003fz-Hy for bug-guix@gnu.org; Wed, 16 Jan 2013 16:34:45 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Tvad5-0001c6-D7 for bug-guix@gnu.org; Wed, 16 Jan 2013 16:34:42 -0500 In-Reply-To: <8738y8ekst.fsf@gnu.org> ("Ludovic =?utf-8?Q?Court=C3=A8s=22'?= =?utf-8?Q?s?= message of "(unknown date)") List-Id: Bug reports for GNU Guix List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guix-bounces+gcggb-bug-guix=m.gmane.org@gnu.org Sender: bug-guix-bounces+gcggb-bug-guix=m.gmane.org@gnu.org To: Ludovic =?utf-8?Q?Court=C3=A8s?= Cc: bug-guix@gnu.org --==-=-= Content-Type: multipart/mixed; boundary="=-=-=" --=-=-= Hi, I changed 'roll-back', but didn't add the command-line option. Could you add it? Why do these lines raise the "non-literal format string" warning? + (format (current-error-port) + "error: '~a' is not a valid profile~%" + profile) Also, is it possible to remove nested if statements? + (if (= number 0) + (format (current-error-port) + "error: '~a' is not a valid profile~%" + profile) + (if (file-exists? previous-profile) + (switch-link) + (format (current-error-port) + (string-append "error: previous profile doesn't exist; " + "not rolling back~%")))))) > I think it works even if PROFILE is not an absolute file name, no? Maybe I misunderstood, but the following doesn't work. scheme@(guile-user)> (define %current-profile "/nix/var/nix/profiles/per-user/root/guix-profile") scheme@(guile-user)> (profile-number %current-profile) $1 = 1 scheme@(guile-user)> (profile-number (basename %current-profile)) $2 = 0 Nikita --=-=-= Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename=guix-package.diff Content-Transfer-Encoding: quoted-printable =2D-- guix-package-orig 2013-01-16 20:56:13.000000000 +0000 +++ guix-package 2013-01-16 21:05:09.000000000 +0000 @@ -13,6 +13,7 @@ !# ;;; GNU Guix --- Functional package management for GNU ;;; Copyright =C2=A9 2012, 2013 Ludovic Court=C3=A8s +;;; Copyright =C2=A9 2013 Nikita Karetnikov ;;; ;;; This file is part of GNU Guix. ;;; @@ -89,13 +90,14 @@ (_ (error "unsupported manifest format" manifest)))) =20 +(define (profile-regexp profile) + "Return a regular expression that matches PROFILE's name and number." + (make-regexp (string-append "^" (regexp-quote (basename profile)) + "-([0-9]+)"))) + (define (latest-profile-number profile) "Return the identifying number of the latest generation of PROFILE. PROFILE is the name of the symlink to the current generation." =2D (define %profile-rx =2D (make-regexp (string-append "^" (regexp-quote (basename profile)) =2D "-([0-9]+)"))) =2D (define* (scandir name #:optional (select? (const #t)) (entry)) + (cut regexp-exec (profile-regexp profile) <>)) (#f ; no profile directory 0) (() ; no profiles 0) ((profiles ...) ; former profiles around =2D (let ((numbers (map (compose string->number =2D (cut match:substring <> 1) =2D (cut regexp-exec %profile-rx <>)) =2D profiles))) + (let ((numbers + (map (compose string->number + (cut match:substring <> 1) + (cut regexp-exec (profile-regexp profile) <>)) + profiles))) (fold (lambda (number highest) (if (> number highest) number @@ -179,6 +182,41 @@ packages) #:modules '((guix build union)))) =20 +(define (profile-number profile) + "Return PROFILE's number or 0. An absolute file name must be used." + (or (and=3D> (false-if-exception (regexp-exec (profile-regexp profile) + (basename (readlink profile)= ))) + (compose string->number (cut match:substring <> 1))) + 0)) + +(define (roll-back profile) + "Roll back to the previous generation of PROFILE." + (let* ((number (profile-number profile)) + (previous-number (1- number)) + (previous-profile + (string-append profile "-" (number->string previous-number) "-li= nk")) + (manifest (string-append previous-profile "/manifest"))) + + (define (switch-link) + (let ((tmp-profile (string-append (dirname profile) + "/tmp-" + (basename previous-profile)))) + + (format #t "switching from generation ~a to ~a~%" + number previous-number) + (symlink previous-profile tmp-profile) + (rename-file tmp-profile profile))) + + (if (=3D number 0) + (format (current-error-port) + "error: '~a' is not a valid profile~%" + profile) + (if (file-exists? previous-profile) + (switch-link) + (format (current-error-port) + (string-append "error: previous profile doesn't exist;= " + "not rolling back~%")))))) + ;;; ;;; Command-line options. @@ -203,6 +241,8 @@ (display (_ " -n, --dry-run show what would be done without actually doing it= ")) (display (_ " + --roll-back roll back to the previous generation")) + (display (_ " --bootstrap use the bootstrap Guile to build the profile")) (display (_ " --verbose produce verbose output")) @@ -237,6 +277,9 @@ (option '(#\r "remove") #t #f (lambda (opt name arg result) (alist-cons 'remove arg result))) + ;; (option '("roll-back") #f #f + ;; (lambda (opt name arg result) + ;; (alist-cons 'roll-back arg result))) (option '(#\p "profile") #t #f (lambda (opt name arg result) (alist-cons 'profile arg --=-=-=-- --==-=-= Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iQIcBAEBAgAGBQJQ9x0QAAoJEM+IQzI9IQ3853AP/iJPpX6DKyA8jVDlmy0ijQin w5f0eqAE6zBoLBfoJMqsghUtAe2A+/122h/6R/Cp1qrSH61l+9KtEDuP2GknP9+W w3h00aFsDBXlIbVpVAU3JJ8juO5EJwUzrX2Frea4SmrZvb5Vs3sE/1oVbdtkgY6b VbIA86ayIdlR39lCaG1bfbN7UxArTCOFZVuW81IEiO/E7M/D82teZkj9bIKNsKrW vIxRl74HezcW1GNV0M7PJS4zjPpe5l6oUPi6hzBwcGhT2NB6ucN6jfuod+Zb2dl0 YyYWKKuFPc7msEPv+AQGeVOne724FZswu9U8N40WxHaCAv6k+rU1w2Sc61b/VQIk Il+2LsCiW6bDRKjNLcWdgdMzLXgOwjGVu1JRU5vBw/2QiQjp6dtM7cwA7QruWs+I Hx0LtFhYjlTW9rCvTBB6BoK0vsPNfOxdfHSaGrqTpviCAneU8EBrW6uT5LGPb8pQ OSaD+gxqcpFX+1il+ynec5YTWsWAt+XR7dFSlBzISHRHW4mtYkge/xWbntT9E1bh zDpRuopZu3OpPUtsCKS1xAIX3DmfxUzvHjPSy7PKIX3QdBOIrXwQc4VnKXA91qx5 M1+E9G6xafv6Iv5aZdiSADxKe19mEOUMMJVE3j08iYniCIVX4ugLj2GmvdVGcmTL ZsBWTBLq8mKYAgNrakY0 =lZUr -----END PGP SIGNATURE----- --==-=-=--