~ruther/guix-local

c743d646ee9104aa14d066cdf6657a0fac82ebea — Maxim Cournoyer 1 year, 2 months ago 45b883a
system: Factorize bashrc default configuration.

This factorizes out the remaining bashrc bits from /etc/skel/.bashrc to a the
template used for both /etc/bashrc on Guix System and ~/.bashrc for
home-bash-service-type.

Rationale: The use of /etc/skel introduce state: the file is only copied
originally when the user account is created, and never (automatically)
refreshed again.

* gnu/system.scm (operating-system-etc-service):
<profile>: Guard against souring /etc/bashrc in non-interactive, SSH case.
<bashrc>: Use %default-bashrc, having migrated the remaining definitions to...
* gnu/system/shadow.scm (%default-bashrc): ... here.  Factorize aliases to...
* gnu/services.scm (%default-bash-aliases): ... here.
(%default-bashrc-d-aliases): New variable.
(%default-etc-bashrc-d-files): Include it in the default configuration.
* gnu/services/base.scm (%base-services): Register etc-bashrc-d-service-type.
* gnu/home/services/shells.scm (add-bash-configuration): Do not set PS1, now
part of %default-bashrc.
(home-bash-configuration) [guix-defaults?]: Update doc.
[aliases]: Set %default-bash-aliases as the default value.  Update doc.
* doc/guix.texi (Shells Home Services): Update documentation.
(Service Reference): Update example.

