* Emacs interface for Guix @ 2014-07-16 5:59 Alex Kost 2014-07-16 14:18 ` Ludovic Courtès 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-07-16 5:59 UTC (permalink / raw) To: guix-devel Hello, I'm working on Emacs UI for Guix and I have pushed something that can be tried. Currently there is no interacting with Guix daemon so such actions as deleting, installing,... are not supported yet. But it is possible to search for and show info about packages. Important: Geiser is required; and the first start of the REPL may take a long time. The source: https://github.com/alezost/guix.el Also if anyone is interested, I appreciate any help with the scheme code. I need a function returning a list of installed packages, and a function "package-installed?". Questions and comments are welcome. Sorry if this list is not an appropriate place for this announcement. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-16 5:59 Emacs interface for Guix Alex Kost @ 2014-07-16 14:18 ` Ludovic Courtès 2014-07-16 19:05 ` Alex Kost 0 siblings, 1 reply; 29+ messages in thread From: Ludovic Courtès @ 2014-07-16 14:18 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Hi! Alex Kost <alezost@gmail.com> skribis: > I'm working on Emacs UI for Guix and I have pushed something that > can be tried. Currently there is no interacting with Guix daemon so > such actions as deleting, installing,... are not supported yet. But it > is possible to search for and show info about packages. Just tried it, and it works great! > Important: Geiser is required; and the first start of the REPL may take a > long time. That’s because it’s rebuilding most of the modules, AFAICS. Perhaps ‘geiser-guile-load-path’ needs to be augmented to avoid that? > Also if anyone is interested, I appreciate any help with the scheme > code. I need a function returning a list of installed packages, and a > function "package-installed?". There’s ‘manifest-installed?’ in (guix profiles): --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> ,use(guix profiles) scheme@(guile-user)> (define m (call-with-input-file "/home/ludo/.guix-profile/manifest" read-manifest)) scheme@(guile-user)> (manifest-installed? m (manifest-pattern (name "emacs"))) $3 = #t --8<---------------cut here---------------end--------------->8--- See tests/profiles.scm for more examples. > Sorry if this list is not an appropriate place for this announcement. It’s definitely appropriate. :-) Thanks! Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-16 14:18 ` Ludovic Courtès @ 2014-07-16 19:05 ` Alex Kost 2014-07-18 9:16 ` Ludovic Courtès 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-07-16 19:05 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel Ludovic Courtès (2014-07-16 18:18 +0400) wrote: > Hi! > > Alex Kost <alezost@gmail.com> skribis: > >> I'm working on Emacs UI for Guix and I have pushed something that >> can be tried. Currently there is no interacting with Guix daemon so >> such actions as deleting, installing,... are not supported yet. But it >> is possible to search for and show info about packages. > > Just tried it, and it works great! > >> Important: Geiser is required; and the first start of the REPL may take a >> long time. > > That’s because it’s rebuilding most of the modules, AFAICS. Perhaps > ‘geiser-guile-load-path’ needs to be augmented to avoid that? Do you mean some guix directories should be added to that var? But how to know the paths before starting guile? Can't the default paths be changed during "./conigure"-ing? Actually I think it's not a problem as auto-compiling of all needed modules takes place only in the first start, besides it may be disabled: (setq guix-guile-program '("guile" "--no-auto-compile")) >> Also if anyone is interested, I appreciate any help with the scheme >> code. I need a function returning a list of installed packages, and a >> function "package-installed?". > > There’s ‘manifest-installed?’ in (guix profiles): > > scheme@(guile-user)> ,use(guix profiles) > scheme@(guile-user)> (define m (call-with-input-file "/home/ludo/.guix-profile/manifest" read-manifest)) > scheme@(guile-user)> (manifest-installed? m (manifest-pattern (name "emacs"))) > $3 = #t > > See tests/profiles.scm for more examples. Yes, this helps a lot, thank you! Now I can move further. -- Alex ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-16 19:05 ` Alex Kost @ 2014-07-18 9:16 ` Ludovic Courtès 2014-07-19 7:51 ` Alex Kost 0 siblings, 1 reply; 29+ messages in thread From: Ludovic Courtès @ 2014-07-18 9:16 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Alex Kost <alezost@gmail.com> skribis: > Ludovic Courtès (2014-07-16 18:18 +0400) wrote: [...] >> That’s because it’s rebuilding most of the modules, AFAICS. Perhaps >> ‘geiser-guile-load-path’ needs to be augmented to avoid that? > > Do you mean some guix directories should be added to that var? Yes. > But how to know the paths before starting guile? Can't the default > paths be changed during "./conigure"-ing? Right. Actually I think eventually (i.e., soon ;-)) we should add guix.el to the Guix repo. Among other things, that means that the Scheme code for guix.el can be easily kept in sync with the (guix ...) API, which is more difficult otherwise. Once guix.el is in the repo, we can use substitutions as for guix/config.scm to get the right directory names. In addition, note that ‘guix pull’ populates ~/.config/guix/latest, so this should come first in the search path (see scripts/guix.in on how it fiddles with search path.) WDYT? Thanks, Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-18 9:16 ` Ludovic Courtès @ 2014-07-19 7:51 ` Alex Kost 2014-07-19 16:28 ` Ludovic Courtès 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-07-19 7:51 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel Ludovic Courtès (2014-07-18 13:16 +0400) wrote: > Alex Kost <alezost@gmail.com> skribis: > >> Ludovic Courtès (2014-07-16 18:18 +0400) wrote: > > [...] > >>> That’s because it’s rebuilding most of the modules, AFAICS. Perhaps >>> ‘geiser-guile-load-path’ needs to be augmented to avoid that? >> >> Do you mean some guix directories should be added to that var? > > Yes. > >> But how to know the paths before starting guile? Can't the default >> paths be changed during "./conigure"-ing? > > Right. > > Actually I think eventually (i.e., soon ;-)) we should add guix.el to > the Guix repo. Among other things, that means that the Scheme code for > guix.el can be easily kept in sync with the (guix ...) API, which is > more difficult otherwise. It would be great! I think the main features should be finished soon: now I'm adding support for displaying info about installed outputs, and then only implementing actions (installing/deleting) will be left. > Once guix.el is in the repo, we can use substitutions as for > guix/config.scm to get the right directory names. > > In addition, note that ‘guix pull’ populates ~/.config/guix/latest, so > this should come first in the search path (see scripts/guix.in on how it > fiddles with search path.) > > WDYT? Thanks, I finally realized why the paths should be augmented (I'm getting experience with guix during working on guix.el :)). Also I have a question: is there such thing as “obsolete package”? AFAIU after ‘guix pull’, a user can still have old versions of packages installed that don't exist in the new guix anymore. I.e. after that some packages from the current manifest cannot be found with ‘(find-packages-by-name "foo" "<old-version>")’. Am I right? > Thanks, > Ludo’. -- Alex ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-19 7:51 ` Alex Kost @ 2014-07-19 16:28 ` Ludovic Courtès 2014-07-20 7:10 ` Alex Kost 0 siblings, 1 reply; 29+ messages in thread From: Ludovic Courtès @ 2014-07-19 16:28 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Alex Kost <alezost@gmail.com> skribis: > Ludovic Courtès (2014-07-18 13:16 +0400) wrote: [...] >> Actually I think eventually (i.e., soon ;-)) we should add guix.el to >> the Guix repo. Among other things, that means that the Scheme code for >> guix.el can be easily kept in sync with the (guix ...) API, which is >> more difficult otherwise. > > It would be great! I think the main features should be finished soon: > now I'm adding support for displaying info about installed outputs, and > then only implementing actions (installing/deleting) will be left. Excellent. We can discuss the details of integration once 0.7 is out. > Also I have a question: is there such thing as “obsolete package”? > AFAIU after ‘guix pull’, a user can still have old versions of packages > installed that don't exist in the new guix anymore. I.e. after that > some packages from the current manifest cannot be found with > ‘(find-packages-by-name "foo" "<old-version>")’. Am I right? Yes. Thus, for such packages, the UI would be unable to display the details. Actually, more generally, there is little meta-data about installed packages, compared to available packages. The UI can assume that an installed package called ‘guile-2.0.11’ is probably the same as an available package with the same name and version, but that’s not necessarily the case. It’s possible to check whether they really are the same by computing the derivation of the available package and comparing its output directory names to those of the installed package. So ideally the UI would show a little warning when it knows it doesn’t match. (Am I clear?) Thanks, Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-19 16:28 ` Ludovic Courtès @ 2014-07-20 7:10 ` Alex Kost 2014-07-20 14:08 ` Ludovic Courtès 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-07-20 7:10 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel Ludovic Courtès (2014-07-19 20:28 +0400) wrote: > Alex Kost <alezost@gmail.com> skribis: > > [...] > >> Also I have a question: is there such thing as “obsolete package”? >> AFAIU after ‘guix pull’, a user can still have old versions of packages >> installed that don't exist in the new guix anymore. I.e. after that >> some packages from the current manifest cannot be found with >> ‘(find-packages-by-name "foo" "<old-version>")’. Am I right? > > Yes. Thus, for such packages, the UI would be unable to display the > details. > > Actually, more generally, there is little meta-data about installed > packages, compared to available packages. The UI can assume that an > installed package called ‘guile-2.0.11’ is probably the same as an > available package with the same name and version, but that’s not > necessarily the case. > > It’s possible to check whether they really are the same by computing the > derivation of the available package and comparing its output directory > names to those of the installed package. > > So ideally the UI would show a little warning when it knows it doesn’t > match. > > (Am I clear?) Yes, that's what concerned me since the very beginning – unique entities should have unique identifiers, i.e. ideally there should be an easy-to-get ID for every package. But as I'm using a non-unique ‘name-version’ spec to "identify" a package, information about installed outputs is displayed for every matching package. You may look at: M-x guix-search-by-name guile-2.0.11 to see how it looks like in a “list” and especially “info” buffers currently (I have updated the repo). Also I made some changes for augmenting paths, so please report if something does not work. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-20 7:10 ` Alex Kost @ 2014-07-20 14:08 ` Ludovic Courtès 2014-07-20 16:52 ` Alex Kost 0 siblings, 1 reply; 29+ messages in thread From: Ludovic Courtès @ 2014-07-20 14:08 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Alex Kost <alezost@gmail.com> skribis: > Yes, that's what concerned me since the very beginning – unique entities > should have unique identifiers, i.e. ideally there should be an > easy-to-get ID for every package. But as I'm using a non-unique > ‘name-version’ spec to "identify" a package, information about installed > outputs is displayed for every matching package. OK. At the Scheme level, package objects are unique of course; but at the UI level, we can’t guarantee that there’s a single package for each name/version pair (and this is not even desirable, I think.) > You may look at: > > M-x guix-search-by-name guile-2.0.11 > > to see how it looks like in a “list” and especially “info” buffers > currently (I have updated the repo). Looks good to me! > Also I made some changes for augmenting paths, so please report if > something does not work. I’m still seeing a lot of these at the top of *Guix REPL*: --8<---------------cut here---------------start------------->8--- ;;; note: source file /data/src/guix.el/guix-helper.scm ;;; newer than compiled /home/ludo/.cache/guile/ccache/2.0-LE-8-2.0/data/src/guix.el/guix-helper.scm.go ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0 ;;; or pass the --no-auto-compile argument to disable. ;;; compiling /data/src/guix.el/guix-helper.scm --8<---------------cut here---------------end--------------->8--- Thanks, Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-20 14:08 ` Ludovic Courtès @ 2014-07-20 16:52 ` Alex Kost 2014-07-20 19:42 ` Alex Kost 2014-07-20 19:47 ` Ludovic Courtès 0 siblings, 2 replies; 29+ messages in thread From: Alex Kost @ 2014-07-20 16:52 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel Ludovic Courtès (2014-07-20 18:08 +0400) wrote: > Alex Kost <alezost@gmail.com> skribis: > >> Yes, that's what concerned me since the very beginning – unique entities >> should have unique identifiers, i.e. ideally there should be an >> easy-to-get ID for every package. But as I'm using a non-unique >> ‘name-version’ spec to "identify" a package, information about installed >> outputs is displayed for every matching package. > > OK. At the Scheme level, package objects are unique of course; but at > the UI level, we can’t guarantee that there’s a single package for each > name/version pair (and this is not even desirable, I think.) I don't say that name+version should identify a package, but I think it would be very convenient to have an ID for a package definition. For example now manifest may tell that "out" of a "guile-2.0.11" package is installed but there are 2 "guile-2.0.11" packages out there and it's impossible to distinguish those. And vice versa when I list available packages I want to see my installed outputs only for the right packages, not for all packages with the same name+version. What if to make some ‘get-package-by-id’ function that will always return a single package? And there is no need to add IDs for all package definitions, as most of them are identified with name+version already. What I suggest is to add an optional “postfix” field to <package> record, so that a combination “name+version+[postfix]” will be unique and will be returned by ‘package-id’ like this: (package-id #<package guile-2.0.11 gnu/packages/guile.scm>) ==> "guile-2.0.11" (package-id #<package guile-2.0.11 gnu/packages/base.scm>) ==> "guile-2.0.11_base" And also to add this ID to the manifest entries. I believe all this will not break current functionality but it may be very useful. What do you think? >> You may look at: >> >> M-x guix-search-by-name guile-2.0.11 >> >> to see how it looks like in a “list” and especially “info” buffers >> currently (I have updated the repo). > > Looks good to me! It doesn't look good to me. As I said before, installed outputs should “belong” only to a single package, which can be done only (IMHO) if there will be a unique ID for a package definition. >> Also I made some changes for augmenting paths, so please report if >> something does not work. > > I’m still seeing a lot of these at the top of *Guix REPL*: > > ;;; note: source file /data/src/guix.el/guix-helper.scm > ;;; newer than compiled /home/ludo/.cache/guile/ccache/2.0-LE-8-2.0/data/src/guix.el/guix-helper.scm.go > ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0 > ;;; or pass the --no-auto-compile argument to disable. > ;;; compiling /data/src/guix.el/guix-helper.scm A lot? Hm, for me “guix-helper.scm” was the only file that was compiled as it was changed. Could you check that “C-h v guix-directory” tells you the proper directory? (for me it is "/home/alexx/.config/guix/latest" now) Also check ‘%load-compiled-path’ in the “*Guix REPL*” buffer, please. Thanks. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-20 16:52 ` Alex Kost @ 2014-07-20 19:42 ` Alex Kost 2014-07-20 19:47 ` Ludovic Courtès 1 sibling, 0 replies; 29+ messages in thread From: Alex Kost @ 2014-07-20 19:42 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel An addition to my previous mail. > I don't say that name+version should identify a package, but I think it > would be very convenient to have an ID for a package definition. For > example now manifest may tell that "out" of a "guile-2.0.11" package is > installed but there are 2 "guile-2.0.11" packages out there and it's > impossible to distinguish those. And vice versa when I list available > packages I want to see my installed outputs only for the right packages, > not for all packages with the same name+version. > > What if to make some ‘get-package-by-id’ function that will always > return a single package? And there is no need to add IDs for all > package definitions, as most of them are identified with name+version > already. What I suggest is to add an optional “postfix” field to > <package> record, so that a combination “name+version+[postfix]” will be > unique and will be returned by ‘package-id’ like this: > > (package-id #<package guile-2.0.11 gnu/packages/guile.scm>) ==> "guile-2.0.11" > (package-id #<package guile-2.0.11 gnu/packages/base.scm>) ==> "guile-2.0.11_base" Perhaps it would be better to have a ‘unique-name’ field that defaults to a ‘name’ field if not specified, so ‘unique-name+version’ pair will identify a package. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-20 16:52 ` Alex Kost 2014-07-20 19:42 ` Alex Kost @ 2014-07-20 19:47 ` Ludovic Courtès 2014-07-21 6:46 ` Alex Kost 1 sibling, 1 reply; 29+ messages in thread From: Ludovic Courtès @ 2014-07-20 19:47 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Alex Kost <alezost@gmail.com> skribis: > Ludovic Courtès (2014-07-20 18:08 +0400) wrote: > >> Alex Kost <alezost@gmail.com> skribis: >> >>> Yes, that's what concerned me since the very beginning – unique entities >>> should have unique identifiers, i.e. ideally there should be an >>> easy-to-get ID for every package. But as I'm using a non-unique >>> ‘name-version’ spec to "identify" a package, information about installed >>> outputs is displayed for every matching package. >> >> OK. At the Scheme level, package objects are unique of course; but at >> the UI level, we can’t guarantee that there’s a single package for each >> name/version pair (and this is not even desirable, I think.) > > I don't say that name+version should identify a package, but I think it > would be very convenient to have an ID for a package definition. For [...] > What if to make some ‘get-package-by-id’ function that will always > return a single package? And there is no need to add IDs for all > package definitions, as most of them are identified with name+version > already. What I suggest is to add an optional “postfix” field to > <package> record, so that a combination “name+version+[postfix]” will be > unique and will be returned by ‘package-id’ like this: > > (package-id #<package guile-2.0.11 gnu/packages/guile.scm>) ==> "guile-2.0.11" > (package-id #<package guile-2.0.11 gnu/packages/base.scm>) ==> "guile-2.0.11_base" > > And also to add this ID to the manifest entries. > > I believe all this will not break current functionality but it may be > very useful. What do you think? I think it would be just another hand-maintained identifier database, thereby suffering from the very same problems as name+version. But there’s already a 100% unique identifier that can be relied on: the directory name of outputs. When the directory name(s) of an installed package match that of a package from the distro, you can tell they’re the same. When they don’t all you know is that it’s a different package. Remember that packages can be generated programmatically (see ‘static-package’ & co.), and they users can install packages from their own recipes. There’s no notion of having a central unique package database. So I think the UI must be able to cope with that: it has package names as nice human-readable identifiers, but it cannot map back from an installed package to its recipe and... >>> You may look at: >>> >>> M-x guix-search-by-name guile-2.0.11 >>> >>> to see how it looks like in a “list” and especially “info” buffers >>> currently (I have updated the repo). >> >> Looks good to me! ... that’s why I say it looks good to me. :-) >>> Also I made some changes for augmenting paths, so please report if >>> something does not work. >> >> I’m still seeing a lot of these at the top of *Guix REPL*: >> >> ;;; note: source file /data/src/guix.el/guix-helper.scm >> ;;; newer than compiled /home/ludo/.cache/guile/ccache/2.0-LE-8-2.0/data/src/guix.el/guix-helper.scm.go >> ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0 >> ;;; or pass the --no-auto-compile argument to disable. >> ;;; compiling /data/src/guix.el/guix-helper.scm > > A lot? Hm, for me “guix-helper.scm” was the only file that was compiled > as it was changed. Could you check that “C-h v guix-directory” tells > you the proper directory? (for me it is "/home/alexx/.config/guix/latest" > now) Also check ‘%load-compiled-path’ in the “*Guix REPL*” buffer, please. The only difference between %load-compiled-path in my *Guile REPL* and that in *Guix REPL* is that the latter adds this "/home/ludo/.config/guix/latest" (which is what ‘guix-directory’ is set to.) I can’t seem to reproduce the problem now, so probably the problem was between keyboard and chair. :-) Thanks! Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-20 19:47 ` Ludovic Courtès @ 2014-07-21 6:46 ` Alex Kost 2014-07-21 16:04 ` Ludovic Courtès 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-07-21 6:46 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel Ludovic Courtès (2014-07-20 23:47 +0400) wrote: > Alex Kost <alezost@gmail.com> skribis: > >> Ludovic Courtès (2014-07-20 18:08 +0400) wrote: >> >>> Alex Kost <alezost@gmail.com> skribis: >>> >>>> Yes, that's what concerned me since the very beginning – unique entities >>>> should have unique identifiers, i.e. ideally there should be an >>>> easy-to-get ID for every package. But as I'm using a non-unique >>>> ‘name-version’ spec to "identify" a package, information about installed >>>> outputs is displayed for every matching package. >>> >>> OK. At the Scheme level, package objects are unique of course; but at >>> the UI level, we can’t guarantee that there’s a single package for each >>> name/version pair (and this is not even desirable, I think.) >> >> I don't say that name+version should identify a package, but I think it >> would be very convenient to have an ID for a package definition. For > > [...] > >> What if to make some ‘get-package-by-id’ function that will always >> return a single package? And there is no need to add IDs for all >> package definitions, as most of them are identified with name+version >> already. What I suggest is to add an optional “postfix” field to >> <package> record, so that a combination “name+version+[postfix]” will be >> unique and will be returned by ‘package-id’ like this: >> >> (package-id #<package guile-2.0.11 gnu/packages/guile.scm>) ==> "guile-2.0.11" >> (package-id #<package guile-2.0.11 gnu/packages/base.scm>) ==> "guile-2.0.11_base" >> >> And also to add this ID to the manifest entries. >> >> I believe all this will not break current functionality but it may be >> very useful. What do you think? > > I think it would be just another hand-maintained identifier database, > thereby suffering from the very same problems as name+version. > > But there’s already a 100% unique identifier that can be relied on: the > directory name of outputs. When the directory name(s) of an installed > package match that of a package from the distro, you can tell they’re > the same. When they don’t all you know is that it’s a different > package. > > Remember that packages can be generated programmatically (see > ‘static-package’ & co.), and they users can install packages from their > own recipes. There’s no notion of having a central unique package > database. > > So I think the UI must be able to cope with that: it has package names > as nice human-readable identifiers, but it cannot map back from an > installed package to its recipe and... A directory name identifies the output but not a package definition. I think current situation is very confusing to users. A user can't even install any package. What if he wants to install “guile” from “base.scm”? It will not be possible to install the exact package with any UI, the only way is to use a guile REPL directly. And I would say the names are not really package names, they are program names, so with “guix package -i ...” a user installs a program, not a particular package. If there were a “unique-name” field, a user would be able to install a real package: “guix package -i guile-base-2.0.11”. I strongly believe this is a problem. You can see the packages that you can't install or even worse “guix package --list-installed” may tell you that you have several “foo-1.0:out” installed. Actually when I saw the packages with the same name/version the first time, I thought it's a bug. Anyway, if nothing can be done here, so be it; but any UI will be confusing for these reasons. P.S. If not all packages are supposed to be installed by the end user, perhaps it would be good to mark those somehow (for example to make an optional “internal” field) and to add “--hide-internals” or “--show-internals” option to “guix package” command. If a user make his own package with the name that already exists, it is his problem. How is he going to distinguish these packages when he uses “guix” script (or more generally any UI except of the guile REPL itself)? ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-21 6:46 ` Alex Kost @ 2014-07-21 16:04 ` Ludovic Courtès 2014-07-21 18:46 ` Alex Kost 0 siblings, 1 reply; 29+ messages in thread From: Ludovic Courtès @ 2014-07-21 16:04 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Alex Kost <alezost@gmail.com> skribis: > I think current situation is very confusing to users. A user can't even > install any package. What if he wants to install “guile” from > “base.scm”? It’s possible, using ‘guix package -e’ (info "(guix) Invoking guix package"). I think guix.el should be able to distinguish packages internally, so that when I choose, say, a specific “guile-2.0.11”, that’s really the one that gets installed (maybe it already does, I haven’t checked.) > I strongly believe this is a problem. You can see the packages that you > can't install or even worse “guix package --list-installed” may tell you > that you have several “foo-1.0:out” installed. Actually when I saw the > packages with the same name/version the first time, I thought it's a > bug. I would say it’s a problem of the distro–i.e., the (gnu packages ...) modules–if several same-named packages are exposed to the user. We’ve discussed several times the problem of having duplicates between base.scm and other modules, but I haven’t come to a satisfying solution. So I agree, these specific cases must be addressed somehow. However, it’s a fundamental feature of the package manager that packages (really: package records) can be freely created, and that the ‘name’ field is just a hint. Duplicates should remain rare in practice, but the UI must be prepared to deal with them IMO. WDYT? Thanks, Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-21 16:04 ` Ludovic Courtès @ 2014-07-21 18:46 ` Alex Kost 2014-07-21 21:26 ` Ludovic Courtès 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-07-21 18:46 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel Ludovic Courtès (2014-07-21 20:04 +0400) wrote: > Alex Kost <alezost@gmail.com> skribis: > >> I think current situation is very confusing to users. A user can't even >> install any package. What if he wants to install “guile” from >> “base.scm”? > > It’s possible, using ‘guix package -e’ (info "(guix) Invoking guix > package"). > > I think guix.el should be able to distinguish packages internally, so > that when I choose, say, a specific “guile-2.0.11”, that’s really the > one that gets installed (maybe it already does, I haven’t checked.) No it doesn't and I don't see how it can be done. If it were Guile Emacs, it would be possible to distinguish packages internally, but all I have now is name+version which is not unique. Or maybe... >> I strongly believe this is a problem. You can see the packages that you >> can't install or even worse “guix package --list-installed” may tell you >> that you have several “foo-1.0:out” installed. Actually when I saw the >> packages with the same name/version the first time, I thought it's a >> bug. > > I would say it’s a problem of the distro–i.e., the (gnu packages ...) > modules–if several same-named packages are exposed to the user. We’ve > discussed several times the problem of having duplicates between > base.scm and other modules, but I haven’t come to a satisfying solution. > > So I agree, these specific cases must be addressed somehow. > > However, it’s a fundamental feature of the package manager that packages > (really: package records) can be freely created, and that the ‘name’ > field is just a hint. Duplicates should remain rare in practice, but > the UI must be prepared to deal with them IMO. > > WDYT? ... or maybe this: to fill some hash table or vhash or whatever with all available packages after a repl is started, and use this storage with unique keys to search/get packages instead of the ‘fold-packages’. This will allow to get and thus to install a particular package by its key. I didn't think much about it, but right now this is the only workaround I can imagine. What do you think? ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-21 18:46 ` Alex Kost @ 2014-07-21 21:26 ` Ludovic Courtès 2014-07-22 6:20 ` Alex Kost 0 siblings, 1 reply; 29+ messages in thread From: Ludovic Courtès @ 2014-07-21 21:26 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Alex Kost <alezost@gmail.com> skribis: > Ludovic Courtès (2014-07-21 20:04 +0400) wrote: [...] >> I think guix.el should be able to distinguish packages internally, so >> that when I choose, say, a specific “guile-2.0.11”, that’s really the >> one that gets installed (maybe it already does, I haven’t checked.) > > No it doesn't and I don't see how it can be done. A trick that may work is to propagate Scheme-side eq?-ness to the elisp side using ‘object-address’: (object-address some-package) returns a number that uniquely identifies ‘some-package’ for the duration of the Guile session. [...] > I didn't think much about it, but right now this is the only workaround > I can imagine. What do you think? What do you think of the trick above? Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-21 21:26 ` Ludovic Courtès @ 2014-07-22 6:20 ` Alex Kost 2014-07-22 6:53 ` Taylan Ulrich Bayirli/Kammer 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-07-22 6:20 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel Ludovic Courtès (2014-07-22 01:26 +0400) wrote: > Alex Kost <alezost@gmail.com> skribis: > >> Ludovic Courtès (2014-07-21 20:04 +0400) wrote: > > [...] > >>> I think guix.el should be able to distinguish packages internally, so >>> that when I choose, say, a specific “guile-2.0.11”, that’s really the >>> one that gets installed (maybe it already does, I haven’t checked.) >> >> No it doesn't and I don't see how it can be done. > > A trick that may work is to propagate Scheme-side eq?-ness to the elisp > side using ‘object-address’: (object-address some-package) returns a > number that uniquely identifies ‘some-package’ for the duration of the > Guile session. > > [...] > >> I didn't think much about it, but right now this is the only workaround >> I can imagine. What do you think? > > What do you think of the trick above? Ah, thanks, I didn't know about ‘object-address’, it will be a perfect ID. But I'm going to make a vhash of address/package pairs anyway, as I need ‘get-package-by-id’ and ‘get-packages-by-ids’ functions and I guess it is not possible to get an object by its address (?), so I think “(vhash-assq <address> <packages-vhash>)” will be the best choice to get a particular package. Thanks, Alex. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-22 6:20 ` Alex Kost @ 2014-07-22 6:53 ` Taylan Ulrich Bayirli/Kammer 2014-07-22 8:41 ` Ludovic Courtès 2014-07-22 9:34 ` Alex Kost 0 siblings, 2 replies; 29+ messages in thread From: Taylan Ulrich Bayirli/Kammer @ 2014-07-22 6:53 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Alex Kost <alezost@gmail.com> writes: > [...] get an object by its address (?), [...] (pointer->scm (make-pointer address)) More info at (info "(guile) Foreign Variables"). Warning: can lead to Scheme code that segfaults! :-) Taylan ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-22 6:53 ` Taylan Ulrich Bayirli/Kammer @ 2014-07-22 8:41 ` Ludovic Courtès 2014-07-22 9:34 ` Alex Kost 1 sibling, 0 replies; 29+ messages in thread From: Ludovic Courtès @ 2014-07-22 8:41 UTC (permalink / raw) To: Taylan Ulrich Bayirli/Kammer; +Cc: guix-devel, Alex Kost Taylan Ulrich Bayirli/Kammer <taylanbayirli@gmail.com> skribis: > Alex Kost <alezost@gmail.com> writes: > >> [...] get an object by its address (?), [...] > > (pointer->scm (make-pointer address)) I was going to suggest that, but yeah, a vhash is more reasonable. :-) Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-22 6:53 ` Taylan Ulrich Bayirli/Kammer 2014-07-22 8:41 ` Ludovic Courtès @ 2014-07-22 9:34 ` Alex Kost 1 sibling, 0 replies; 29+ messages in thread From: Alex Kost @ 2014-07-22 9:34 UTC (permalink / raw) To: Taylan Ulrich Bayirli/Kammer; +Cc: guix-devel Taylan Ulrich Bayirli/Kammer (2014-07-22 10:53 +0400) wrote: >> [...] get an object by its address (?), [...] > > (pointer->scm (make-pointer address)) > > More info at (info "(guile) Foreign Variables"). > > Warning: can lead to Scheme code that segfaults! :-) > > Taylan Ludovic Courtès (2014-07-22 12:41 +0400) wrote: > I was going to suggest that, but yeah, a vhash is more reasonable. :-) Ah, that's cool, thanks for the information, guys (I'm going to stay on vhash). -- Alex Kost ^ permalink raw reply [flat|nested] 29+ messages in thread
* Emacs interface for Guix @ 2014-07-25 17:58 Alex Kost 2014-07-25 20:36 ` Ludovic Courtès 2014-07-26 20:58 ` Ludovic Courtès 0 siblings, 2 replies; 29+ messages in thread From: Alex Kost @ 2014-07-25 17:58 UTC (permalink / raw) To: guix-devel Hello, I have questions about installing/deleting packages using guile repl. I know it is possible to ‘(guix-package "--install" "guile-2.0.11")’, but is there an easy way to install an output of an exact _package object_? I mean not any "guile" but #<package guile-2.0.11 ...>. I think ‘(guix-package "--install-from-expression" ...)’ is also not sufficient as it always (?) installs “out”. If I understand correctly a lot of stuff should be done to perform such actions properly: at first the new manifest is created from the current one by adding/removing entries (created from packages) for installation/deletion, then the derivations are built and symlinks are updated. There is a lot of code in “guix/scripts/package.scm” to do all that stuff and unfortunately not much is exported from this module (“package->manifest-entry” from “options->installable” would be very useful for example), and I think trying to include this code in the helper scheme file for guix.el is not right (besides my scheme foo is weak and I'm not sure I can do that successfully) that's why I ask about an easier way. Thanks, Alex ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-25 17:58 Alex Kost @ 2014-07-25 20:36 ` Ludovic Courtès 2014-07-26 17:44 ` Alex Kost 2014-07-26 20:58 ` Ludovic Courtès 1 sibling, 1 reply; 29+ messages in thread From: Ludovic Courtès @ 2014-07-25 20:36 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Hi, Alex, Alex Kost <alezost@gmail.com> skribis: > I have questions about installing/deleting packages using guile repl. > I know it is possible to ‘(guix-package "--install" "guile-2.0.11")’, > but is there an easy way to install an output of an exact _package > object_? I mean not any "guile" but #<package guile-2.0.11 ...>. > > I think ‘(guix-package "--install-from-expression" ...)’ is also not > sufficient as it always (?) installs “out”. This is correct. (It could be worked around by adding a command-line option to specify another output, but that just hadn’t seem very useful so far.) > There is a lot of code in “guix/scripts/package.scm” to do all that > stuff and unfortunately not much is exported from this module > (“package->manifest-entry” from “options->installable” would be very > useful for example), and I think trying to include this code in the > helper scheme file for guix.el is not right (besides my scheme foo is > weak and I'm not sure I can do that successfully) that's why I ask > about an easier way. Well, you’ve already understood what needs to be done. :-) Namely, (guix scripts package) needs to be made more modular, and the generic bits must be moved to (guix profiles). Now that there’s a second consumer for this API, there’s more of an incentive to do it. I’m willing to help for that, but I’m happy if you give it a try. WDYT? Thanks, Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-25 20:36 ` Ludovic Courtès @ 2014-07-26 17:44 ` Alex Kost 2014-07-28 10:15 ` Alex Kost 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-07-26 17:44 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel Ludovic Courtès (2014-07-26 00:36 +0400) wrote: [...] > Namely, (guix scripts package) needs to be made more modular, and the > generic bits must be moved to (guix profiles). Now that there’s a > second consumer for this API, there’s more of an incentive to do it. > > I’m willing to help for that, but I’m happy if you give it a try. > WDYT? Sure, I'll do what I can, however the quality of my try may be unsatisfactory. Anyway I think I'll send a patch in several days. -- Alex Kost ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-26 17:44 ` Alex Kost @ 2014-07-28 10:15 ` Alex Kost 2014-08-11 20:54 ` Ludovic Courtès 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-07-28 10:15 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel [-- Attachment #1: Type: text/plain, Size: 1262 bytes --] Hello, Ludovic and happy vacations :) Alex Kost (2014-07-26 21:44 +0400) wrote: > Ludovic Courtès (2014-07-26 00:36 +0400) wrote: > > [...] > >> Namely, (guix scripts package) needs to be made more modular, and the >> generic bits must be moved to (guix profiles). Now that there’s a >> second consumer for this API, there’s more of an incentive to do it. >> >> I’m willing to help for that, but I’m happy if you give it a try. >> WDYT? > > Sure, I'll do what I can, however the quality of my try may be > unsatisfactory. Anyway I think I'll send a patch in several days. You are probably reading this a couple of weeks from now so my changes may not be actual, but anyway I'm attaching a patch with the changes. Here is what I've done: - A part of code for installing/upgrading/removing was extracted from ‘guix-package’ function (from ‘process-actions’ more precisely). So the new function (I named it ‘process-package-actions’) can be used in "guix.el". - A bit of code was placed into "profiles.scm" as ‘manifest-add’. - Also I think you forgot (?) to remove ‘deduplicate’ function in commit 4ca0b41, so I did it as well. I hope something of the above is acceptable. WDYT? [-- Attachment #2: guix.diff --] [-- Type: text/x-diff, Size: 20226 bytes --] diff --git a/guix/profiles.scm b/guix/profiles.scm index 5e69e01..8533af5 100644 --- a/guix/profiles.scm +++ b/guix/profiles.scm @@ -47,6 +47,7 @@ manifest-pattern? manifest-remove + manifest-add manifest-installed? manifest-matching-entries @@ -196,6 +197,25 @@ must be a manifest-pattern." (manifest-entries manifest) patterns))) +(define (manifest-add manifest entries) + "Add ENTRIES to MANIFEST and return new manifest. +Remove MANIFEST entries that have the same name and output as ENTRIES." + (define (same-entry? entry name output) + (match entry + (($ <manifest-entry> entry-name _ entry-output _ ...) + (and (equal? name entry-name) + (equal? output entry-output))))) + + (make-manifest + (append entries + (fold (lambda (entry result) + (match entry + (($ <manifest-entry> name _ out _ ...) + (filter (negate (cut same-entry? <> name out)) + result)))) + (manifest-entries manifest) + entries)))) + (define (manifest-installed? manifest pattern) "Return #t if MANIFEST has an entry matching PATTERN (a manifest-pattern), #f otherwise." diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm index 31da773..09c1bf1 100644 --- a/guix/scripts/package.scm +++ b/guix/scripts/package.scm @@ -44,6 +44,7 @@ #:use-module ((gnu packages bootstrap) #:select (%bootstrap-guile)) #:use-module (guix gnu-maintenance) #:export (specification->package+output + process-package-actions guix-package)) (define %store @@ -620,112 +621,46 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n")) %standard-build-options)) -(define (options->installable opts manifest) - "Given MANIFEST, the current manifest, and OPTS, the result of 'args-fold', -return the new list of manifest entries." - (define (deduplicate deps) - ;; Remove duplicate entries from DEPS, a list of propagated inputs, where - ;; each input is a name/path tuple. - (define (same? d1 d2) - (match d1 - ((_ p1) - (match d2 - ((_ p2) (eq? p1 p2)) - (_ #f))) - ((_ p1 out1) - (match d2 - ((_ p2 out2) - (and (string=? out1 out2) - (eq? p1 p2))) - (_ #f))))) - - (delete-duplicates deps same?)) - - (define (package->manifest-entry* package output) - (check-package-freshness package) - ;; When given a package via `-e', install the first of its - ;; outputs (XXX). - (package->manifest-entry package output)) - +(define (options->installable options manifest) + "Given OPTIONS, return a list of patterns for installing/upgrading. +Returned list is suitable for 'process-package-actions'." (define upgrade-regexps (filter-map (match-lambda (('upgrade . regexp) (make-regexp (or regexp ""))) (_ #f)) - opts)) + options)) (define packages-to-upgrade (match upgrade-regexps (() '()) ((_ ...) - (let ((newest (find-newest-available-packages))) - (filter-map (match-lambda - (($ <manifest-entry> name version output path _) - (and (any (cut regexp-exec <> name) - upgrade-regexps) - (upgradeable? name version path) - (let ((output (or output "out"))) - (call-with-values - (lambda () - (specification->package+output name output)) - list)))) - (_ #f)) - (manifest-entries manifest)))))) - - (define to-upgrade - (map (match-lambda - ((package output) - (package->manifest-entry* package output))) - packages-to-upgrade)) + (filter-map (match-lambda + (($ <manifest-entry> name version output path _) + (and (any (cut regexp-exec <> name) + upgrade-regexps) + (upgradeable? name version path) + (let ((output (or output "out"))) + (call-with-values + (lambda () + (specification->package+output name output)) + list)))) + (_ #f)) + (manifest-entries manifest))))) (define packages-to-install (filter-map (match-lambda - (('install . (? package? p)) - (list p "out")) - (('install . (? string? spec)) - (and (not (store-path? spec)) - (let-values (((package output) - (specification->package+output spec))) - (and package (list package output))))) + (('install . package) package) (_ #f)) - opts)) - - (define to-install - (append (map (match-lambda - ((package output) - (package->manifest-entry* package output))) - packages-to-install) - (filter-map (match-lambda - (('install . (? package?)) - #f) - (('install . (? store-path? path)) - (let-values (((name version) - (package-name->name+version - (store-path-package-name path)))) - (manifest-entry - (name name) - (version version) - (output #f) - (item path)))) - (_ #f)) - opts))) - - (append to-upgrade to-install)) - -(define (options->removable options manifest) - "Given options, return the list of manifest patterns of packages to be -removed from MANIFEST." + options)) + + (append packages-to-upgrade packages-to-install)) + +(define (options->removable options) + "Given OPTIONS, return a list of package specifications for deleting." (filter-map (match-lambda - (('remove . spec) - (call-with-values - (lambda () - (package-specification->name+version+output spec)) - (lambda (name version output) - (manifest-pattern - (name name) - (version version) - (output output))))) + (('remove . spec) spec) (_ #f)) options)) @@ -744,6 +679,150 @@ removed from MANIFEST." file (apply throw args))))) +(define (ensure-default-profile) + "Ensure the default profile symlink and directory exist and are +writable." + (define (rtfm) + (format (current-error-port) + (_ "Try \"info '(guix) Invoking guix package'\" for \ +more information.~%")) + (exit 1)) + + ;; Create ~/.guix-profile if it doesn't exist yet. + (when (and %user-profile-directory + %current-profile + (not (false-if-exception + (lstat %user-profile-directory)))) + (symlink %current-profile %user-profile-directory)) + + (let ((s (stat %profile-directory #f))) + ;; Attempt to create /…/profiles/per-user/$USER if needed. + (unless (and s (eq? 'directory (stat:type s))) + (catch 'system-error + (lambda () + (mkdir-p %profile-directory)) + (lambda args + ;; Often, we cannot create %PROFILE-DIRECTORY because its + ;; parent directory is root-owned and we're running + ;; unprivileged. + (format (current-error-port) + (_ "error: while creating directory `~a': ~a~%") + %profile-directory + (strerror (system-error-errno args))) + (format (current-error-port) + (_ "Please create the `~a' directory, with you as the owner.~%") + %profile-directory) + (rtfm)))) + + ;; Bail out if it's not owned by the user. + (unless (or (not s) (= (stat:uid s) (getuid))) + (format (current-error-port) + (_ "error: directory `~a' is not owned by you~%") + %profile-directory) + (format (current-error-port) + (_ "Please change the owner of `~a' to user ~s.~%") + %profile-directory (or (getenv "USER") + (getenv "LOGNAME") + (getuid))) + (rtfm)))) + +(define* (process-package-actions store profile + #:key (install '()) (remove '()) + dry-run? (use-substitutes? #t)) + "Install/remove packages. + +INSTALL is a list of package patterns for installation. Each element of +the list may be a package, a list (PACKAGE OUTPUT), a string with name +specification or a store path. + +REMOVE is a list of name specifications for removing from PROFILE +manifest." + (define (package->manifest-entry* package output) + (check-package-freshness package) + ;; When given a package via `-e', install the first of its + ;; outputs (XXX). + (package->manifest-entry package output)) + + (define (entries-to-install install) + ;; Return a list of manifest entries for installing. + (filter-map (match-lambda + ((? package? package) + (package->manifest-entry* package "out")) + (((? package? package) output) + (package->manifest-entry* package output)) + ((? string? spec-or-path) + (if (store-path? spec-or-path) + (let-values (((name version) + (package-name->name+version + (store-path-package-name spec-or-path)))) + (manifest-entry + (name name) + (version version) + (output #f) + (item spec-or-path))) + (let-values (((package output) + (specification->package+output spec-or-path))) + (and package (package->manifest-entry* package output))))) + (_ #f)) + install)) + + (define (patterns-to-remove remove) + ;; Return a list of manifest patterns for removing. + (map (lambda (spec) + (call-with-values + (lambda () + (package-specification->name+version+output spec)) + (lambda (name version output) + (manifest-pattern + (name name) + (version version) + (output output))))) + remove)) + + (let* ((manifest (profile-manifest profile)) + (install (entries-to-install install)) + (remove (patterns-to-remove remove)) + (new (manifest-add (manifest-remove manifest remove) + install)) + (entries (manifest-entries new))) + + (unless (and (null? install) (null? remove)) + (when (equal? profile %current-profile) + (ensure-default-profile)) + + (let* ((prof-drv (run-with-store store (profile-derivation new))) + (prof (derivation->output-path prof-drv)) + (remove (manifest-matching-entries manifest remove))) + (show-what-to-remove/install remove install dry-run?) + (show-what-to-build store (list prof-drv) + #:use-substitutes? use-substitutes? + #:dry-run? dry-run?) + + (cond + (dry-run? #t) + ((and (file-exists? profile) + (and=> (readlink* profile) (cut string=? prof <>))) + (format (current-error-port) (_ "nothing to be done~%"))) + (else + (let* ((number (generation-number profile)) + + ;; Always use NUMBER + 1 for the new profile, + ;; possibly overwriting a "previous future + ;; generation". + (name (generation-file-name profile + (+ 1 number)))) + (and (build-derivations store (list prof-drv)) + (let ((count (length entries))) + (switch-symlinks name prof) + (switch-symlinks profile name) + (maybe-register-gc-root store profile) + (format #t (N_ "~a package in profile~%" + "~a packages in profile~%" + count) + count) + (display-search-paths entries + profile)))))))))) + \f ;;; ;;; Entry point. @@ -767,66 +846,13 @@ removed from MANIFEST." (let ((out (derivation->output-path (%guile-for-build)))) (not (valid-path? (%store) out)))) - (define (ensure-default-profile) - ;; Ensure the default profile symlink and directory exist and are - ;; writable. - - (define (rtfm) - (format (current-error-port) - (_ "Try \"info '(guix) Invoking guix package'\" for \ -more information.~%")) - (exit 1)) - - ;; Create ~/.guix-profile if it doesn't exist yet. - (when (and %user-profile-directory - %current-profile - (not (false-if-exception - (lstat %user-profile-directory)))) - (symlink %current-profile %user-profile-directory)) - - (let ((s (stat %profile-directory #f))) - ;; Attempt to create /…/profiles/per-user/$USER if needed. - (unless (and s (eq? 'directory (stat:type s))) - (catch 'system-error - (lambda () - (mkdir-p %profile-directory)) - (lambda args - ;; Often, we cannot create %PROFILE-DIRECTORY because its - ;; parent directory is root-owned and we're running - ;; unprivileged. - (format (current-error-port) - (_ "error: while creating directory `~a': ~a~%") - %profile-directory - (strerror (system-error-errno args))) - (format (current-error-port) - (_ "Please create the `~a' directory, with you as the owner.~%") - %profile-directory) - (rtfm)))) - - ;; Bail out if it's not owned by the user. - (unless (or (not s) (= (stat:uid s) (getuid))) - (format (current-error-port) - (_ "error: directory `~a' is not owned by you~%") - %profile-directory) - (format (current-error-port) - (_ "Please change the owner of `~a' to user ~s.~%") - %profile-directory (or (getenv "USER") - (getenv "LOGNAME") - (getuid))) - (rtfm)))) - (define (process-actions opts) ;; Process any install/remove/upgrade action from OPTS. - (define dry-run? (assoc-ref opts 'dry-run?)) - (define verbose? (assoc-ref opts 'verbose?)) - (define profile (assoc-ref opts 'profile)) - - (define (same-package? entry name output) - (match entry - (($ <manifest-entry> entry-name _ entry-output _ ...) - (and (equal? name entry-name) - (equal? output entry-output))))) + (define substitutes? (assoc-ref opts 'substitutes?)) + (define dry-run? (assoc-ref opts 'dry-run?)) + (define verbose? (assoc-ref opts 'verbose?)) + (define profile (assoc-ref opts 'profile)) (define current-generation-number (generation-number profile)) @@ -895,61 +921,12 @@ more information.~%")) (_ #f)) opts)) (else - (let* ((manifest (profile-manifest profile)) - (install (options->installable opts manifest)) - (remove (options->removable opts manifest)) - (entries - (append install - (fold (lambda (package result) - (match package - (($ <manifest-entry> name _ out _ ...) - (filter (negate - (cut same-package? <> - name out)) - result)))) - (manifest-entries - (manifest-remove manifest remove)) - install))) - (new (make-manifest entries))) - - (when (equal? profile %current-profile) - (ensure-default-profile)) - - (unless (and (null? install) (null? remove)) - (let* ((prof-drv (run-with-store (%store) - (profile-derivation new))) - (prof (derivation->output-path prof-drv)) - (remove (manifest-matching-entries manifest remove))) - (show-what-to-remove/install remove install dry-run?) - (show-what-to-build (%store) (list prof-drv) - #:use-substitutes? - (assoc-ref opts 'substitutes?) - #:dry-run? dry-run?) - - (cond - (dry-run? #t) - ((and (file-exists? profile) - (and=> (readlink* profile) (cut string=? prof <>))) - (format (current-error-port) (_ "nothing to be done~%"))) - (else - (let* ((number (generation-number profile)) - - ;; Always use NUMBER + 1 for the new profile, - ;; possibly overwriting a "previous future - ;; generation". - (name (generation-file-name profile - (+ 1 number)))) - (and (build-derivations (%store) (list prof-drv)) - (let ((count (length entries))) - (switch-symlinks name prof) - (switch-symlinks profile name) - (maybe-register-gc-root (%store) profile) - (format #t (N_ "~a package in profile~%" - "~a packages in profile~%" - count) - count) - (display-search-paths entries - profile)))))))))))) + (process-package-actions + (%store) profile + #:install (options->installable opts (profile-manifest profile)) + #:remove (options->removable opts) + #:use-substitutes? substitutes? + #:dry-run? dry-run?)))) (define (process-query opts) ;; Process any query specified by OPTS. Return #t when a query was ^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-28 10:15 ` Alex Kost @ 2014-08-11 20:54 ` Ludovic Courtès 2014-08-12 10:19 ` [PATCH] " Alex Kost 0 siblings, 1 reply; 29+ messages in thread From: Ludovic Courtès @ 2014-08-11 20:54 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Alex Kost <alezost@gmail.com> skribis: > - A part of code for installing/upgrading/removing was extracted from > ‘guix-package’ function (from ‘process-actions’ more precisely). So > the new function (I named it ‘process-package-actions’) can be used in > "guix.el". That looks good, but could you make it a separate patch? In general, it’s better to send atomic changes, with a commit log, in the format produced by ‘git format-patch’ (see HACKING.) That facilitates review and incremental changes. > - A bit of code was placed into "profiles.scm" as ‘manifest-add’. Good idea. Could you send a single patch for this change? I’ll even add a couple of test cases in tests/profiles.scm for the new procedure if you don’t do it yourself. :-) > - Also I think you forgot (?) to remove ‘deduplicate’ function in commit > 4ca0b41, so I did it as well. Indeed, I’ve just removed it and a couple others. Somehow I thought we were compiling with -Wunused-toplevel. Thanks, Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH] Emacs interface for Guix 2014-08-11 20:54 ` Ludovic Courtès @ 2014-08-12 10:19 ` Alex Kost 2014-08-12 14:19 ` Ludovic Courtès 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-08-12 10:19 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel [-- Attachment #1: Type: text/plain, Size: 1126 bytes --] Hello, Ludovic Courtès (2014-08-12 00:54 +0400) wrote: > Alex Kost <alezost@gmail.com> skribis: > >> - A part of code for installing/upgrading/removing was extracted from >> ‘guix-package’ function (from ‘process-actions’ more precisely). So >> the new function (I named it ‘process-package-actions’) can be used in >> "guix.el". > > That looks good, but could you make it a separate patch? > > In general, it’s better to send atomic changes, with a commit log, in > the format produced by ‘git format-patch’ (see HACKING.) That > facilitates review and incremental changes. Thanks for pointing. I've never contributed to a real project, so I don't know the rules actually :) >> - A bit of code was placed into "profiles.scm" as ‘manifest-add’. > > Good idea. Could you send a single patch for this change? I’ll even > add a couple of test cases in tests/profiles.scm for the new procedure > if you don’t do it yourself. :-) Ok, I'm attaching 2 patches with ‘manifest-add’ and ‘process-package-actions’. What should be changed/improved there? [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-profiles-Add-manifest-add.patch --] [-- Type: text/x-patch, Size: 2954 bytes --] From af4b8495969d70d59aa9f3f296628daeaf80b0d2 Mon Sep 17 00:00:00 2001 From: Alex Kost <alezost@gmail.com> Date: Tue, 12 Aug 2014 12:32:16 +0400 Subject: [PATCH 1/2] profiles: Add 'manifest-add'. * guix/profiles.scm (manifest-add): New procedure. * tests/profiles.scm (guile-1.8.8): New variable. ("manifest-add"): New test. --- guix/profiles.scm | 20 ++++++++++++++++++++ tests/profiles.scm | 21 +++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/guix/profiles.scm b/guix/profiles.scm index 5e69e01..c7aec79 100644 --- a/guix/profiles.scm +++ b/guix/profiles.scm @@ -47,6 +47,7 @@ manifest-pattern? manifest-remove + manifest-add manifest-installed? manifest-matching-entries @@ -196,6 +197,25 @@ must be a manifest-pattern." (manifest-entries manifest) patterns))) +(define (manifest-add manifest entries) + "Add a list of manifest ENTRIES to MANIFEST and return new manifest. +Remove MANIFEST entries that have the same name and output as ENTRIES." + (define (same-entry? entry name output) + (match entry + (($ <manifest-entry> entry-name _ entry-output _ ...) + (and (equal? name entry-name) + (equal? output entry-output))))) + + (make-manifest + (append entries + (fold (lambda (entry result) + (match entry + (($ <manifest-entry> name _ out _ ...) + (filter (negate (cut same-entry? <> name out)) + result)))) + (manifest-entries manifest) + entries)))) + (define (manifest-installed? manifest pattern) "Return #t if MANIFEST has an entry matching PATTERN (a manifest-pattern), #f otherwise." diff --git a/tests/profiles.scm b/tests/profiles.scm index d405f64..b2919d7 100644 --- a/tests/profiles.scm +++ b/tests/profiles.scm @@ -40,6 +40,13 @@ ;; Example manifest entries. +(define guile-1.8.8 + (manifest-entry + (name "guile") + (version "1.8.8") + (item "/gnu/store/...") + (output "out"))) + (define guile-2.0.9 (manifest-entry (name "guile") @@ -101,6 +108,20 @@ (null? (manifest-entries m3)) (null? (manifest-entries m4))))))) +(test-assert "manifest-add" + (let* ((m0 (manifest '())) + (m1 (manifest-add m0 (list guile-1.8.8))) + (m2 (manifest-add m1 (list guile-2.0.9))) + (m3 (manifest-add m2 (list guile-2.0.9:debug))) + (m4 (manifest-add m3 (list guile-2.0.9:debug)))) + (and (match (manifest-entries m1) + ((($ <manifest-entry> "guile" "1.8.8" "out")) #t) + (_ #f)) + (match (manifest-entries m2) + ((($ <manifest-entry> "guile" "2.0.9" "out")) #t) + (_ #f)) + (equal? m3 m4)))) + (test-assert "profile-derivation" (run-with-store %store (mlet* %store-monad -- 2.0.3 [-- Attachment #3: 0002-guix-package-Add-process-package-actions.patch --] [-- Type: text/x-patch, Size: 17619 bytes --] From 5fd45b3f4216921837f522d56b20c4be0a58fe8e Mon Sep 17 00:00:00 2001 From: Alex Kost <alezost@gmail.com> Date: Tue, 12 Aug 2014 13:54:23 +0400 Subject: [PATCH 2/2] guix package: Add 'process-package-actions'. * guix/scripts/package.scm (process-package-actions): New procedure. (guix-package): Use it. [ensure-default-profile]: Move to top-level. [substitutes?]: New variable. [same-package?]: Remove. (options->installable, options->removable): Change according to 'process-package-actions'. --- guix/scripts/package.scm | 336 +++++++++++++++++++++++------------------------ 1 file changed, 166 insertions(+), 170 deletions(-) diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm index 4eb046e..2719b74 100644 --- a/guix/scripts/package.scm +++ b/guix/scripts/package.scm @@ -44,6 +44,7 @@ #:use-module ((gnu packages bootstrap) #:select (%bootstrap-guile)) #:use-module (guix gnu-maintenance) #:export (specification->package+output + process-package-actions guix-package)) (define %store @@ -619,21 +620,15 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n")) %standard-build-options)) -(define (options->installable opts manifest) - "Given MANIFEST, the current manifest, and OPTS, the result of 'args-fold', -return the new list of manifest entries." - (define (package->manifest-entry* package output) - (check-package-freshness package) - ;; When given a package via `-e', install the first of its - ;; outputs (XXX). - (package->manifest-entry package output)) - +(define (options->installable options manifest) + "Given OPTIONS, return a list of patterns for installing/upgrading. +Returned list is suitable for 'process-package-actions'." (define upgrade-regexps (filter-map (match-lambda (('upgrade . regexp) (make-regexp (or regexp ""))) (_ #f)) - opts)) + options)) (define packages-to-upgrade (match upgrade-regexps @@ -653,59 +648,18 @@ return the new list of manifest entries." (_ #f)) (manifest-entries manifest))))) - (define to-upgrade - (map (match-lambda - ((package output) - (package->manifest-entry* package output))) - packages-to-upgrade)) - (define packages-to-install (filter-map (match-lambda - (('install . (? package? p)) - (list p "out")) - (('install . (? string? spec)) - (and (not (store-path? spec)) - (let-values (((package output) - (specification->package+output spec))) - (and package (list package output))))) + (('install . package) package) (_ #f)) - opts)) - - (define to-install - (append (map (match-lambda - ((package output) - (package->manifest-entry* package output))) - packages-to-install) - (filter-map (match-lambda - (('install . (? package?)) - #f) - (('install . (? store-path? path)) - (let-values (((name version) - (package-name->name+version - (store-path-package-name path)))) - (manifest-entry - (name name) - (version version) - (output #f) - (item path)))) - (_ #f)) - opts))) - - (append to-upgrade to-install)) - -(define (options->removable options manifest) - "Given options, return the list of manifest patterns of packages to be -removed from MANIFEST." + options)) + + (append packages-to-upgrade packages-to-install)) + +(define (options->removable options) + "Given OPTIONS, return a list of package specifications for deleting." (filter-map (match-lambda - (('remove . spec) - (call-with-values - (lambda () - (package-specification->name+version+output spec)) - (lambda (name version output) - (manifest-pattern - (name name) - (version version) - (output output))))) + (('remove . spec) spec) (_ #f)) options)) @@ -724,6 +678,150 @@ removed from MANIFEST." file (apply throw args))))) +(define (ensure-default-profile) + "Ensure the default profile symlink and directory exist and are +writable." + (define (rtfm) + (format (current-error-port) + (_ "Try \"info '(guix) Invoking guix package'\" for \ +more information.~%")) + (exit 1)) + + ;; Create ~/.guix-profile if it doesn't exist yet. + (when (and %user-profile-directory + %current-profile + (not (false-if-exception + (lstat %user-profile-directory)))) + (symlink %current-profile %user-profile-directory)) + + (let ((s (stat %profile-directory #f))) + ;; Attempt to create /…/profiles/per-user/$USER if needed. + (unless (and s (eq? 'directory (stat:type s))) + (catch 'system-error + (lambda () + (mkdir-p %profile-directory)) + (lambda args + ;; Often, we cannot create %PROFILE-DIRECTORY because its + ;; parent directory is root-owned and we're running + ;; unprivileged. + (format (current-error-port) + (_ "error: while creating directory `~a': ~a~%") + %profile-directory + (strerror (system-error-errno args))) + (format (current-error-port) + (_ "Please create the `~a' directory, with you as the owner.~%") + %profile-directory) + (rtfm)))) + + ;; Bail out if it's not owned by the user. + (unless (or (not s) (= (stat:uid s) (getuid))) + (format (current-error-port) + (_ "error: directory `~a' is not owned by you~%") + %profile-directory) + (format (current-error-port) + (_ "Please change the owner of `~a' to user ~s.~%") + %profile-directory (or (getenv "USER") + (getenv "LOGNAME") + (getuid))) + (rtfm)))) + +(define* (process-package-actions store profile + #:key (install '()) (remove '()) + dry-run? (use-substitutes? #t)) + "Install/remove packages. + +INSTALL is a list of package patterns for installation. Each element of +the list may be a package, a list (PACKAGE OUTPUT), a string with name +specification or a store path. + +REMOVE is a list of name specifications for removing from PROFILE +manifest." + (define (package->manifest-entry* package output) + (check-package-freshness package) + ;; When given a package via `-e', install the first of its + ;; outputs (XXX). + (package->manifest-entry package output)) + + (define (entries-to-install install) + ;; Return a list of manifest entries for installing. + (filter-map (match-lambda + ((? package? package) + (package->manifest-entry* package "out")) + (((? package? package) output) + (package->manifest-entry* package output)) + ((? string? spec-or-path) + (if (store-path? spec-or-path) + (let-values (((name version) + (package-name->name+version + (store-path-package-name spec-or-path)))) + (manifest-entry + (name name) + (version version) + (output #f) + (item spec-or-path))) + (let-values (((package output) + (specification->package+output spec-or-path))) + (and package (package->manifest-entry* package output))))) + (_ #f)) + install)) + + (define (patterns-to-remove remove) + ;; Return a list of manifest patterns for removing. + (map (lambda (spec) + (call-with-values + (lambda () + (package-specification->name+version+output spec)) + (lambda (name version output) + (manifest-pattern + (name name) + (version version) + (output output))))) + remove)) + + (let* ((manifest (profile-manifest profile)) + (install (entries-to-install install)) + (remove (patterns-to-remove remove)) + (new (manifest-add (manifest-remove manifest remove) + install)) + (entries (manifest-entries new))) + + (unless (and (null? install) (null? remove)) + (when (equal? profile %current-profile) + (ensure-default-profile)) + + (let* ((prof-drv (run-with-store store (profile-derivation new))) + (prof (derivation->output-path prof-drv)) + (remove (manifest-matching-entries manifest remove))) + (show-what-to-remove/install remove install dry-run?) + (show-what-to-build store (list prof-drv) + #:use-substitutes? use-substitutes? + #:dry-run? dry-run?) + + (cond + (dry-run? #t) + ((and (file-exists? profile) + (and=> (readlink* profile) (cut string=? prof <>))) + (format (current-error-port) (_ "nothing to be done~%"))) + (else + (let* ((number (generation-number profile)) + + ;; Always use NUMBER + 1 for the new profile, + ;; possibly overwriting a "previous future + ;; generation". + (name (generation-file-name profile + (+ 1 number)))) + (and (build-derivations store (list prof-drv)) + (let ((count (length entries))) + (switch-symlinks name prof) + (switch-symlinks profile name) + (maybe-register-gc-root store profile) + (format #t (N_ "~a package in profile~%" + "~a packages in profile~%" + count) + count) + (display-search-paths entries + profile)))))))))) + \f ;;; ;;; Entry point. @@ -742,65 +840,12 @@ removed from MANIFEST." %default-options #f)) - (define (ensure-default-profile) - ;; Ensure the default profile symlink and directory exist and are - ;; writable. - - (define (rtfm) - (format (current-error-port) - (_ "Try \"info '(guix) Invoking guix package'\" for \ -more information.~%")) - (exit 1)) - - ;; Create ~/.guix-profile if it doesn't exist yet. - (when (and %user-profile-directory - %current-profile - (not (false-if-exception - (lstat %user-profile-directory)))) - (symlink %current-profile %user-profile-directory)) - - (let ((s (stat %profile-directory #f))) - ;; Attempt to create /…/profiles/per-user/$USER if needed. - (unless (and s (eq? 'directory (stat:type s))) - (catch 'system-error - (lambda () - (mkdir-p %profile-directory)) - (lambda args - ;; Often, we cannot create %PROFILE-DIRECTORY because its - ;; parent directory is root-owned and we're running - ;; unprivileged. - (format (current-error-port) - (_ "error: while creating directory `~a': ~a~%") - %profile-directory - (strerror (system-error-errno args))) - (format (current-error-port) - (_ "Please create the `~a' directory, with you as the owner.~%") - %profile-directory) - (rtfm)))) - - ;; Bail out if it's not owned by the user. - (unless (or (not s) (= (stat:uid s) (getuid))) - (format (current-error-port) - (_ "error: directory `~a' is not owned by you~%") - %profile-directory) - (format (current-error-port) - (_ "Please change the owner of `~a' to user ~s.~%") - %profile-directory (or (getenv "USER") - (getenv "LOGNAME") - (getuid))) - (rtfm)))) - (define (process-actions opts) ;; Process any install/remove/upgrade action from OPTS. - (define dry-run? (assoc-ref opts 'dry-run?)) - (define profile (assoc-ref opts 'profile)) - - (define (same-package? entry name output) - (match entry - (($ <manifest-entry> entry-name _ entry-output _ ...) - (and (equal? name entry-name) - (equal? output entry-output))))) + (define substitutes? (assoc-ref opts 'substitutes?)) + (define dry-run? (assoc-ref opts 'dry-run?)) + (define profile (assoc-ref opts 'profile)) (define current-generation-number (generation-number profile)) @@ -869,61 +914,12 @@ more information.~%")) (_ #f)) opts)) (else - (let* ((manifest (profile-manifest profile)) - (install (options->installable opts manifest)) - (remove (options->removable opts manifest)) - (entries - (append install - (fold (lambda (package result) - (match package - (($ <manifest-entry> name _ out _ ...) - (filter (negate - (cut same-package? <> - name out)) - result)))) - (manifest-entries - (manifest-remove manifest remove)) - install))) - (new (make-manifest entries))) - - (when (equal? profile %current-profile) - (ensure-default-profile)) - - (unless (and (null? install) (null? remove)) - (let* ((prof-drv (run-with-store (%store) - (profile-derivation new))) - (prof (derivation->output-path prof-drv)) - (remove (manifest-matching-entries manifest remove))) - (show-what-to-remove/install remove install dry-run?) - (show-what-to-build (%store) (list prof-drv) - #:use-substitutes? - (assoc-ref opts 'substitutes?) - #:dry-run? dry-run?) - - (cond - (dry-run? #t) - ((and (file-exists? profile) - (and=> (readlink* profile) (cut string=? prof <>))) - (format (current-error-port) (_ "nothing to be done~%"))) - (else - (let* ((number (generation-number profile)) - - ;; Always use NUMBER + 1 for the new profile, - ;; possibly overwriting a "previous future - ;; generation". - (name (generation-file-name profile - (+ 1 number)))) - (and (build-derivations (%store) (list prof-drv)) - (let ((count (length entries))) - (switch-symlinks name prof) - (switch-symlinks profile name) - (maybe-register-gc-root (%store) profile) - (format #t (N_ "~a package in profile~%" - "~a packages in profile~%" - count) - count) - (display-search-paths entries - profile)))))))))))) + (process-package-actions + (%store) profile + #:install (options->installable opts (profile-manifest profile)) + #:remove (options->removable opts) + #:use-substitutes? substitutes? + #:dry-run? dry-run?)))) (define (process-query opts) ;; Process any query specified by OPTS. Return #t when a query was -- 2.0.3 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH] Emacs interface for Guix 2014-08-12 10:19 ` [PATCH] " Alex Kost @ 2014-08-12 14:19 ` Ludovic Courtès 2014-08-12 16:20 ` Alex Kost 0 siblings, 1 reply; 29+ messages in thread From: Ludovic Courtès @ 2014-08-12 14:19 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Alex Kost <alezost@gmail.com> skribis: > Thanks for pointing. I've never contributed to a real project, so I > don't know the rules actually :) No problem. :-) There might still be unwritten rules, but we can fix that as we go. > From af4b8495969d70d59aa9f3f296628daeaf80b0d2 Mon Sep 17 00:00:00 2001 > From: Alex Kost <alezost@gmail.com> > Date: Tue, 12 Aug 2014 12:32:16 +0400 > Subject: [PATCH 1/2] profiles: Add 'manifest-add'. > > * guix/profiles.scm (manifest-add): New procedure. > * tests/profiles.scm (guile-1.8.8): New variable. > ("manifest-add"): New test. Perfect. I’ve pushed it, followed by a patch that changes guix/scripts/package.scm to use ‘manifest-add’ (comments welcome.) > From 5fd45b3f4216921837f522d56b20c4be0a58fe8e Mon Sep 17 00:00:00 2001 > From: Alex Kost <alezost@gmail.com> > Date: Tue, 12 Aug 2014 13:54:23 +0400 > Subject: [PATCH 2/2] guix package: Add 'process-package-actions'. > > * guix/scripts/package.scm (process-package-actions): New procedure. > (guix-package): Use it. > [ensure-default-profile]: Move to top-level. > [substitutes?]: New variable. > [same-package?]: Remove. > (options->installable, options->removable): Change according to > 'process-package-actions'. This patch would need to be rebased on top of f48624f. Were you planning on using ‘process-package-actions’ in the Emacs interface? That seems like a coarse-grain and clumsy interface. Perhaps there are tinier parts of it that could be moved to (guix profiles)? For instance, there’s no ‘manifest-upgrade’ at the moment. What about introducing a <manifest-transaction> type that would contain a list of packages to install, to remove, and to upgrade, and we could do: ;; Show what will/would be installed, removed, etc. (show-transaction manifest transaction #:dry-run? bool) ;; Do the installation/removal/upgrades listed in TRANSACTION, and ;; return the new manifest. (manifest-perform-transaction manifest transaction) WDYT? Thanks, Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] Emacs interface for Guix 2014-08-12 14:19 ` Ludovic Courtès @ 2014-08-12 16:20 ` Alex Kost 2014-08-12 19:50 ` Ludovic Courtès 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-08-12 16:20 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel Ludovic Courtès (2014-08-12 18:19 +0400) wrote: > Alex Kost <alezost@gmail.com> skribis: > >> Thanks for pointing. I've never contributed to a real project, so I >> don't know the rules actually :) > > No problem. :-) There might still be unwritten rules, but we can fix > that as we go. > >> From af4b8495969d70d59aa9f3f296628daeaf80b0d2 Mon Sep 17 00:00:00 2001 >> From: Alex Kost <alezost@gmail.com> >> Date: Tue, 12 Aug 2014 12:32:16 +0400 >> Subject: [PATCH 1/2] profiles: Add 'manifest-add'. >> >> * guix/profiles.scm (manifest-add): New procedure. >> * tests/profiles.scm (guile-1.8.8): New variable. >> ("manifest-add"): New test. > > Perfect. I’ve pushed it, followed by a patch that changes > guix/scripts/package.scm to use ‘manifest-add’ (comments welcome.) Thanks, you forgot to delete ‘same-package?’ from ‘guix-package’ [‘process-actions’] in your commit – it is a part of ‘manifest-add’ now. >> From 5fd45b3f4216921837f522d56b20c4be0a58fe8e Mon Sep 17 00:00:00 2001 >> From: Alex Kost <alezost@gmail.com> >> Date: Tue, 12 Aug 2014 13:54:23 +0400 >> Subject: [PATCH 2/2] guix package: Add 'process-package-actions'. >> >> * guix/scripts/package.scm (process-package-actions): New procedure. >> (guix-package): Use it. >> [ensure-default-profile]: Move to top-level. >> [substitutes?]: New variable. >> [same-package?]: Remove. >> (options->installable, options->removable): Change according to >> 'process-package-actions'. > > This patch would need to be rebased on top of f48624f. > > Were you planning on using ‘process-package-actions’ in the Emacs > interface? Yes, actually I've been using that function for a couple of weeks, I just didn't update "guix.el" repo for that. But your suggestion below is definitely better. > That seems like a coarse-grain and clumsy interface. Perhaps there are > tinier parts of it that could be moved to (guix profiles)? For > instance, there’s no ‘manifest-upgrade’ at the moment. I think ‘manifest-add’ already does what ‘manifest-upgrade’ would do: it replaces entries with the same name. So if there is installed “guile-2.0.11:out” and a user installs “guile-1.8.8:out”, the previously installed guile is removed from manifest. I thought it's intended behaviour and that's why ‘options->installable’ combines “to-install” and “to-upgrade” options. Could you explain what ‘manifest-upgrade’ should do? > What about introducing a <manifest-transaction> type that would contain > a list of packages to install, to remove, and to upgrade, and we could do: I think only “install” part should contain a list of packages (or (PACKAGE OUTPUT) things). Upgrading and removing can be performed on obsolete packages, so only a package specification of an installed package is known in such cases. Perhaps any pattern (package (with "out" output), (package output), name specification) should be accepted. So there will be ‘make-manifest-transaction’ function with #:install, #:upgrade, #:remove keys. Do I understand it right? > ;; Show what will/would be installed, removed, etc. > (show-transaction manifest transaction #:dry-run? bool) > > ;; Do the installation/removal/upgrades listed in TRANSACTION, and > ;; return the new manifest. > (manifest-perform-transaction manifest transaction) So ‘manifest-perform-transaction’ will open connection? If so, shouldn't it accept '#:dry-run' and '#:use-substitutes?' keys? -- Alex ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] Emacs interface for Guix 2014-08-12 16:20 ` Alex Kost @ 2014-08-12 19:50 ` Ludovic Courtès 2014-08-13 6:57 ` Alex Kost 0 siblings, 1 reply; 29+ messages in thread From: Ludovic Courtès @ 2014-08-12 19:50 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Alex Kost <alezost@gmail.com> skribis: > Ludovic Courtès (2014-08-12 18:19 +0400) wrote: [...] >> Perfect. I’ve pushed it, followed by a patch that changes >> guix/scripts/package.scm to use ‘manifest-add’ (comments welcome.) > > Thanks, you forgot to delete ‘same-package?’ from ‘guix-package’ > [‘process-actions’] in your commit – it is a part of ‘manifest-add’ now. Oops, fixed now. >>> From 5fd45b3f4216921837f522d56b20c4be0a58fe8e Mon Sep 17 00:00:00 2001 >>> From: Alex Kost <alezost@gmail.com> >>> Date: Tue, 12 Aug 2014 13:54:23 +0400 >>> Subject: [PATCH 2/2] guix package: Add 'process-package-actions'. >>> >>> * guix/scripts/package.scm (process-package-actions): New procedure. >>> (guix-package): Use it. >>> [ensure-default-profile]: Move to top-level. >>> [substitutes?]: New variable. >>> [same-package?]: Remove. >>> (options->installable, options->removable): Change according to >>> 'process-package-actions'. >> >> This patch would need to be rebased on top of f48624f. >> >> Were you planning on using ‘process-package-actions’ in the Emacs >> interface? > > Yes, actually I've been using that function for a couple of weeks, I > just didn't update "guix.el" repo for that. But your suggestion below > is definitely better. Cool. >> That seems like a coarse-grain and clumsy interface. Perhaps there are >> tinier parts of it that could be moved to (guix profiles)? For >> instance, there’s no ‘manifest-upgrade’ at the moment. > > I think ‘manifest-add’ already does what ‘manifest-upgrade’ would do: it > replaces entries with the same name. So if there is installed > “guile-2.0.11:out” and a user installs “guile-1.8.8:out”, the previously > installed guile is removed from manifest. I thought it's intended > behaviour and that's why ‘options->installable’ combines “to-install” > and “to-upgrade” options. Could you explain what ‘manifest-upgrade’ > should do? Oh you’re right, currently upgrade and install are basically the same thing. >> What about introducing a <manifest-transaction> type that would contain >> a list of packages to install, to remove, and to upgrade, and we could do: > > I think only “install” part should contain a list of packages (or > (PACKAGE OUTPUT) things). Upgrading and removing can be performed on > obsolete packages, so only a package specification of an installed > package is known in such cases. Perhaps any pattern (package (with > "out" output), (package output), name specification) should be accepted. The arguments should be the same as (or compatible) for ‘manifest-add’ and ‘manifest-remove’. So the list of packages could be installed could be a list of (PACKAGE OUTPUT) as you note. The list of packages to upgrade could a list of (PACKAGE OUTPUT) as well, computed by ‘guix package’ or guix.el. (The difficulty here is that (guix profiles) should not depend on (gnu packages).) The list of packages to remove should be a list of <manifest-pattern>. > So there will be ‘make-manifest-transaction’ function with #:install, > #:upgrade, #:remove keys. Do I understand it right? Rather, use (define-record-type* <manifest-transaction> ...), so we can then write: (manifest-transaction (install lst1) (remove lst2) ...) >> ;; Show what will/would be installed, removed, etc. >> (show-transaction manifest transaction #:dry-run? bool) >> >> ;; Do the installation/removal/upgrades listed in TRANSACTION, and >> ;; return the new manifest. >> (manifest-perform-transaction manifest transaction) > > So ‘manifest-perform-transaction’ will open connection? If so, > shouldn't it accept '#:dry-run' and '#:use-substitutes?' keys? No, it would just return the new manifest, built by successive calls to ‘manifest-add’ and ‘manifest-remove’. Very simple. The actual profile is still built with ‘profile-derivation’. Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] Emacs interface for Guix 2014-08-12 19:50 ` Ludovic Courtès @ 2014-08-13 6:57 ` Alex Kost 2014-08-13 16:03 ` Ludovic Courtès 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-08-13 6:57 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel [-- Attachment #1: Type: text/plain, Size: 2454 bytes --] Ludovic Courtès (2014-08-12 23:50 +0400) wrote: [...] >>> What about introducing a <manifest-transaction> type that would contain >>> a list of packages to install, to remove, and to upgrade, and we could do: >> >> I think only “install” part should contain a list of packages (or >> (PACKAGE OUTPUT) things). Upgrading and removing can be performed on >> obsolete packages, so only a package specification of an installed >> package is known in such cases. Perhaps any pattern (package (with >> "out" output), (package output), name specification) should be accepted. > > The arguments should be the same as (or compatible) for ‘manifest-add’ > and ‘manifest-remove’. > > So the list of packages could be installed could be a list of (PACKAGE > OUTPUT) as you note. > > The list of packages to upgrade could a list of (PACKAGE OUTPUT) as > well, computed by ‘guix package’ or guix.el. (The difficulty here is > that (guix profiles) should not depend on (gnu packages).) > > The list of packages to remove should be a list of <manifest-pattern>. > >> So there will be ‘make-manifest-transaction’ function with #:install, >> #:upgrade, #:remove keys. Do I understand it right? > > Rather, use (define-record-type* <manifest-transaction> ...), so we can > then write: > > (manifest-transaction > (install lst1) > (remove lst2) > ...) > >>> ;; Show what will/would be installed, removed, etc. >>> (show-transaction manifest transaction #:dry-run? bool) >>> >>> ;; Do the installation/removal/upgrades listed in TRANSACTION, and >>> ;; return the new manifest. >>> (manifest-perform-transaction manifest transaction) >> >> So ‘manifest-perform-transaction’ will open connection? If so, >> shouldn't it accept '#:dry-run' and '#:use-substitutes?' keys? > > No, it would just return the new manifest, built by successive calls to > ‘manifest-add’ and ‘manifest-remove’. Very simple. > > The actual profile is still built with ‘profile-derivation’. I realized there could be a problem with (PACKAGE OUTPUT) elements. They should be transformed into manifest entries, but "guix/scripts/package.scm" uses ‘package->manifest-entry*’ for that, so this cannot be performed in (guix profiles) module. Perhaps “install” should just contain a list of manifest entries. WDYT? And manifest-transaction stuff could look like this: [-- Attachment #2: Type: text/plain, Size: 2584 bytes --] (define-record-type* <manifest-transaction> manifest-transaction make-manifest-transaction manifest-transaction? (install manifest-transaction-install ; list of <manifest-entry> (default '())) (remove manifest-transaction-remove ; list of <manifest-pattern> (default '()))) (define (manifest-perform-transaction manifest transaction) "Perform TRANSACTION on MANIFEST and return new manifest." (let ((install (manifest-transaction-install transaction)) (remove (manifest-transaction-remove transaction))) (manifest-add (manifest-remove manifest remove) install))) (define* (show-transaction manifest transaction #:key dry-run?) "Display what will/would be installed/removed from MANIFEST by TRANSACTION." (let ((install (manifest-transaction-install transaction)) (remove (manifest-matching-entries manifest (manifest-transaction-remove transaction)))) (match remove ((($ <manifest-entry> name version output path _) ..1) (let ((len (length name)) (remove (map (cut format #f " ~a-~a\t~a\t~a" <> <> <> <>) name version output path))) (if dry-run? (format (current-error-port) (N_ "The following package would be removed:~%~{~a~%~}~%" "The following packages would be removed:~%~{~a~%~}~%" len) remove) (format (current-error-port) (N_ "The following package will be removed:~%~{~a~%~}~%" "The following packages will be removed:~%~{~a~%~}~%" len) remove)))) (_ #f)) (match install ((($ <manifest-entry> name version output path _) ..1) (let ((len (length name)) (install (map (cut format #f " ~a-~a\t~a\t~a" <> <> <> <>) name version output path))) (if dry-run? (format (current-error-port) (N_ "The following package would be installed:~%~{~a~%~}~%" "The following packages would be installed:~%~{~a~%~}~%" len) install) (format (current-error-port) (N_ "The following package will be installed:~%~{~a~%~}~%" "The following packages will be installed:~%~{~a~%~}~%" len) install)))) (_ #f)))) [-- Attachment #3: Type: text/plain, Size: 298 bytes --] (I excluded “upgrade” part as it's the same as “install”, and ‘show-transaction’ is almost the same as ‘show-what-to-remove/install’ from "package.scm".) Also I think "guix.el" should check for freshness too, so ‘check-package-freshness’ should probably be exported. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] Emacs interface for Guix 2014-08-13 6:57 ` Alex Kost @ 2014-08-13 16:03 ` Ludovic Courtès 2014-08-13 20:58 ` Alex Kost 0 siblings, 1 reply; 29+ messages in thread From: Ludovic Courtès @ 2014-08-13 16:03 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Alex Kost <alezost@gmail.com> skribis: > I realized there could be a problem with (PACKAGE OUTPUT) elements. > They should be transformed into manifest entries, but > "guix/scripts/package.scm" uses ‘package->manifest-entry*’ for that, so > this cannot be performed in (guix profiles) module. Perhaps “install” > should just contain a list of manifest entries. WDYT? Yes, that’s fine too. > And manifest-transaction stuff could look like this: > > (define-record-type* <manifest-transaction> manifest-transaction > make-manifest-transaction > manifest-transaction? > (install manifest-transaction-install ; list of <manifest-entry> > (default '())) > (remove manifest-transaction-remove ; list of <manifest-pattern> > (default '()))) > > (define (manifest-perform-transaction manifest transaction) > "Perform TRANSACTION on MANIFEST and return new manifest." > (let ((install (manifest-transaction-install transaction)) > (remove (manifest-transaction-remove transaction))) > (manifest-add (manifest-remove manifest remove) > install))) > > (define* (show-transaction manifest transaction #:key dry-run?) > "Display what will/would be installed/removed from MANIFEST by TRANSACTION." > (let ((install (manifest-transaction-install transaction)) > (remove (manifest-matching-entries > manifest > (manifest-transaction-remove transaction)))) > (match remove > ((($ <manifest-entry> name version output path _) ..1) > (let ((len (length name)) > (remove (map (cut format #f " ~a-~a\t~a\t~a" <> <> <> <>) > name version output path))) > (if dry-run? > (format (current-error-port) > (N_ "The following package would be removed:~%~{~a~%~}~%" > "The following packages would be removed:~%~{~a~%~}~%" > len) > remove) > (format (current-error-port) > (N_ "The following package will be removed:~%~{~a~%~}~%" > "The following packages will be removed:~%~{~a~%~}~%" > len) > remove)))) > (_ #f)) > (match install > ((($ <manifest-entry> name version output path _) ..1) > (let ((len (length name)) > (install (map (cut format #f " ~a-~a\t~a\t~a" <> <> <> <>) > name version output path))) > (if dry-run? > (format (current-error-port) > (N_ "The following package would be installed:~%~{~a~%~}~%" > "The following packages would be installed:~%~{~a~%~}~%" > len) > install) > (format (current-error-port) > (N_ "The following package will be installed:~%~{~a~%~}~%" > "The following packages will be installed:~%~{~a~%~}~%" > len) > install)))) > (_ #f)))) Looks good! > (I excluded “upgrade” part as it's the same as “install”, and > ‘show-transaction’ is almost the same as ‘show-what-to-remove/install’ > from "package.scm".) Yes. Could you turn the above thing into a patch with a commit log? Bonus points for ‘manifest-perform-transaction’ unit tests. Make sure to add a copyright line for yourself in profiles.scm. And then a second patch to actually use it in (guix scripts package) would be wonderful. :-) In the next iteration, ‘show-what-to-remove/install’ should report packages that are going to be upgraded (by checking among ‘install’ those are already in the manifest.) > Also I think "guix.el" should check for freshness too, so > ‘check-package-freshness’ should probably be exported. Yes, probably in the (gnu packages) module? Thanks, Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] Emacs interface for Guix 2014-08-13 16:03 ` Ludovic Courtès @ 2014-08-13 20:58 ` Alex Kost 2014-08-16 12:24 ` Ludovic Courtès 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-08-13 20:58 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel [-- Attachment #1: Type: text/plain, Size: 1625 bytes --] Ludovic Courtès (2014-08-13 20:03 +0400) wrote: > Alex Kost <alezost@gmail.com> skribis: > > [...] > >> (I excluded “upgrade” part as it's the same as “install”, and >> ‘show-transaction’ is almost the same as ‘show-what-to-remove/install’ >> from "package.scm".) > > Yes. > > Could you turn the above thing into a patch with a commit log? Bonus > points for ‘manifest-perform-transaction’ unit tests. Make sure to add > a copyright line for yourself in profiles.scm. > > And then a second patch to actually use it in (guix scripts package) > would be wonderful. :-) Ok, I'm attaching these patches. But there are several issues there: - I fixed a typo in "tests/profiles.scm" (“profile” -> “profiles”) – Is it ok to do this in that commit or should there be a separate commit? - I added a copyright line to the test file as well. Is it ok? - The main thing: look at ‘manifest-show-transaction’ – unlike ‘show-what-to-remove/install’ it doesn't display an output path of a package item, because a store should be used for that. So is it acceptable or should something be changed there? > In the next iteration, ‘show-what-to-remove/install’ should report > packages that are going to be upgraded (by checking among ‘install’ > those are already in the manifest.) I'll try to do this. >> Also I think "guix.el" should check for freshness too, so >> ‘check-package-freshness’ should probably be exported. > > Yes, probably in the (gnu packages) module? Probably, but I think I'm not competent to decide :) [-- Attachment #2: 0001-profiles-Add-manifest-transaction.patch --] [-- Type: text/x-patch, Size: 6630 bytes --] From d2d3f9d296c26ad1d4a1e17d56ae3e3361ca02d7 Mon Sep 17 00:00:00 2001 From: Alex Kost <alezost@gmail.com> Date: Thu, 14 Aug 2014 00:03:53 +0400 Subject: [PATCH 1/2] profiles: Add 'manifest-transaction'. * guix/profiles.scm (<manifest-transaction>): New record-type. (manifest-perform-transaction): New procedure. (manifest-show-transaction): New procedure. * tests/profiles.scm ("manifest-perform-transaction"): New test. --- guix/profiles.scm | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/profiles.scm | 22 +++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/guix/profiles.scm b/guix/profiles.scm index e921566..55a3348 100644 --- a/guix/profiles.scm +++ b/guix/profiles.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org> +;;; Copyright © 2014 Alex Kost <alezost@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;; @@ -18,6 +19,7 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (guix profiles) + #:use-module (guix ui) #:use-module (guix utils) #:use-module (guix records) #:use-module (guix derivations) @@ -51,6 +53,13 @@ manifest-installed? manifest-matching-entries + manifest-transaction + manifest-transaction? + manifest-transaction-install + manifest-transaction-remove + manifest-perform-transaction + manifest-show-transaction + profile-manifest package->manifest-entry profile-derivation @@ -244,6 +253,72 @@ Remove MANIFEST entries that have the same name and output as ENTRIES." \f ;;; +;;; Manifest transactions. +;;; + +(define-record-type* <manifest-transaction> manifest-transaction + make-manifest-transaction + manifest-transaction? + (install manifest-transaction-install ; list of <manifest-entry> + (default '())) + (remove manifest-transaction-remove ; list of <manifest-pattern> + (default '()))) + +(define (manifest-perform-transaction manifest transaction) + "Perform TRANSACTION on MANIFEST and return new manifest." + (let ((install (manifest-transaction-install transaction)) + (remove (manifest-transaction-remove transaction))) + (manifest-add (manifest-remove manifest remove) + install))) + +(define* (manifest-show-transaction manifest transaction #:key dry-run?) + "Display what will/would be installed/removed from MANIFEST by TRANSACTION." + ;; TODO: Report upgrades more clearly. + (let ((install (manifest-transaction-install transaction)) + (remove (manifest-matching-entries + manifest (manifest-transaction-remove transaction)))) + (match remove + ((($ <manifest-entry> name version output path _) ..1) + (let ((len (length name)) + (remove (map (cut format #f " ~a-~a\t~a\t~a" <> <> <> <>) + name version output path))) + (if dry-run? + (format (current-error-port) + (N_ "The following package would be removed:~%~{~a~%~}~%" + "The following packages would be removed:~%~{~a~%~}~%" + len) + remove) + (format (current-error-port) + (N_ "The following package will be removed:~%~{~a~%~}~%" + "The following packages will be removed:~%~{~a~%~}~%" + len) + remove)))) + (_ #f)) + (match install + ((($ <manifest-entry> name version output item _) ..1) + (let ((len (length name)) + (install (map (lambda (name version output item) + (if (package? item) + (format #f " ~a-~a\t~a" + name version output) + (format #f " ~a-~a\t~a\t~a" + name version output item))) + name version output item))) + (if dry-run? + (format (current-error-port) + (N_ "The following package would be installed:~%~{~a~%~}~%" + "The following packages would be installed:~%~{~a~%~}~%" + len) + install) + (format (current-error-port) + (N_ "The following package will be installed:~%~{~a~%~}~%" + "The following packages will be installed:~%~{~a~%~}~%" + len) + install)))) + (_ #f)))) + +\f +;;; ;;; Profiles. ;;; diff --git a/tests/profiles.scm b/tests/profiles.scm index b2919d7..e1f1eef 100644 --- a/tests/profiles.scm +++ b/tests/profiles.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2014 Alex Kost <alezost@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;; @@ -26,7 +27,7 @@ #:use-module (ice-9 match) #:use-module (srfi srfi-64)) -;; Test the (guix profile) module. +;; Test the (guix profiles) module. (define %store (open-connection)) @@ -122,6 +123,25 @@ (_ #f)) (equal? m3 m4)))) +(test-assert "manifest-perform-transaction" + (let* ((m0 (manifest (list guile-2.0.9 guile-2.0.9:debug))) + (t1 (manifest-transaction + (install (list guile-1.8.8)) + (remove (list (manifest-pattern (name "guile") + (output "debug")))))) + (t2 (manifest-transaction + (remove (list (manifest-pattern (name "guile") + (version "2.0.9") + (output #f)))))) + (m1 (manifest-perform-transaction m0 t1)) + (m2 (manifest-perform-transaction m1 t2)) + (m3 (manifest-perform-transaction m0 t2))) + (and (match (manifest-entries m1) + ((($ <manifest-entry> "guile" "1.8.8" "out")) #t) + (_ #f)) + (equal? m1 m2) + (null? (manifest-entries m3))))) + (test-assert "profile-derivation" (run-with-store %store (mlet* %store-monad -- 2.0.3 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #3: 0002-guix-package-Use-manifest-transaction.patch --] [-- Type: text/x-patch, Size: 4669 bytes --] From 5358263f259ea099bbcb62a6bc548c6c9fdb1567 Mon Sep 17 00:00:00 2001 From: Alex Kost <alezost@gmail.com> Date: Thu, 14 Aug 2014 00:15:48 +0400 Subject: [PATCH 2/2] guix package: Use 'manifest-transaction'. * guix/scripts/package.scm (guix-package)[process-actions]: Use 'manifest-transaction' instead of the equivalent code. (show-what-to-remove/install): Remove. --- guix/scripts/package.scm | 60 ++++++++---------------------------------------- 1 file changed, 10 insertions(+), 50 deletions(-) diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm index 3bfef4f..b7bdadc 100644 --- a/guix/scripts/package.scm +++ b/guix/scripts/package.scm @@ -184,49 +184,6 @@ DURATION-RELATION with the current time." filter-by-duration) (else #f))) -(define (show-what-to-remove/install remove install dry-run?) - "Given the manifest entries listed in REMOVE and INSTALL, display the -packages that will/would be installed and removed." - ;; TODO: Report upgrades more clearly. - (match remove - ((($ <manifest-entry> name version output path _) ..1) - (let ((len (length name)) - (remove (map (cut format #f " ~a-~a\t~a\t~a" <> <> <> <>) - name version output path))) - (if dry-run? - (format (current-error-port) - (N_ "The following package would be removed:~%~{~a~%~}~%" - "The following packages would be removed:~%~{~a~%~}~%" - len) - remove) - (format (current-error-port) - (N_ "The following package will be removed:~%~{~a~%~}~%" - "The following packages will be removed:~%~{~a~%~}~%" - len) - remove)))) - (_ #f)) - (match install - ((($ <manifest-entry> name version output item _) ..1) - (let ((len (length name)) - (install (map (lambda (name version output item) - (format #f " ~a-~a\t~a\t~a" name version output - (if (package? item) - (package-output (%store) item output) - item))) - name version output item))) - (if dry-run? - (format (current-error-port) - (N_ "The following package would be installed:~%~{~a~%~}~%" - "The following packages would be installed:~%~{~a~%~}~%" - len) - install) - (format (current-error-port) - (N_ "The following package will be installed:~%~{~a~%~}~%" - "The following packages will be installed:~%~{~a~%~}~%" - len) - install)))) - (_ #f))) - \f ;;; ;;; Package specifications. @@ -863,21 +820,24 @@ more information.~%")) (_ #f)) opts)) (else - (let* ((manifest (profile-manifest profile)) - (install (options->installable opts manifest)) - (remove (options->removable opts manifest)) - (new (manifest-add (manifest-remove manifest remove) - install))) + (let* ((manifest (profile-manifest profile)) + (install (options->installable opts manifest)) + (remove (options->removable opts manifest)) + (transaction (manifest-transaction (install install) + (remove remove))) + (new (manifest-perform-transaction + manifest transaction))) (when (equal? profile %current-profile) (ensure-default-profile)) (unless (and (null? install) (null? remove)) (let* ((prof-drv (run-with-store (%store) - (profile-derivation new))) + (profile-derivation new))) (prof (derivation->output-path prof-drv)) (remove (manifest-matching-entries manifest remove))) - (show-what-to-remove/install remove install dry-run?) + (manifest-show-transaction manifest transaction + #:dry-run? dry-run?) (show-what-to-build (%store) (list prof-drv) #:use-substitutes? (assoc-ref opts 'substitutes?) -- 2.0.3 [-- Attachment #4: Type: text/plain, Size: 14 bytes --] -- Alex Kost ^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH] Emacs interface for Guix 2014-08-13 20:58 ` Alex Kost @ 2014-08-16 12:24 ` Ludovic Courtès 2014-08-16 13:07 ` Alex Kost 0 siblings, 1 reply; 29+ messages in thread From: Ludovic Courtès @ 2014-08-16 12:24 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel (Sorry for replying to messages in the wrong order. :-)) Alex Kost <alezost@gmail.com> skribis: > Ok, I'm attaching these patches. But there are several issues there: > > - I fixed a typo in "tests/profiles.scm" (“profile” -> “profiles”) – Is > it ok to do this in that commit or should there be a separate commit? No that’s OK. > - I added a copyright line to the test file as well. Is it ok? Sure! > - The main thing: look at ‘manifest-show-transaction’ – unlike > ‘show-what-to-remove/install’ it doesn't display an output path of a > package item, because a store should be used for that. So is it > acceptable or should something be changed there? I think it should be changed to display the same thing as before. What about adding just a ‘store’ parameter to ‘manifest-show-transaction’, and then just use the same code as ‘show-what-to-remove/install’? Other than that the two patches look good, so if you make that change, we can go ahead. >>> Also I think "guix.el" should check for freshness too, so >>> ‘check-package-freshness’ should probably be exported. >> >> Yes, probably in the (gnu packages) module? > > Probably, but I think I'm not competent to decide :) Well, take it as a suggestion then. :-) Thanks, Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] Emacs interface for Guix 2014-08-16 12:24 ` Ludovic Courtès @ 2014-08-16 13:07 ` Alex Kost 2014-08-19 21:00 ` Ludovic Courtès 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-08-16 13:07 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel [-- Attachment #1: Type: text/plain, Size: 1706 bytes --] Ludovic Courtès (2014-08-16 16:24 +0400) wrote: > (Sorry for replying to messages in the wrong order. :-)) Sorry, I had sent old patches before you sent this message :) Ignore my previous message (with the subject "[PATCH] manifest-transaction") please. > Alex Kost <alezost@gmail.com> skribis: > >> Ok, I'm attaching these patches. But there are several issues there: >> >> - I fixed a typo in "tests/profiles.scm" (“profile” -> “profiles”) – Is >> it ok to do this in that commit or should there be a separate commit? > > No that’s OK. > >> - I added a copyright line to the test file as well. Is it ok? > > Sure! > >> - The main thing: look at ‘manifest-show-transaction’ – unlike >> ‘show-what-to-remove/install’ it doesn't display an output path of a >> package item, because a store should be used for that. So is it >> acceptable or should something be changed there? > > I think it should be changed to display the same thing as before. What > about adding just a ‘store’ parameter to ‘manifest-show-transaction’, > and then just use the same code as ‘show-what-to-remove/install’? > > Other than that the two patches look good, so if you make that change, > we can go ahead. I've made the change (the ‘store’ argument is added now). The patches are attached. >>>> Also I think "guix.el" should check for freshness too, so >>>> ‘check-package-freshness’ should probably be exported. >>> >>> Yes, probably in the (gnu packages) module? >> >> Probably, but I think I'm not competent to decide :) > > Well, take it as a suggestion then. :-) OK, I'll send a patch for that later. Thanks. [-- Attachment #2: 0001-profiles-Add-manifest-transaction.patch --] [-- Type: text/x-patch, Size: 6631 bytes --] From 7641752189cfc4ad3c85a042ea9eeea2b39435b4 Mon Sep 17 00:00:00 2001 From: Alex Kost <alezost@gmail.com> Date: Thu, 14 Aug 2014 00:03:53 +0400 Subject: [PATCH 1/2] profiles: Add 'manifest-transaction'. * guix/profiles.scm (<manifest-transaction>): New record-type. (manifest-perform-transaction): New procedure. (manifest-show-transaction): New procedure. * tests/profiles.scm ("manifest-perform-transaction"): New test. --- guix/profiles.scm | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/profiles.scm | 22 +++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/guix/profiles.scm b/guix/profiles.scm index e921566..2398b89 100644 --- a/guix/profiles.scm +++ b/guix/profiles.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org> +;;; Copyright © 2014 Alex Kost <alezost@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;; @@ -18,6 +19,7 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (guix profiles) + #:use-module (guix ui) #:use-module (guix utils) #:use-module (guix records) #:use-module (guix derivations) @@ -51,6 +53,13 @@ manifest-installed? manifest-matching-entries + manifest-transaction + manifest-transaction? + manifest-transaction-install + manifest-transaction-remove + manifest-perform-transaction + manifest-show-transaction + profile-manifest package->manifest-entry profile-derivation @@ -244,6 +253,72 @@ Remove MANIFEST entries that have the same name and output as ENTRIES." \f ;;; +;;; Manifest transactions. +;;; + +(define-record-type* <manifest-transaction> manifest-transaction + make-manifest-transaction + manifest-transaction? + (install manifest-transaction-install ; list of <manifest-entry> + (default '())) + (remove manifest-transaction-remove ; list of <manifest-pattern> + (default '()))) + +(define (manifest-perform-transaction manifest transaction) + "Perform TRANSACTION on MANIFEST and return new manifest." + (let ((install (manifest-transaction-install transaction)) + (remove (manifest-transaction-remove transaction))) + (manifest-add (manifest-remove manifest remove) + install))) + +(define* (manifest-show-transaction manifest transaction store + #:key dry-run?) + "Display what will/would be installed/removed from MANIFEST by TRANSACTION." + ;; TODO: Report upgrades more clearly. + (let ((install (manifest-transaction-install transaction)) + (remove (manifest-matching-entries + manifest (manifest-transaction-remove transaction)))) + (match remove + ((($ <manifest-entry> name version output path _) ..1) + (let ((len (length name)) + (remove (map (cut format #f " ~a-~a\t~a\t~a" <> <> <> <>) + name version output path))) + (if dry-run? + (format (current-error-port) + (N_ "The following package would be removed:~%~{~a~%~}~%" + "The following packages would be removed:~%~{~a~%~}~%" + len) + remove) + (format (current-error-port) + (N_ "The following package will be removed:~%~{~a~%~}~%" + "The following packages will be removed:~%~{~a~%~}~%" + len) + remove)))) + (_ #f)) + (match install + ((($ <manifest-entry> name version output item _) ..1) + (let ((len (length name)) + (install (map (lambda (name version output item) + (format #f " ~a-~a\t~a\t~a" name version output + (if (package? item) + (package-output store item output) + item))) + name version output item))) + (if dry-run? + (format (current-error-port) + (N_ "The following package would be installed:~%~{~a~%~}~%" + "The following packages would be installed:~%~{~a~%~}~%" + len) + install) + (format (current-error-port) + (N_ "The following package will be installed:~%~{~a~%~}~%" + "The following packages will be installed:~%~{~a~%~}~%" + len) + install)))) + (_ #f)))) + +\f +;;; ;;; Profiles. ;;; diff --git a/tests/profiles.scm b/tests/profiles.scm index b2919d7..e1f1eef 100644 --- a/tests/profiles.scm +++ b/tests/profiles.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2014 Alex Kost <alezost@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;; @@ -26,7 +27,7 @@ #:use-module (ice-9 match) #:use-module (srfi srfi-64)) -;; Test the (guix profile) module. +;; Test the (guix profiles) module. (define %store (open-connection)) @@ -122,6 +123,25 @@ (_ #f)) (equal? m3 m4)))) +(test-assert "manifest-perform-transaction" + (let* ((m0 (manifest (list guile-2.0.9 guile-2.0.9:debug))) + (t1 (manifest-transaction + (install (list guile-1.8.8)) + (remove (list (manifest-pattern (name "guile") + (output "debug")))))) + (t2 (manifest-transaction + (remove (list (manifest-pattern (name "guile") + (version "2.0.9") + (output #f)))))) + (m1 (manifest-perform-transaction m0 t1)) + (m2 (manifest-perform-transaction m1 t2)) + (m3 (manifest-perform-transaction m0 t2))) + (and (match (manifest-entries m1) + ((($ <manifest-entry> "guile" "1.8.8" "out")) #t) + (_ #f)) + (equal? m1 m2) + (null? (manifest-entries m3))))) + (test-assert "profile-derivation" (run-with-store %store (mlet* %store-monad -- 2.0.3 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #3: 0002-guix-package-Use-manifest-transaction.patch --] [-- Type: text/x-patch, Size: 4748 bytes --] From 9bc3426a4550fe7e28a4c9ff807e3650f0ab1b92 Mon Sep 17 00:00:00 2001 From: Alex Kost <alezost@gmail.com> Date: Thu, 14 Aug 2014 00:15:48 +0400 Subject: [PATCH 2/2] guix package: Use 'manifest-transaction'. * guix/scripts/package.scm (guix-package)[process-actions]: Use 'manifest-transaction' instead of the equivalent code. (show-what-to-remove/install): Remove. --- guix/scripts/package.scm | 63 +++++++++--------------------------------------- 1 file changed, 11 insertions(+), 52 deletions(-) diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm index 3bfef4f..e17ae18 100644 --- a/guix/scripts/package.scm +++ b/guix/scripts/package.scm @@ -184,49 +184,6 @@ DURATION-RELATION with the current time." filter-by-duration) (else #f))) -(define (show-what-to-remove/install remove install dry-run?) - "Given the manifest entries listed in REMOVE and INSTALL, display the -packages that will/would be installed and removed." - ;; TODO: Report upgrades more clearly. - (match remove - ((($ <manifest-entry> name version output path _) ..1) - (let ((len (length name)) - (remove (map (cut format #f " ~a-~a\t~a\t~a" <> <> <> <>) - name version output path))) - (if dry-run? - (format (current-error-port) - (N_ "The following package would be removed:~%~{~a~%~}~%" - "The following packages would be removed:~%~{~a~%~}~%" - len) - remove) - (format (current-error-port) - (N_ "The following package will be removed:~%~{~a~%~}~%" - "The following packages will be removed:~%~{~a~%~}~%" - len) - remove)))) - (_ #f)) - (match install - ((($ <manifest-entry> name version output item _) ..1) - (let ((len (length name)) - (install (map (lambda (name version output item) - (format #f " ~a-~a\t~a\t~a" name version output - (if (package? item) - (package-output (%store) item output) - item))) - name version output item))) - (if dry-run? - (format (current-error-port) - (N_ "The following package would be installed:~%~{~a~%~}~%" - "The following packages would be installed:~%~{~a~%~}~%" - len) - install) - (format (current-error-port) - (N_ "The following package will be installed:~%~{~a~%~}~%" - "The following packages will be installed:~%~{~a~%~}~%" - len) - install)))) - (_ #f))) - \f ;;; ;;; Package specifications. @@ -863,21 +820,23 @@ more information.~%")) (_ #f)) opts)) (else - (let* ((manifest (profile-manifest profile)) - (install (options->installable opts manifest)) - (remove (options->removable opts manifest)) - (new (manifest-add (manifest-remove manifest remove) - install))) + (let* ((manifest (profile-manifest profile)) + (install (options->installable opts manifest)) + (remove (options->removable opts manifest)) + (transaction (manifest-transaction (install install) + (remove remove))) + (new (manifest-perform-transaction + manifest transaction))) (when (equal? profile %current-profile) (ensure-default-profile)) (unless (and (null? install) (null? remove)) (let* ((prof-drv (run-with-store (%store) - (profile-derivation new))) - (prof (derivation->output-path prof-drv)) - (remove (manifest-matching-entries manifest remove))) - (show-what-to-remove/install remove install dry-run?) + (profile-derivation new))) + (prof (derivation->output-path prof-drv))) + (manifest-show-transaction manifest transaction (%store) + #:dry-run? dry-run?) (show-what-to-build (%store) (list prof-drv) #:use-substitutes? (assoc-ref opts 'substitutes?) -- 2.0.3 [-- Attachment #4: Type: text/plain, Size: 9 bytes --] -- Alex ^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH] Emacs interface for Guix 2014-08-16 13:07 ` Alex Kost @ 2014-08-19 21:00 ` Ludovic Courtès 2014-08-20 10:54 ` Alex Kost 0 siblings, 1 reply; 29+ messages in thread From: Ludovic Courtès @ 2014-08-19 21:00 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Alex Kost <alezost@gmail.com> skribis: > From 7641752189cfc4ad3c85a042ea9eeea2b39435b4 Mon Sep 17 00:00:00 2001 > From: Alex Kost <alezost@gmail.com> > Date: Thu, 14 Aug 2014 00:03:53 +0400 > Subject: [PATCH 1/2] profiles: Add 'manifest-transaction'. > > * guix/profiles.scm (<manifest-transaction>): New record-type. > (manifest-perform-transaction): New procedure. > (manifest-show-transaction): New procedure. > * tests/profiles.scm ("manifest-perform-transaction"): New test. Applied with two minor changes: use (ice-9 format), as reported by -Wformat, and move the ‘store’ argument first for consistency. > From 9bc3426a4550fe7e28a4c9ff807e3650f0ab1b92 Mon Sep 17 00:00:00 2001 > From: Alex Kost <alezost@gmail.com> > Date: Thu, 14 Aug 2014 00:15:48 +0400 > Subject: [PATCH 2/2] guix package: Use 'manifest-transaction'. > > * guix/scripts/package.scm (guix-package)[process-actions]: Use > 'manifest-transaction' instead of the equivalent code. > (show-what-to-remove/install): Remove. Applied, with the store argument first. Thanks! Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-08-19 21:00 ` Ludovic Courtès @ 2014-08-20 10:54 ` Alex Kost 2014-08-22 8:56 ` Ludovic Courtès 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-08-20 10:54 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel Ludovic Courtès (2014-08-20 01:00 +0400) wrote: > Alex Kost <alezost@gmail.com> skribis: > >> From 7641752189cfc4ad3c85a042ea9eeea2b39435b4 Mon Sep 17 00:00:00 2001 >> From: Alex Kost <alezost@gmail.com> >> Date: Thu, 14 Aug 2014 00:03:53 +0400 >> Subject: [PATCH 1/2] profiles: Add 'manifest-transaction'. >> >> * guix/profiles.scm (<manifest-transaction>): New record-type. >> (manifest-perform-transaction): New procedure. >> (manifest-show-transaction): New procedure. >> * tests/profiles.scm ("manifest-perform-transaction"): New test. > > Applied with two minor changes: use (ice-9 format), as reported by > -Wformat, and move the ‘store’ argument first for consistency. > >> From 9bc3426a4550fe7e28a4c9ff807e3650f0ab1b92 Mon Sep 17 00:00:00 2001 >> From: Alex Kost <alezost@gmail.com> >> Date: Thu, 14 Aug 2014 00:15:48 +0400 >> Subject: [PATCH 2/2] guix package: Use 'manifest-transaction'. >> >> * guix/scripts/package.scm (guix-package)[process-actions]: Use >> 'manifest-transaction' instead of the equivalent code. >> (show-what-to-remove/install): Remove. > > Applied, with the store argument first. Thanks, now (with the latest “guix pull”), installing/upgrading/removing should work in "guix.el". If you (or someone else) wish to try it, you may use: (setq guix-dry-run t) (It has the same meaning as “--dry-run” option). Also I would like to add support for deleting generations (to "guix.el"), so I think it would be good to export ‘delete-generation’ from "scripts/package.scm". WDYT? -- Alex ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-08-20 10:54 ` Alex Kost @ 2014-08-22 8:56 ` Ludovic Courtès 2014-08-22 12:44 ` Alex Kost 0 siblings, 1 reply; 29+ messages in thread From: Ludovic Courtès @ 2014-08-22 8:56 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Alex Kost <alezost@gmail.com> skribis: > Thanks, now (with the latest “guix pull”), installing/upgrading/removing > should work in "guix.el". If you (or someone else) wish to try it, you > may use: > > (setq guix-dry-run t) > > (It has the same meaning as “--dry-run” option). I gave it a try, but AFAICS, when the REPL is started as “internal”, guix-main.scm isn’t loaded, and thus “Install” fails: --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> (process-package-actions #:install '((58935712 "out")) #:upgrade '() #:remove '() #:use-substitutes? #t #:dry-run? #f) ;;; <stdin>:11:0: warning: possibly unbound variable `process-package-actions' <unnamed port>:11:0: In procedure #<procedure 42ba0c0 at <current input>:11:0 ()>: <unnamed port>:11:0: In procedure module-lookup: Unbound variable: process-package-actions --8<---------------cut here---------------end--------------->8--- Did I miss something? Besides, I like M-x guix-generations, pretty cool. :-) > Also I would like to add support for deleting generations (to > "guix.el"), so I think it would be good to export ‘delete-generation’ > from "scripts/package.scm". WDYT? Yes, that makes sense, one could use it from the *Guix Generation List* buffer. Regarding package installation/removal/upgrade, I think it would be great UI-wise to support transactions that perform multiple operations. I was initially thinking of something similar to what package.el does: marks packages from installation/removal, and then hit ‘x’ to execute the transaction. So the current “Install” and “Delete” buttons could be changed to just mark things for installation/removal. WDYT? Thanks, Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-08-22 8:56 ` Ludovic Courtès @ 2014-08-22 12:44 ` Alex Kost 2014-08-27 8:34 ` Ludovic Courtès 0 siblings, 1 reply; 29+ messages in thread From: Alex Kost @ 2014-08-22 12:44 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guix-devel [-- Attachment #1: Type: text/plain, Size: 1204 bytes --] Ludovic Courtès (2014-08-22 12:56 +0400) wrote: > Alex Kost <alezost@gmail.com> skribis: > >> Thanks, now (with the latest “guix pull”), installing/upgrading/removing >> should work in "guix.el". If you (or someone else) wish to try it, you >> may use: >> >> (setq guix-dry-run t) >> >> (It has the same meaning as “--dry-run” option). > > I gave it a try, but AFAICS, when the REPL is started as “internal”, > guix-main.scm isn’t loaded, and thus “Install” fails: > > scheme@(guile-user)> (process-package-actions #:install '((58935712 "out")) #:upgrade '() #:remove '() #:use-substitutes? #t #:dry-run? #f) > ;;; <stdin>:11:0: warning: possibly unbound variable `process-package-actions' > <unnamed port>:11:0: In procedure #<procedure 42ba0c0 at <current input>:11:0 ()>: > <unnamed port>:11:0: In procedure module-lookup: Unbound variable: process-package-actions > > Did I miss something? I don't understand why you get this, it works for me and I can't reproduce it with "emacs -Q". Does the following recipe works for you?: 1. emacs -Q 2. Evaluate the following code (for example, paste it into *scratch* buffer and "M-x eval-buffer"): [-- Attachment #2: test.el --] [-- Type: application/emacs-lisp, Size: 467 bytes --] [-- Attachment #3: Type: text/plain, Size: 231 bytes --] 3. M-x guix-all-available-packages 4. RET on any package that is not installed and press "Install" button in “*Guix Package Info*” buffer. For me “*Guix REPL*” is shown and the following output is printed: [-- Attachment #4: Type: text/plain, Size: 792 bytes --] scheme@(guile-user)> (process-package-actions #:install '((151687520 "out")) #:upgrade '() #:remove '() #:use-substitutes? #t #:dry-run? #t) The process begins ... The following package would be installed: a2ps-4.14 out /gnu/store/1akh02xh4z7i2idfnxbd28zzm87ghav1-a2ps-4.14 substitute-binary: ;;; note: source file /usr/share/guile/site/2.0/guix/config.scm substitute-binary: ;;; newer than compiled /usr/share/guile/site/2.0/guix/config.go The following derivation would be built: /gnu/store/868vmg9s02jf4pxm3nvfmk168qbx44ld-profile.drv The following files would be downloaded: /gnu/store/1akh02xh4z7i2idfnxbd28zzm87ghav1-a2ps-4.14 /gnu/store/43bg01fshdm6hnacb9b8mha681cll0nw-coreutils-8.22 /gnu/store/sv8ijfgc0d4ll8wzlxa6s2rkcvcjgrwx-perl-5.16.1 scheme@(guile-user)> [-- Attachment #5: Type: text/plain, Size: 1487 bytes --] I tried with emacs 24.3.1 and the latest Geiser (from <https://github.com/jaor/geiser>). > Besides, I like M-x guix-generations, pretty cool. :-) > >> Also I would like to add support for deleting generations (to >> "guix.el"), so I think it would be good to export ‘delete-generation’ >> from "scripts/package.scm". WDYT? > > Yes, that makes sense, one could use it from the *Guix Generation List* > buffer. Yes, that's what I had in mind: mark generations with "d" and execute a deletion operation with "x". > Regarding package installation/removal/upgrade, I think it would be > great UI-wise to support transactions that perform multiple operations. > > I was initially thinking of something similar to what package.el does: > marks packages from installation/removal, and then hit ‘x’ to execute > the transaction. So the current “Install” and “Delete” buttons could be > changed to just mark things for installation/removal. It is already available in a “*Guix Package List*” buffer: you can mark packages with "d"/"i"/"^" ("u" is for unmarking) and execute an operation with "x". As for me, I prefer to keep buttons in a “*Guix Package Info*” buffer as they are now. It's just an alternative way to install/delete a package: if you want to make a transaction of several actions – use a "list" buffer, if you just want to install some package, you can do it by pressing a button in "info" buffer. -- Alex Kost ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-08-22 12:44 ` Alex Kost @ 2014-08-27 8:34 ` Ludovic Courtès 0 siblings, 0 replies; 29+ messages in thread From: Ludovic Courtès @ 2014-08-27 8:34 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Alex Kost <alezost@gmail.com> skribis: > Ludovic Courtès (2014-08-22 12:56 +0400) wrote: > >> Alex Kost <alezost@gmail.com> skribis: >> >>> Thanks, now (with the latest “guix pull”), installing/upgrading/removing >>> should work in "guix.el". If you (or someone else) wish to try it, you >>> may use: >>> >>> (setq guix-dry-run t) >>> >>> (It has the same meaning as “--dry-run” option). >> >> I gave it a try, but AFAICS, when the REPL is started as “internal”, >> guix-main.scm isn’t loaded, and thus “Install” fails: >> >> scheme@(guile-user)> (process-package-actions #:install '((58935712 "out")) #:upgrade '() #:remove '() #:use-substitutes? #t #:dry-run? #f) >> ;;; <stdin>:11:0: warning: possibly unbound variable `process-package-actions' >> <unnamed port>:11:0: In procedure #<procedure 42ba0c0 at <current input>:11:0 ()>: >> <unnamed port>:11:0: In procedure module-lookup: Unbound variable: process-package-actions >> >> Did I miss something? > > I don't understand why you get this, it works for me and I can't > reproduce it with "emacs -Q". Does the following recipe works for you?: I can no longer reproduce the issue, but my ~/.config/guix/latest was pointing to an older version, so I think this may have led to a silent failure about unbound variables, which then prevented guix-helper.scm to be successfully loaded. Thanks, Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Emacs interface for Guix 2014-07-25 17:58 Alex Kost 2014-07-25 20:36 ` Ludovic Courtès @ 2014-07-26 20:58 ` Ludovic Courtès 1 sibling, 0 replies; 29+ messages in thread From: Ludovic Courtès @ 2014-07-26 20:58 UTC (permalink / raw) To: Alex Kost; +Cc: guix-devel Alex Kost <alezost@gmail.com> skribis: > (“package->manifest-entry” from “options->installable” would be very > useful for example) Commit 462f5cc makes it public. Ludo’. ^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2014-08-27 8:35 UTC | newest] Thread overview: 29+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-07-16 5:59 Emacs interface for Guix Alex Kost 2014-07-16 14:18 ` Ludovic Courtès 2014-07-16 19:05 ` Alex Kost 2014-07-18 9:16 ` Ludovic Courtès 2014-07-19 7:51 ` Alex Kost 2014-07-19 16:28 ` Ludovic Courtès 2014-07-20 7:10 ` Alex Kost 2014-07-20 14:08 ` Ludovic Courtès 2014-07-20 16:52 ` Alex Kost 2014-07-20 19:42 ` Alex Kost 2014-07-20 19:47 ` Ludovic Courtès 2014-07-21 6:46 ` Alex Kost 2014-07-21 16:04 ` Ludovic Courtès 2014-07-21 18:46 ` Alex Kost 2014-07-21 21:26 ` Ludovic Courtès 2014-07-22 6:20 ` Alex Kost 2014-07-22 6:53 ` Taylan Ulrich Bayirli/Kammer 2014-07-22 8:41 ` Ludovic Courtès 2014-07-22 9:34 ` Alex Kost -- strict thread matches above, loose matches on Subject: below -- 2014-07-25 17:58 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-16 12:24 ` 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-07-26 20:58 ` Ludovic Courtès
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.