From: ludo@gnu.org (Ludovic Courtès)
To: Nikita Karetnikov <nikita@karetnikov.org>
Cc: bug-guix@gnu.org
Subject: Re: guix-package --roll-back
Date: Thu, 10 Jan 2013 23:26:58 +0100 [thread overview]
Message-ID: <8738y8ekst.fsf@gnu.org> (raw)
In-Reply-To: <87fw2ai3e1.fsf@karetnikov.org> (Nikita Karetnikov's message of "Wed, 09 Jan 2013 14:04:37 -0500")
Hi,
Nikita Karetnikov <nikita@karetnikov.org> skribis:
> I'm attaching a slightly modified version.
Thanks!
>> Yeah, that’s expected. Basically, if you do
>
>> guix-package -p /dev/null --roll-back
>
>> it should fail with an error message saying that there is no previous
>> profile or something like that.
>
> 'profile-number' will fail if I call it with a bogus file name.
>
> For instance:
>
> scheme@(guile-user)> (profile-number "/foo/bar")
> ERROR: In procedure readlink:
> ERROR: In procedure readlink: No such file or directory
>
> What should I use to handle this error? Please show an example. The
> ones from the manual aren't helpful.
At the command-line level, an example would be:
$ guix-package -p /dev/null --roll-back ; echo $?
error: no previous profile to roll back to
1
(Please, add this example to tests/guix-package.sh.)
Internally, I would expect this ‘profile-number’ to return #f.
> I don't understand how to add a command-line option that should accept
> an optional argument. I commented out my attempts.
(option '("foo")
#f ; no required argument
#t ; an optional argument
(lambda (opt name arg result)
;; Function called when ‘--foo’ is passed.
;; ARG is #f or the optional argument.
;; ...
))
See SRFI-37 in Guile’s manual.
> +(define (profile-rx profile)
Perhaps ‘profile-regexp’ (since it’s a global variable.)
> +(define (profile-number profile)
> + "Return PROFILE's number. An absolute file name must be used."
I think it works even if PROFILE is not an absolute file name, no?
Just like ‘latest-profile-number’ returns 0 if there was no file
matching %PROFILE-RX, ‘profile-number’ should return 0.
So you’d want to enclose the whole body like this:
(or (and=> ...) 0)
> + (and=> (regexp-exec (profile-rx profile)
> + (basename (readlink profile)))
> + (cut match:substring <> 1)))
First, you need to move ‘readlink’ above, in ‘false-if-exception’.
Second, it should return a number, not a string.
So the result should be along these lines:
(let ((target (false-if-exception (readlink profile))))
(and target
(and=> (regexp-exec (profile-regexp profile) (basename target))
(compose string->number (cut match:substring <> 1))
> +(define* (roll-back #:optional profile)
Make ‘profile’ mandatory.
> + "Roll back to the previous profile."
Rather: “Roll back to the previous generation of PROFILE.”
> + (let* ((current-profile-number
> + (string->number (profile-number (or profile %current-profile))))
The ‘or’ and ‘string->number’ can now be removed.
Name the variable just ‘number’, because long names for local vars
hinder clarity.
Now you need to introduce an
(if number
;; then do the thing
(format (current-error-port) (_ "error: ‘~a’ is not a valid profile~%")
profile))
> + (previous-profile-number (number->string (1- current-profile-number)))
> + (previous-profile
> + (string-append (or profile %current-profile) "-"
> + previous-profile-number "-link"))
> + (manifest (string-append previous-profile "/manifest")))
> +
> + (define (switch-link)
> + ;; Switch to the previous generation.
> + (let ((tmp-profile (string-append (dirname (or profile %current-profile))
> + "/tmp-"
> + (basename previous-profile))))
> +
> + (simple-format #t "guix-package: switching from generation ~a to ~a~%"
> + current-profile-number previous-profile-number)
> + (symlink previous-profile tmp-profile)
> + (rename-file tmp-profile (or profile %current-profile))))
Looks good.
However, just use ‘format’, and also make sure that messages and i18n’d:
(format #t (_ "switching from generation ~a to ~a...~%")
number previous-number)
> + (if (equal? (map (cut file-exists? <>)
> + (list previous-profile manifest))
> + '(#t #t))
I think you just need to check for ‘previous-profile’. If it turns out
not to be a genuine profile, that’s not our problem.
Besides, this is a mundane (and inefficient) way of writing:
(every file-exists? (list previous-profile manifest))
or simply:
(and (file-exists? previous-profile)
(file-exists? manifest))
:-)
> + (switch-link)
> + (leave (_ (string-append
> + "guix-package: previous profile doesn't exist; "
> + "not rolling back~%"))))))
Strip “guix-package: ”.
Woow, this was long.
Thanks,
Ludo’.
next prev parent reply other threads:[~2013-01-10 22:27 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-21 22:49 guix-package --roll-back Nikita Karetnikov
2012-12-29 23:09 ` Nikita Karetnikov
2012-12-29 23:13 ` Andreas Enge
2012-12-30 15:30 ` Ludovic Courtès
2013-01-01 13:57 ` Nikita Karetnikov
2013-01-01 22:58 ` Ludovic Courtès
2013-01-03 5:42 ` Nikita Karetnikov
2013-01-03 14:41 ` Ludovic Courtès
2013-01-04 18:18 ` Nikita Karetnikov
2013-01-05 19:20 ` Ludovic Courtès
2013-01-09 19:04 ` Nikita Karetnikov
2013-01-10 15:01 ` Nikita Karetnikov
2013-01-10 22:26 ` Ludovic Courtès [this message]
2013-01-11 5:48 ` Nikita Karetnikov
2013-01-11 13:39 ` Ludovic Courtès
2013-01-12 21:03 ` Nikita Karetnikov
2013-01-13 20:40 ` Ludovic Courtès
2013-01-16 21:34 ` Nikita Karetnikov
2013-01-17 21:47 ` Ludovic Courtès
2013-01-21 5:50 ` Nikita Karetnikov
2013-01-22 21:37 ` Ludovic Courtès
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://guix.gnu.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8738y8ekst.fsf@gnu.org \
--to=ludo@gnu.org \
--cc=bug-guix@gnu.org \
--cc=nikita@karetnikov.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/guix.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).