Change-Id: I340c614983a78fd20a9c4a9705e7fc542ae9b513
M doc/guix.texi => doc/guix.texi +9 -5
@@ 47688,8 47688,9 @@ not end with @file{.sh} are @emph{not} added to @file{/etc/profile.d/}
and are silently dropped.  The default value is made available via the
@var{%default-etc-bashrc-d-files} variable for users to extended.
Package objects can also be provided directly to have their
@file{etc/bashrc.d/*.sh} prefixed files added.  An example usage may
look like:
@file{etc/bashrc.d/*.sh} prefixed files added.  Since the service is
part @code{%base-services}, it can be extended via @code{simple-service}
like so:

@example
(use-package-modules gnome)     ;for the `vte' package


@@ 49322,8 49323,11 @@ Available @code{home-bash-configuration} fields are:
The Bash package to use.

@item @code{guix-defaults?} (default: @code{#t}) (type: boolean)
Add sane defaults like reading @file{/etc/bashrc} and coloring the output of
@command{ls} to the top of the @file{.bashrc} file.
Add sane defaults like setting @env{PS1}, @env{SHELL}, and ensuring
@file{/etc/profile} is sourced for non-interactive SSH shells.  If you
use Guix System, is it safe to set this to @code{#f}, as in this case
this is already taken care of by the globally installed
@file{/etc/bashrc}.

@item @code{environment-variables} (default: @code{'()}) (type: alist)
Association list of environment variables to set for the Bash session.  The


@@ 49331,7 49335,7 @@ rules for the @code{home-environment-variables-service-type} apply
here (@pxref{Essential Home Services}).  The contents of this field will be
added after the contents of the @code{bash-profile} field.

@item @code{aliases} (default: @code{'()}) (type: alist)
@item @code{aliases} (default: @code{%default-bash-aliases}) (type: alist)
Association list of aliases to set for the Bash session.  The aliases
will be defined after the contents of the @code{bashrc} field has been
put in the @file{.bashrc} file.  The alias will automatically be quoted,

M gnu/home/services/shells.scm => gnu/home/services/shells.scm +7 -7
@@ 20,6 20,7 @@

(define-module (gnu home services shells)
  #:use-module (gnu services configuration)
  #:use-module ((gnu services) #:select (%default-bash-aliases))
  #:autoload   (gnu system shadow) (%default-bashrc %default-zprofile)
  #:use-module (gnu home services utils)
  #:use-module (gnu home services)


@@ 333,9 334,12 @@ another process for example)."))
   (package bash)
   "The Bash package to use.")
  (guix-defaults?
   ;; TODO: Set to #f when the target system is determined to be Guix System.
   (boolean #t)
   "Add sane defaults like reading @file{/etc/bashrc} and coloring the output of
@command{ls} to the top of the @file{.bashrc} file.")
   "Add sane defaults like setting @env{PS1}, @env{SHELL}, and ensuring
@file{/etc/profile} is sourced for non-interactive SSH shells.  If you use
Guix System, is it safe to set this to @code{#f}, as in this case this is
already taken care of by the globally installed @file{/etc/bashrc}.")
  (environment-variables
   (alist '())
   "Association list of environment variables to set for the Bash session.  The


@@ 344,7 348,7 @@ here (@pxref{Essential Home Services}).  The contents of this field will be
added after the contents of the @code{bash-profile} field."
   (serializer serialize-posix-env-vars))
  (aliases
   (alist '())
   (alist %default-bash-aliases)
   "Association list of aliases to set for the Bash session.  The aliases will be
defined after the contents of the @code{bashrc} field has been put in the
@file{.bashrc} file.  The alias will automatically be quoted, so something line


@@ 423,10 427,6 @@ if [ -f ~/.bashrc ]; then source ~/.bashrc; fi
              'bashrc
              (if (home-bash-configuration-guix-defaults? config)
                  (list (plain-file-content %default-bashrc) "\n"
                        ;; The host distro might provide a bad 'PS1'
                        ;; default--e.g., not taking $GUIX_ENVIRONMENT into
                        ;; account.  Provide a good default here when asked.
                        "PS1='\\u@\\h \\w${GUIX_ENVIRONMENT:+ [env]}\\$ '\n"
                        (serialize-field 'aliases))
                  (list (serialize-field 'aliases))))
             (file-if-not-empty 'bash-logout)))))

M gnu/services.scm => gnu/services.scm +21 -2
@@ 125,6 125,7 @@
            etc-profile-d-service-type
            etc-bashrc-d-service-type
            %default-etc-bashrc-d-files
            %default-bash-aliases
            etc-directory
            privileged-program-service-type
            setuid-program-service-type ; deprecated


@@ 993,9 994,27 @@ log in.")))
(define files->bashrc-d-directory
  (make-files->etc-directory "bashrc.d"))

;;; Use an alist to be compatible with <home-bash-configuration>.
(define %default-bash-aliases
  '(("ls" . "ls -p --color=auto")
    ("ll" . "ls -l")
    ("grep" . "grep --color=auto")
    ("ip" . "ip -color=auto")))

;;; ... but avoid the full blown bash-serialize-aliases, which depends on
;;; other 'guix home' definitions such as `shell-double-quote'.
(define %default-bashrc-d-aliases
  (plain-file "aliases.sh"
              (string-join
               (map (match-lambda
                      ((alias . value)
                       (format #f "~a=~s~%" alias value)))
                    %default-bash-aliases)
               "")))

(define %default-etc-bashrc-d-files
  (list (file-append bash-completion
                     "/etc/profile.d/bash_completion.sh")))
  (list (file-append bash-completion "/etc/profile.d/bash_completion.sh")
        %default-bashrc-d-aliases))

(define etc-bashrc-d-service-type
  (service-type

M gnu/services/base.scm => gnu/services/base.scm +4 -1
@@ 4138,7 4138,10 @@ login manager daemon.")
        (service mingetty-service-type (mingetty-configuration
                                         (tty "tty5")))
        (service mingetty-service-type (mingetty-configuration
                                         (tty "tty6")))
                                        (tty "tty6")))

        ;; Extra Bash configuration including Bash completion and aliases.
        (service etc-bashrc-d-service-type)

        (service static-networking-service-type
                 (list %loopback-static-networking))

M gnu/system.scm => gnu/system.scm +7 -17
@@ 1141,23 1141,13 @@ for i in /etc/profile.d/*.sh; do
done
unset i

if [ -n \"$BASH_VERSION\" -a -f /etc/bashrc ]
then
  # Load Bash-specific initialization code.
  . /etc/bashrc
if [ -n \"$BASH_VERSION\" -a -f /etc/bashrc ]; then
  # Load Bash-specific initialization code, taking care to not source
  # /etc/bashrc when invoked from a non-interactive SSH shell,
  # to avoid recursion (/etc/bashrc also sources /etc/profile
  # in the non-login, non-interactive SSH case).
  [[ $- != *i* && -n $SSH_CLIENT ]] || source /etc/bashrc
fi
"))

        (bashrc    (plain-file "bashrc" "\
# Bash-specific initialization.

# Provide a default prompt.  The user's ~/.bashrc can override it.
PS1='\\u@\\h \\w${GUIX_ENVIRONMENT:+ [env]}\\$ '

for i in /etc/bashrc.d/*.sh; do
    [[ -r $i ]] && source \"$i\"
done
unset i
")))
    (service etc-service-type
     `(("os-release" ,os-release)


@@ 1168,7 1158,7 @@ unset i
       ("issue" ,issue)
       ,@(if nsswitch `(("nsswitch.conf" ,nsswitch)) '())
       ("profile" ,profile)
       ("bashrc" ,bashrc)
       ("bashrc" ,%default-bashrc)
       ;; Write the operating-system-host-name to /etc/hostname to prevent
       ;; NetworkManager from changing the system's hostname when connecting
       ;; to certain networks.  Some discussion at

M gnu/system/shadow.scm => gnu/system/shadow.scm +10 -8
@@ 147,8 147,11 @@

(define %default-bashrc
  (plain-file "bashrc" "\
# Bash initialization for interactive non-login shells and
# for remote shells (info \"(bash) Bash Startup Files\").
# Bash-specific initialization, including for non-login and remote
# shells (info \"(bash) Bash Startup Files\").

# Provide a default prompt.
PS1='\\u@\\h \\w${GUIX_ENVIRONMENT:+ [env]}\\$ '

# Export 'SHELL' to child processes.  Programs such as 'screen'
# honor it and otherwise use /bin/sh.


@@ 165,10 168,11 @@ then
    return
fi

alias ls='ls -p --color=auto'
alias ll='ls -l'
alias grep='grep --color=auto'
alias ip='ip -color=auto'\n"))
for i in /etc/bashrc.d/*.sh; do
    [[ -r $i ]] && source \"$i\"
done
unset i
"))

(define %default-bash-profile
  (plain-file "bash_profile" "\


@@ 289,12 293,10 @@ home-config"))
'useradd' in the home directory of newly created user accounts."

  (let ((profile   %default-bash-profile)
        (bashrc    %default-bashrc)
        (zprofile  %default-zprofile)
        (xdefaults %default-xdefaults)
        (gdbinit   %default-gdbinit))
    `((".bash_profile" ,profile)
      (".bashrc" ,bashrc)
      ;; Zsh sources ~/.zprofile before ~/.zshrc, and it sources ~/.zlogin
      ;; after ~/.zshrc.  To avoid interfering with any customizations a user
      ;; may have made in their ~/.zshrc, put this in .zprofile, not .zlogin.

M gnu/tests/base.scm => gnu/tests/base.scm +10 -7
@@ 187,6 187,8 @@ test \"$PROFILE_D_OK\" = yes")
                                            "\
. /etc/bashrc
set -e -x
test -f /etc/bashrc.d/bash_completion.sh
test -f /etc/bashrc.d/aliases.sh
test -f /etc/bashrc.d/test_bashrc_d.sh
test \"$BASHRC_D_OK\" = yes"))
                    marionette)))


@@ 606,14 608,15 @@ functionality tests, using the given KERNEL.")
                                           (plain-file
                                            "invalid-name"
                                            "not a POSIX script -- ignore me")))
                                    (service
                                    (simple-service
                                     'extra-bashrc-d-files
                                     etc-bashrc-d-service-type
                                     (list (plain-file
                                            "test_bashrc_d.sh"
                                            "export BASHRC_D_OK=yes\n")
                                           (plain-file
                                            "invalid-name"
                                            "not a Bash script -- ignore me")))
                                     (list  (plain-file
                                             "test_bashrc_d.sh"
                                             "export BASHRC_D_OK=yes\n")
                                            (plain-file
                                             "invalid-name"
                                             "not a Bash script -- ignore me")))
                                    %base-services)))
                 #:imported-modules '((gnu services herd)
                                      (guix combinators))))