From 33af9948e51d769f95298aa3f7a64598b6d9ffd5 Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 4 Jan 2018 11:59:58 +0100 Subject: [PATCH 01/12] home-environment: describe session variable trickyness --- modules/home-environment.nix | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/modules/home-environment.nix b/modules/home-environment.nix index f29364159..61ca0649e 100644 --- a/modules/home-environment.nix +++ b/modules/home-environment.nix @@ -127,6 +127,25 @@ in example = { EDITOR = "emacs"; GS_OPTIONS = "-sPAPERSIZE=a4"; }; description = '' Environment variables to always set at login. + + Note, these variables may be set in any order so no session + variable may have a runtime dependency on another session + variable. In particular code like + + home.sessionVariables = { + FOO = "Hello"; + BAR = "$FOO World!"; + }; + + may not work as expected. If you need to reference another + session variable, then do so inside Nix instead. The above + example then becomes + + home.sessionVariables = { + FOO = "Hello"; + BAR = "''${config.home.sessionVariables.FOO} World!"; + }; + ''; }; From df6590abfc650d23532ef097892f61ba6d203c5f Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 4 Jan 2018 12:19:34 +0100 Subject: [PATCH 02/12] home-environment: describe session variable values a bit --- modules/home-environment.nix | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/home-environment.nix b/modules/home-environment.nix index 61ca0649e..77850a8e3 100644 --- a/modules/home-environment.nix +++ b/modules/home-environment.nix @@ -128,6 +128,15 @@ in description = '' Environment variables to always set at login. + The values may refer to other environment variables using + POSIX.2 style variable references. For example, a variable + parameter may be referenced as + $parameter or ''${parameter}. A + default value foo may be given as per + ''${parameter:-foo} and, similarly, an alternate + value bar can be given as per + ''${parameter:+bar}. + Note, these variables may be set in any order so no session variable may have a runtime dependency on another session variable. In particular code like From 58a629b02e46b76ef55c0fd7e4fa998cb87cad91 Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 4 Jan 2018 12:21:06 +0100 Subject: [PATCH 03/12] lib/shell: add library of convenience functions This library holds a few convenience functions for generating shell code. --- modules/lib/default.nix | 2 ++ modules/lib/shell.nix | 11 +++++++++++ 2 files changed, 13 insertions(+) create mode 100644 modules/lib/shell.nix diff --git a/modules/lib/default.nix b/modules/lib/default.nix index 5c273f15d..8291be0b2 100644 --- a/modules/lib/default.nix +++ b/modules/lib/default.nix @@ -15,4 +15,6 @@ entryAfter = d.dagEntryAfter; entryBefore = d.dagEntryBefore; }; + + shell = import ./shell.nix { inherit lib; }; } diff --git a/modules/lib/shell.nix b/modules/lib/shell.nix new file mode 100644 index 000000000..f1443c546 --- /dev/null +++ b/modules/lib/shell.nix @@ -0,0 +1,11 @@ +{ lib }: + +rec { + # Produces a Bourne shell like variable export statement. + export = n: v: "export ${n}=\"${toString v}\""; + + # Given an attribute set containing shell variable names and their + # assignment, this function produces a string containing an export + # statement for each set entry. + exportAll = vars: lib.concatStringsSep "\n" (lib.mapAttrsToList export vars); +} From 026375da49002d4439554d04ac7f74a375e70ef5 Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 4 Jan 2018 12:22:17 +0100 Subject: [PATCH 04/12] bash: use shell library --- modules/programs/bash.nix | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/modules/programs/bash.nix b/modules/programs/bash.nix index 90ab5dd75..fa32a4be7 100644 --- a/modules/programs/bash.nix +++ b/modules/programs/bash.nix @@ -131,12 +131,6 @@ in map (v: "shopt -s ${v}") cfg.shellOptions ); - export = n: v: "export ${n}=\"${toString v}\""; - setIfNonEmpty = n: v: optionalString (v != "") "${n}=${toString v}"; - - histControlStr = concatStringsSep ":" cfg.historyControl; - histIgnoreStr = concatStringsSep ":" cfg.historyIgnore; - # If Bash is the session variable setter then this is the # attribute set of global session variables, otherwise it is an # empty set. @@ -145,17 +139,27 @@ in (config.home.sessionVariableSetter == "bash") config.home.sessionVariables; - envVarsStr = concatStringsSep "\n" ( - mapAttrsToList export (cfg.sessionVariables // globalEnvVars) - ); + envVarsStr = + config.lib.shell.exportAll (cfg.sessionVariables // globalEnvVars); + + historyControlStr = + concatStringsSep "\n" (mapAttrsToList (n: v: "${n}=${v}") ( + { + HISTSIZE = toString cfg.historySize; + HISTFILESIZE = toString cfg.historyFileSize; + } + // optionalAttrs (cfg.historyControl != []) { + HISTCONTROL = concatStringsSep ":" cfg.historyControl; + } + // optionalAttrs (cfg.historyIgnore != []) { + HISTIGNORE = concatStringsSep ":" cfg.historyIgnore; + } + )); in mkIf cfg.enable { programs.bash.bashrcExtra = '' # Commands that should be applied only for interactive shells. if [[ -n $PS1 ]]; then - HISTSIZE=${toString cfg.historySize} - HISTFILESIZE=${toString cfg.historyFileSize} - ${setIfNonEmpty "HISTCONTROL" histControlStr} - ${setIfNonEmpty "HISTIGNORE" histIgnoreStr} + ${historyControlStr} ${shoptsStr} From 2fc1b9b5e00e31e23b015b2204840109f4e7fe55 Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 4 Jan 2018 12:22:35 +0100 Subject: [PATCH 05/12] zsh: use shell library --- modules/programs/zsh.nix | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/modules/programs/zsh.nix b/modules/programs/zsh.nix index a088b332a..39203612b 100644 --- a/modules/programs/zsh.nix +++ b/modules/programs/zsh.nix @@ -11,17 +11,11 @@ let pluginsDir = if cfg.dotDir != null then relToDotDir "plugins" else ".zsh/plugins"; - export = n: v: "export ${n}=\"${toString v}\""; - - toEnvVarsStr = vars: concatStringsSep "\n" ( - mapAttrsToList export vars - ); - envVars = cfg.sessionVariables // ( if config.home.sessionVariableSetter == "zsh" then config.home.sessionVariables else {} ); - envVarsStr = toEnvVarsStr envVars; + envVarsStr = config.lib.shell.exportAll envVars; aliasesStr = concatStringsSep "\n" ( mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases From e624b9aa6a7caf99eaacfd4ffd9c3ef839c68a66 Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 4 Jan 2018 13:15:22 +0100 Subject: [PATCH 06/12] home-environment: install `hm-session-vars.sh` file This is a file containing all session variables exported using a Bourne-compatible syntax. --- modules/home-environment.nix | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/modules/home-environment.nix b/modules/home-environment.nix index 77850a8e3..66fe430bc 100644 --- a/modules/home-environment.nix +++ b/modules/home-environment.nix @@ -267,6 +267,23 @@ in // (maybeSet "LC_TIME" cfg.language.time); + home.packages = [ + # Provide a file holding all session variables. + ( + pkgs.writeTextFile { + name = "hm-session-vars.sh"; + destination = "/etc/profile.d/hm-session-vars.sh"; + text = '' + # Only source this once. + if [ -n "$__HM_SESS_VARS_SOURCED" ]; then return; fi + export __HM_SESS_VARS_SOURCED=1 + + ${config.lib.shell.exportAll cfg.sessionVariables} + ''; + } + ) + ]; + # A dummy entry acting as a boundary between the activation # script's "check" and the "write" phases. home.activation.writeBoundary = dag.entryAnywhere ""; From 4f9158e533ddd4e84f36e9846dd29afa5677b138 Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 4 Jan 2018 13:27:29 +0100 Subject: [PATCH 07/12] readme: add note about session variables file If a user does not want to manage their shell configuration through Home Manager then they have to manually make sure that the session variables are set. --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index f83af3366..7c7d4b123 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,24 @@ Currently the easiest way to install Home Manager is as follows: Home Manager should now be active and available in your user environment. +5. If you do not plan on having Home Manager manage your shell + configuration then you must source the + + ``` + "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" + ``` + + file in your shell configuration. Unfortunately, we currently only + support POSIX.2-like shells such as [Bash][] or [Z shell][]. + + For example, if you use Bash then add + + ```bash + . "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" + ``` + + to your `~/.profile` file. + Note, because the `HM_PATH` variable above points to the live Home Manager repository you will automatically get updates whenever you build a new generation. If you dislike automatic updates then perform @@ -240,8 +258,10 @@ in your system configuration and in your Home Manager configuration. +[Bash]: https://www.gnu.org/software/bash/ [Nix]: https://nixos.org/nix/ [NixOS]: https://nixos.org/ [Nixpkgs]: https://nixos.org/nixpkgs/ [nixAllowedUsers]: https://nixos.org/nix/manual/#conf-allowed-users [nixosAllowedUsers]: https://nixos.org/nixos/manual/options.html#opt-nix.allowedUsers +[Z shell]: http://zsh.sourceforge.net/ From a3250dfac70af2784d5cb2a70f76a5d81a4244ab Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 4 Jan 2018 13:28:55 +0100 Subject: [PATCH 08/12] xsession: source session variables script --- modules/xsession.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/xsession.nix b/modules/xsession.nix index 9f06e76be..40e522029 100644 --- a/modules/xsession.nix +++ b/modules/xsession.nix @@ -82,6 +82,9 @@ in }; home.file.".xprofile".text = '' + ${optionalString (config.home.sessionVariableSetter != "pam") + ''. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"''} + if [[ -e "$HOME/.profile" ]]; then . "$HOME/.profile" fi From 803abb58f9fbebf05a8cf62f960a32fb1b101011 Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 4 Jan 2018 13:29:45 +0100 Subject: [PATCH 09/12] bash: source session variables script This replaces the explicit set within the Bash profile file. --- modules/programs/bash.nix | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/modules/programs/bash.nix b/modules/programs/bash.nix index fa32a4be7..b5ac9417b 100644 --- a/modules/programs/bash.nix +++ b/modules/programs/bash.nix @@ -131,16 +131,7 @@ in map (v: "shopt -s ${v}") cfg.shellOptions ); - # If Bash is the session variable setter then this is the - # attribute set of global session variables, otherwise it is an - # empty set. - globalEnvVars = - optionalAttrs - (config.home.sessionVariableSetter == "bash") - config.home.sessionVariables; - - envVarsStr = - config.lib.shell.exportAll (cfg.sessionVariables // globalEnvVars); + sessionVarsStr = config.lib.shell.exportAll cfg.sessionVariables; historyControlStr = concatStringsSep "\n" (mapAttrsToList (n: v: "${n}=${v}") ( @@ -185,7 +176,11 @@ in home.file.".profile".text = '' # -*- mode: sh -*- - ${envVarsStr} + ${optionalString (config.home.sessionVariableSetter != "pam") '' + . "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" + ''} + + ${sessionVarsStr} ${cfg.profileExtra} ''; From 7631921366c8be1f6d87b57d03279f0bfae30b6d Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 4 Jan 2018 13:32:49 +0100 Subject: [PATCH 10/12] zsh: source session variables script This replaces the explicit set within the Z shell `zshenv` file. --- modules/programs/zsh.nix | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/programs/zsh.nix b/modules/programs/zsh.nix index 39203612b..4c97a921d 100644 --- a/modules/programs/zsh.nix +++ b/modules/programs/zsh.nix @@ -11,11 +11,7 @@ let pluginsDir = if cfg.dotDir != null then relToDotDir "plugins" else ".zsh/plugins"; - envVars = cfg.sessionVariables // ( - if config.home.sessionVariableSetter == "zsh" then config.home.sessionVariables else {} - ); - - envVarsStr = config.lib.shell.exportAll envVars; + envVarsStr = config.lib.shell.exportAll cfg.sessionVariables; aliasesStr = concatStringsSep "\n" ( mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases @@ -249,6 +245,9 @@ in home.file."${relToDotDir ".zshenv"}".text = '' typeset -U fpath + ${optionalString (config.home.sessionVariableSetter != "pam") '' + . "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" + ''} ${envVarsStr} ''; From d7755de116850c4864613029abd15931471b66ea Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 4 Jan 2018 16:11:23 +0100 Subject: [PATCH 11/12] pam: add option `pam.sessionVariables` --- modules/misc/pam.nix | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/modules/misc/pam.nix b/modules/misc/pam.nix index 3bd0f2925..dfeaf2f33 100644 --- a/modules/misc/pam.nix +++ b/modules/misc/pam.nix @@ -6,17 +6,35 @@ let homeCfg = config.home; + vars = + optionalAttrs (homeCfg.sessionVariableSetter == "pam") homeCfg.sessionVariables + // config.pam.sessionVariables; + in { meta.maintainers = [ maintainers.rycee ]; - options = {}; + options = { + pam.sessionVariables = mkOption { + default = {}; + type = types.attrs; + example = { EDITOR = "vim"; }; + description = '' + Environment variables that will be set for the PAM session. + The variable values must be as described in + + pam_env.conf + 5 + . + ''; + }; + }; - config = mkIf (homeCfg.sessionVariableSetter == "pam") { + config = mkIf (vars != {}) { home.file.".pam_environment".text = concatStringsSep "\n" ( - mapAttrsToList (n: v: "${n} OVERRIDE=${v}") homeCfg.sessionVariables + mapAttrsToList (n: v: "${n} OVERRIDE=${toString v}") vars ) + "\n"; }; } From 18159c85b9733161ead2b8fcbfbc9fefbef9f3c7 Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 4 Jan 2018 16:12:06 +0100 Subject: [PATCH 12/12] home-environment: deprecate option `home.sessionVariableSetter` --- modules/home-environment.nix | 7 +++-- modules/misc/news.nix | 54 ++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/modules/home-environment.nix b/modules/home-environment.nix index 66fe430bc..197e9dc57 100644 --- a/modules/home-environment.nix +++ b/modules/home-environment.nix @@ -159,8 +159,8 @@ in }; home.sessionVariableSetter = mkOption { - default = "bash"; - type = types.enum [ "pam" "bash" "zsh" ]; + default = null; + type = types.nullOr (types.enum [ "pam" "bash" "zsh" ]); example = "pam"; description = '' Identifies the module that should set the session variables. @@ -171,6 +171,9 @@ in If "pam" is set then PAM must be used to set the system environment. Also mind that typical environment variables might not be set by the time PAM starts up. + + This option is DEPRECATED, the shell modules are now + automatically setting the session variables when enabled. ''; }; diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 8ca9b7aae..5c11803ed 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -478,6 +478,60 @@ in necessary. ''; } + + { + time = "2018-01-08T20:39:56+00:00"; + condition = config.home.sessionVariableSetter != null; + message = + let + opts = { + bash = '' + Instead the 'programs.bash' module will, when enabled, + automatically set session variables. You can safely + remove the 'home.sessionVariableSetter' option from your + configuration. + ''; + + zsh = '' + Instead the 'programs.zsh' module will, when enabled, + automatically set session variables. You can safely + remove the 'home.sessionVariableSetter' option from your + configuration. + ''; + + pam = '' + Unfortunately setting general session variables using + PAM will not be directly supported after this date. The + primary reason for this change is its limited support + for variable expansion. + + To continue setting session variables from the Home + Manager configuration you must either use the + 'programs.bash' or 'programs.zsh' modules or manually + source the session variable file + + $HOME/.nix-profile/etc/profile.d/hm-session-vars.sh + + within your shell configuration, see the README file for + more information. This file requires a Bourne-like shell + such as Bash or Z shell but hopefully other shells + will be supported in the future. + + If you specifically need to set a session variable using + PAM then the new option 'pam.sessionVariables' can be + used. It works much the same as 'home.sessionVariables' + but its attribute values must be valid within the PAM + environment file. + ''; + }; + in + '' + The 'home.sessionVariableSetter' option is now deprecated + and will be removed on February 8, 2018. + + ${opts.${config.home.sessionVariableSetter}} + ''; + } ]; }; }