all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* 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-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

* 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

* 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

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.