From: Alex Kost <alezost@gmail.com>
To: guix-devel@gnu.org
Subject: [PATCH] guix package: Add '--switch-generation' option.
Date: Mon, 06 Oct 2014 18:14:53 +0400 [thread overview]
Message-ID: <8738b1jndu.fsf_-_@gmail.com> (raw)
In-Reply-To: <87eguninyx.fsf@gnu.org> ("Ludovic \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\= \=\?utf-8\?Q\?s\?\= message of "Sat, 04 Oct 2014 22:23:02 +0200")
[-- Attachment #1: Type: text/plain, Size: 1682 bytes --]
Ludovic Courtès (2014-10-05 00:23 +0400) wrote:
> Alex Kost <alezost@gmail.com> skribis:>
[...]
>> - (Not related to this patch, but still …) Currently with “roll-back”,
>> we can only switch to the previous generation. What about adding a
>> possibility to switch to any generation? So that we could use
>> something like this:
>>
>> guix package --switch-generation=7
>>
>> Also such functionality can be added to Emacs UI: for example pressing
>> "C" on a generation in *Guix Generation List* will make this
>> generation the current one.
>>
>> So ‘roll-back’ procedure may become a special case of the
>> ‘switch-generation’ one. WDYT?
>
> I think it’s a good idea! (I think it was suggested in earlier
> discussions, but never implemented.)
Andreas Enge (2014-10-05 18:44 +0400) wrote:
[...]
> Actually, sometimes I would like to switch to the next generation ("-roll-
> forward", in a sense): I install something, go back with "--roll-back",
> and might like to go just one forward again.
>
> So how about the following:
> --switch-generation=1
> goes to generation 1;
> --switch-generation=-1
> goes 1 generation back;
> --switch-generation=+1
> goes one generation forward.
Thanks for the great idea!
————————————————————————————————————————————————————————————————
A patch is attached. Some comments:
- ‘shitted-generation’ is not a very good name, I think. Ideas?
- ‘previous-generation-number’ may use ‘shifted-generation’ now:
[-- Attachment #2: sample.scm --]
[-- Type: text/plain, Size: 389 bytes --]
(define* (previous-generation-number profile #:optional
(number (generation-number profile)))
"Return the number of the generation before generation NUMBER of
PROFILE, or 0 if none exists. It could be NUMBER - 1, but it's not the
case when generations have been deleted (there are \"holes\")."
(or (shifted-generation profile -1 number)
0))
[-- Attachment #3: Type: text/plain, Size: 591 bytes --]
Worth changing?
- Perhaps it would be better to make 2 commits (?): one for adding
‘shifted-generation’ and ‘switch-to-generation’ procedures to (guix
profiles) and another is for adding the “--switch-generation” option
itself.
- Also I made a couple of cosmetic changes in “guix/scripts/package.scm”:
* ‘filter-map’ was replaced by 'for-each' because it was called only for
side effects there;
* ‘begin’ was removed from ‘cond’.
I think these changes do not deserve a separate commit and may stay in
this patch. Is it OK?
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0001-guix-package-Add-switch-generation-option.patch --]
[-- Type: text/x-diff, Size: 7887 bytes --]
From 3cc52d1aade5e9723c38c0af5fa4437cbdf1a9b6 Mon Sep 17 00:00:00 2001
From: Alex Kost <alezost@gmail.com>
Date: Mon, 6 Oct 2014 17:35:51 +0400
Subject: [PATCH] guix package: Add '--switch-generation' option.
* doc/guix.texi (Invoking guix package): Update documentation.
* guix/profiles.scm (shifted-generation, switch-to-generation): New
procedures.
* guix/scripts/package.scm: Add '--switch-generation' option.
(switch-to-previous-generation): Use 'switch-to-generation'.
---
doc/guix.texi | 15 +++++++++++++++
guix/profiles.scm | 36 +++++++++++++++++++++++++++++++++++-
guix/scripts/package.scm | 44 +++++++++++++++++++++++++++++++++-----------
3 files changed, 83 insertions(+), 12 deletions(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index f6357bd..c6921b1 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -784,6 +784,21 @@ Installing, removing, or upgrading packages from a generation that has
been rolled back to overwrites previous future generations. Thus, the
history of a profile's generations is always linear.
+@item --switch-generation=@var{pattern}
+@itemx -S @var{pattern}
+Switch to a particular generation defined by @var{pattern}.
+
+@var{pattern} may be either a generation number or a number prefixed
+with ``+'' or ``-''. The latter means: move forward/backward by a
+specified number of generations. For example, if you want to return to
+the latest generation after @code{--roll-back}, use
+@code{--switch-generation=+1}.
+
+The difference between @code{--roll-back} and
+@code{--switch-generation=-1} is that @code{--switch-generation} will
+not make a zeroth generation, so if a specified generation does not
+exist, the current generation will not be changed.
+
@item --search-paths
@cindex search paths
Report environment variable definitions, in Bash syntax, that may be
diff --git a/guix/profiles.scm b/guix/profiles.scm
index 18733a6..589402e 100644
--- a/guix/profiles.scm
+++ b/guix/profiles.scm
@@ -71,9 +71,11 @@
generation-number
generation-numbers
profile-generations
+ shifted-generation
previous-generation-number
generation-time
- generation-file-name))
+ generation-file-name
+ switch-to-generation))
;;; Commentary:
;;;
@@ -569,6 +571,21 @@ former profiles were found."
'()
generations)))
+(define* (shifted-generation profile shift
+ #:optional (current (generation-number profile)))
+ "Return PROFILE's generation shifted from the CURRENT generation by SHIFT.
+SHIFT is a positive or negative number.
+Return #f if there is no such generation."
+ (let* ((abs-shift (abs shift))
+ (numbers (profile-generations profile))
+ (from-current (memq current
+ (if (negative? shift)
+ (reverse numbers)
+ numbers))))
+ (and from-current
+ (< abs-shift (length from-current))
+ (list-ref from-current abs-shift))))
+
(define (previous-generation-number profile number)
"Return the number of the generation before generation NUMBER of
PROFILE, or 0 if none exists. It could be NUMBER - 1, but it's not the
@@ -589,4 +606,21 @@ case when generations have been deleted (there are \"holes\")."
(make-time time-utc 0
(stat:ctime (stat (generation-file-name profile number)))))
+(define (switch-to-generation profile number)
+ "Atomically switch PROFILE to the generation NUMBER."
+ (let ((current (generation-number profile))
+ (file (generation-file-name profile number)))
+ (cond ((not (file-exists? profile))
+ (format (current-error-port)
+ (_ "profile '~a' does not exist~%")
+ profile))
+ ((not (file-exists? file))
+ (format (current-error-port)
+ (_ "generation ~a does not exist~%")
+ number))
+ (else
+ (format #t (_ "switching from generation ~a to ~a~%")
+ current number)
+ (switch-symlinks profile file)))))
+
;;; profiles.scm ends here
diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm
index fc9c37b..b071029 100644
--- a/guix/scripts/package.scm
+++ b/guix/scripts/package.scm
@@ -96,12 +96,9 @@ return PROFILE unchanged. The goal is to treat '-p ~/.guix-profile' as if
(define (switch-to-previous-generation profile)
"Atomically switch PROFILE to the previous generation."
- (let* ((number (generation-number profile))
- (previous-number (previous-generation-number profile number))
- (previous-generation (generation-file-name profile previous-number)))
- (format #t (_ "switching from generation ~a to ~a~%")
- number previous-number)
- (switch-symlinks profile previous-generation)))
+ (let* ((current (generation-number profile))
+ (previous (previous-generation-number profile current)))
+ (switch-to-generation profile previous)))
(define (roll-back store profile)
"Roll back to the previous generation of PROFILE."
@@ -409,6 +406,9 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
-d, --delete-generations[=PATTERN]
delete generations matching PATTERN"))
(display (_ "
+ -S, --switch-generation=PATTERN
+ switch to a generation matching PATTERN"))
+ (display (_ "
-p, --profile=PROFILE use PROFILE instead of the user's default profile"))
(newline)
(display (_ "
@@ -488,6 +488,10 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
(values (alist-cons 'delete-generations (or arg "")
result)
#f)))
+ (option '(#\S "switch-generation") #t #f
+ (lambda (opt name arg result arg-handler)
+ (values (alist-cons 'switch-generation arg result)
+ #f)))
(option '("search-paths") #f #f
(lambda (opt name arg result arg-handler)
(values (cons `(query search-paths) result)
@@ -713,13 +717,31 @@ more information.~%"))
(generation-number profile))
;; First roll back if asked to.
- (cond ((and (assoc-ref opts 'roll-back?) (not dry-run?))
- (begin
- (roll-back (%store) profile)
- (process-actions (alist-delete 'roll-back? opts))))
+ (cond ((and (assoc-ref opts 'roll-back?)
+ (not dry-run?))
+ (roll-back (%store) profile)
+ (process-actions (alist-delete 'roll-back? opts)))
+ ((and (assoc-ref opts 'switch-generation)
+ (not dry-run?))
+ (for-each
+ (match-lambda
+ (('switch-generation . pattern)
+ (let* ((number (string->number pattern))
+ (number (and number
+ (case (string-ref pattern 0)
+ ((#\+ #\-)
+ (shifted-generation profile number))
+ (else number)))))
+ (if number
+ (switch-to-generation profile number)
+ (format (current-error-port)
+ "Cannot switch to generation '~a'~%" pattern)))
+ (process-actions (alist-delete 'switch-generation opts)))
+ (_ #f))
+ opts))
((and (assoc-ref opts 'delete-generations)
(not dry-run?))
- (filter-map
+ (for-each
(match-lambda
(('delete-generations . pattern)
(cond ((not (file-exists? profile)) ; XXX: race condition
--
2.1.2
[-- Attachment #5: Type: text/plain, Size: 18 bytes --]
--
Thanks,
Alex
next prev parent reply other threads:[~2014-10-06 14:15 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-25 17:58 Emacs interface for Guix Alex Kost
2014-07-25 20:36 ` Ludovic Courtès
2014-07-26 17:44 ` Alex Kost
2014-07-28 10:15 ` Alex Kost
2014-08-11 20:54 ` Ludovic Courtès
2014-08-12 10:19 ` [PATCH] " Alex Kost
2014-08-12 14:19 ` Ludovic Courtès
2014-08-12 16:20 ` Alex Kost
2014-08-12 19:50 ` Ludovic Courtès
2014-08-13 6:57 ` Alex Kost
2014-08-13 16:03 ` Ludovic Courtès
2014-08-13 20:58 ` Alex Kost
2014-08-15 5:51 ` Alex Kost
2014-08-16 9:27 ` Ludovic Courtès
2014-08-16 10:52 ` [PATCH] manifest-transaction Alex Kost
2014-08-20 12:10 ` [PATCH] profiles: Report about upgrades Alex Kost
2014-08-23 11:58 ` Ludovic Courtès
2014-08-30 19:56 ` Ludovic Courtès
2014-08-31 6:04 ` Alex Kost
2014-08-31 19:57 ` Ludovic Courtès
2014-08-31 22:54 ` Jason Self
2014-09-01 7:13 ` Alex Kost
2014-09-02 19:45 ` Ludovic Courtès
[not found] ` <87egvrke1z.fsf@gmail.com>
2014-09-04 19:37 ` Ludovic Courtès
2014-08-16 12:24 ` [PATCH] Emacs interface for Guix Ludovic Courtès
2014-08-16 13:07 ` Alex Kost
2014-08-19 21:00 ` Ludovic Courtès
2014-08-20 10:54 ` Alex Kost
2014-08-22 8:56 ` Ludovic Courtès
2014-08-22 12:44 ` Alex Kost
2014-08-27 8:34 ` Ludovic Courtès
2014-10-04 17:59 ` [PATCH] guix package: Export generation procedures Alex Kost
2014-10-04 20:23 ` Ludovic Courtès
2014-10-05 8:54 ` [PATCH] emacs: Add support for deleting generations Alex Kost
2014-10-05 13:14 ` Ludovic Courtès
2014-10-05 18:23 ` Alex Kost
2014-10-05 19:20 ` Ludovic Courtès
2014-10-05 20:04 ` Alex Kost
2014-10-06 7:36 ` Ludovic Courtès
2014-10-06 14:14 ` Alex Kost [this message]
2014-10-06 19:27 ` [PATCH] guix package: Add '--switch-generation' option Ludovic Courtès
2014-10-07 10:04 ` Alex Kost
2014-10-07 16:00 ` Ludovic Courtès
2014-10-07 21:32 ` Alex Kost
2014-10-08 9:44 ` Ludovic Courtès
2014-10-05 14:44 ` [PATCH] guix package: Export generation procedures Andreas Enge
2014-10-05 19:21 ` Ludovic Courtès
2014-07-26 20:58 ` Emacs interface for Guix 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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8738b1jndu.fsf_-_@gmail.com \
--to=alezost@gmail.com \
--cc=guix-devel@gnu.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 external index
https://git.savannah.gnu.org/cgit/guix.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.