~ruther/guix-local

0ec1af59e564c00fb48359fec84d049138589dee — Ludovic Courtès 13 years ago 2a5ab9d
guix-package: Create or diagnose missing profile directory.

Reported by Andreas Enge.

* guix-package.in (%profile-directory): Honor $NIX_STATE_DIR.
  (guix-package)[ensure-default-profile]: Use it.
  [process-actions]: Call it when the `profile' option is
  %CURRENT-PROFILE.
* tests/guix-package.sh: Add installation test with $HOME set, using the
  default profile.
3 files changed, 63 insertions(+), 14 deletions(-)

M doc/guix.texi
M guix-package.in
M tests/guix-package.sh
M doc/guix.texi => doc/guix.texi +13 -1
@@ 444,11 444,23 @@ previous generations of the profile remain available, should the user
want to roll back.

For each user, a symlink to the user's default profile is automatically
created in @file{$HOME/.guix-profile}.  This symlink always point to the
created in @file{$HOME/.guix-profile}.  This symlink always points to the
current generation of the user's default profile.  Thus, users can add
@file{$HOME/.guix-profile/bin} to their @code{PATH} environment
variable, and so on.

In a multi-user setup, user profiles must be stored in a place
registered as a @dfn{garbage-collector root}, which
@file{$HOME/.guix-profile} points to (@pxref{Invoking guix-gc}).  That
directory is normally
@code{@var{localstatedir}/profiles/per-user/@var{user}}, where
@var{localstatedir} is the value passed to @code{configure} as
@code{--localstatedir}, and @var{user} is the user name.  It must be
created by @code{root}, with @var{user} as the owner.  When it does not
exist, @command{guix-package} emits an error about it.

The @var{options} can be among the following:

@table @code

@item --install=@var{package}

M guix-package.in => guix-package.in +34 -10
@@ 36,6 36,7 @@ exec ${GUILE-@GUILE@} -L "@guilemoduledir@" -l "$0"    \
  #:use-module (guix packages)
  #:use-module (guix utils)
  #:use-module (guix config)
  #:use-module ((guix build utils) #:select (directory-exists? mkdir-p))
  #:use-module (ice-9 ftw)
  #:use-module (ice-9 format)
  #:use-module (ice-9 match)


@@ 63,7 64,7 @@ exec ${GUILE-@GUILE@} -L "@guilemoduledir@" -l "$0"    \
         (cut string-append <> "/.guix-profile")))

(define %profile-directory
  (string-append %state-directory "/profiles/"
  (string-append (or (getenv "NIX_STATE_DIR") %state-directory) "/profiles/"
                 (or (and=> (getenv "USER")
                            (cut string-append "per-user/" <>))
                     "default")))


@@ 330,6 331,34 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
        (()
         (leave (_ "~a: package not found~%") request)))))

  (define (ensure-default-profile)
    ;; Ensure the default profile symlink and directory exist.

    ;; Create ~/.guix-profile if it doesn't exist yet.
    (when (and %user-environment-directory
               %current-profile
               (not (false-if-exception
                     (lstat %user-environment-directory))))
      (symlink %current-profile %user-environment-directory))

    ;; Attempt to create /…/profiles/per-user/$USER if needed.
    (unless (directory-exists? %profile-directory)
      (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)
          (exit 1)))))

  (define (process-actions opts)
    ;; Process any install/remove/upgrade action from OPTS.
    (let* ((dry-run? (assoc-ref opts 'dry-run?))


@@ 355,7 384,7 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
                                                  (package-name->name+version
                                                   (store-path-package-name
                                                    path))))
                                     `(,name ,version #f ,path)))
                                      `(,name ,version #f ,path)))
                                   (_ #f))
                                  opts)
                      (map (lambda (tuple drv)


@@ 382,6 411,9 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
                                         remove)
                                   install*))))

      (when (equal? (assoc-ref opts 'profile) %current-profile)
        (ensure-default-profile))

      (show-what-to-build drv dry-run?)

      (or dry-run?


@@ 458,14 490,6 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
  (setvbuf (current-error-port) _IOLBF)

  (let ((opts (parse-options)))

    ;; Create ~/.guix-profile if it doesn't exist yet.
    (when (and %user-environment-directory
               %current-profile
               (not (false-if-exception
                     (lstat %user-environment-directory))))
      (symlink %current-profile %user-environment-directory))

    (with-error-handling
      (or (process-query opts)
          (parameterize ((%guile-for-build

M tests/guix-package.sh => tests/guix-package.sh +16 -3
@@ 25,10 25,11 @@ guix-package --version
profile="t-profile-$$"
rm -f "$profile"

trap 'rm "$profile" "$profile-"[0-9]*' EXIT
trap 'rm "$profile" "$profile-"[0-9]* ; rm -rf t-home-'"$$" EXIT

guix-package --bootstrap -p "$profile"						\
    -i `guix-build -e '(@@ (distro packages base) %bootstrap-guile)'`
boot_guile="`guix-build -e '(@ (distro packages bootstrap) %bootstrap-guile)'`"

guix-package --bootstrap -p "$profile" -i "$boot_guile"
test -L "$profile" && test -L "$profile-1-link"
test -f "$profile/bin/guile"



@@ 75,3 76,15 @@ guix-package --bootstrap -i "binutils:lib" -p "$profile" -n
# Check whether `--list-available' returns something sensible.
guix-package -A 'gui.*e' | grep guile

# Try with the default profile.

XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"
export XDG_CACHE_HOME
HOME="t-home-$$"
export HOME

mkdir -p "$HOME"

guix-package --bootstrap -i "$boot_guile"
test -L "$HOME/.guix-profile"
test -f "$HOME/.guix-profile/bin/guile"