mirror of
https://github.com/nix-community/home-manager
synced 2024-11-26 21:19:45 +01:00
Switch to extended Nixpkg's lib
This change makes use of the `extend` function inside `lib` to inject a new `hm` field containing the Home Manager library functions. This simplifies use of the Home Manager library in the modules and reduces the risk of accidental infinite recursion. PR #994
This commit is contained in:
parent
c8323a0bf1
commit
6e4b9af080
19 changed files with 136 additions and 75 deletions
|
@ -1,18 +1,20 @@
|
|||
{ pkgs }:
|
||||
{
|
||||
# Note, this should be "the standard library" + HM extensions.
|
||||
lib
|
||||
, pkgs
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
lib = pkgs.lib;
|
||||
|
||||
nmdSrc = pkgs.fetchFromGitLab {
|
||||
name = "nmd";
|
||||
owner = "rycee";
|
||||
repo = "nmd";
|
||||
rev = "9751ca5ef6eb2ef27470010208d4c0a20e89443d";
|
||||
sha256 = "0rbx10n8kk0bvp1nl5c8q79lz1w0p1b8103asbvwps3gmqd070hi";
|
||||
rev = "b437898c2b137c39d9c5f9a1cf62ec630f14d9fc";
|
||||
sha256 = "18j1nh53cfpjpdiwn99x9kqpvr0s7hwngyc0a93xf4sg88ww93lq";
|
||||
};
|
||||
|
||||
nmd = import nmdSrc { inherit pkgs; };
|
||||
nmd = import nmdSrc { inherit lib pkgs; };
|
||||
|
||||
# Make sure the used package is scrubbed to avoid actually
|
||||
# instantiating derivations.
|
||||
|
@ -29,7 +31,10 @@ let
|
|||
|
||||
hmModulesDocs = nmd.buildModulesDocs {
|
||||
modules =
|
||||
import ../modules/modules.nix { inherit lib pkgs; }
|
||||
import ../modules/modules.nix {
|
||||
inherit lib pkgs;
|
||||
check = false;
|
||||
}
|
||||
++ [ scrubbedPkgsModule ];
|
||||
moduleRootPaths = [ ./.. ];
|
||||
mkModuleUrl = path:
|
||||
|
|
|
@ -36,6 +36,39 @@ home.file = {
|
|||
Support for the list form will be removed in Home Manager version
|
||||
20.09.
|
||||
|
||||
* The `lib` function attribute given to modules is now enriched with
|
||||
an attribute `hm` containing extra library functions specific for Home
|
||||
Manager. More specifically, `lib.hm` is now the same as `config.lib`
|
||||
and should be the preferred choice since it is more robust.
|
||||
+
|
||||
Therefore, if your configuration makes use of, for example,
|
||||
`config.lib.dag` to create activation script blocks, it is recommended
|
||||
to change to `lib.hm.dag`.
|
||||
+
|
||||
Note, in the unlikely case that you are
|
||||
+
|
||||
** using Home Manager's NixOS or nix-darwin module,
|
||||
** have made your own Home Manager module containing an top-level
|
||||
option named `config` or `options`, and
|
||||
** assign to this option in your system configuration inside a plain
|
||||
attribute set, i.e., without a function argument,
|
||||
|
||||
+
|
||||
then you must update your configuration to perform the option
|
||||
assignment inside a `config` attribute. For example, instead of
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
home-manager.users.jane = { config = "foo"; };
|
||||
----
|
||||
+
|
||||
use
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
home-manager.users.jane = { config.config = "foo"; };
|
||||
----
|
||||
|
||||
[[sec-release-20.03-state-version-changes]]
|
||||
=== State Version Changes
|
||||
|
||||
|
|
|
@ -19,10 +19,16 @@ let
|
|||
in
|
||||
fold f res res.config.warnings;
|
||||
|
||||
rawModule = lib.evalModules {
|
||||
modules =
|
||||
[ configuration ]
|
||||
++ (import ./modules.nix { inherit check lib pkgs; });
|
||||
extendedLib = import ./lib/stdlib-extended.nix pkgs.lib;
|
||||
|
||||
hmModules =
|
||||
import ./modules.nix {
|
||||
inherit check pkgs;
|
||||
lib = extendedLib;
|
||||
};
|
||||
|
||||
rawModule = extendedLib.evalModules {
|
||||
modules = [ configuration ] ++ hmModules;
|
||||
specialArgs = {
|
||||
modulesPath = builtins.toString ./.;
|
||||
};
|
||||
|
|
|
@ -6,8 +6,6 @@ let
|
|||
|
||||
cfg = config.home.file;
|
||||
|
||||
dag = config.lib.dag;
|
||||
|
||||
homeDirectory = config.home.homeDirectory;
|
||||
|
||||
fileType = (import lib/file-type.nix {
|
||||
|
@ -43,7 +41,7 @@ in
|
|||
config = {
|
||||
# This verifies that the links we are about to create will not
|
||||
# overwrite an existing file.
|
||||
home.activation.checkLinkTargets = dag.entryBefore ["writeBoundary"] (
|
||||
home.activation.checkLinkTargets = hm.dag.entryBefore ["writeBoundary"] (
|
||||
let
|
||||
check = pkgs.writeText "check" ''
|
||||
. ${./lib-bash/color-echo.sh}
|
||||
|
@ -113,7 +111,7 @@ in
|
|||
# and a failure during the intermediate state FA ∩ FB will not
|
||||
# result in lost links because this set of links are in both the
|
||||
# source and target generation.
|
||||
home.activation.linkGeneration = dag.entryAfter ["writeBoundary"] (
|
||||
home.activation.linkGeneration = hm.dag.entryAfter ["writeBoundary"] (
|
||||
let
|
||||
link = pkgs.writeText "link" ''
|
||||
newGenFiles="$1"
|
||||
|
@ -210,7 +208,7 @@ in
|
|||
''
|
||||
);
|
||||
|
||||
home.activation.checkFilesChanged = dag.entryBefore ["linkGeneration"] (
|
||||
home.activation.checkFilesChanged = hm.dag.entryBefore ["linkGeneration"] (
|
||||
''
|
||||
declare -A changedFiles
|
||||
'' + concatMapStrings (v: ''
|
||||
|
@ -220,7 +218,7 @@ in
|
|||
'') (filter (v: v.onChange != "") (attrValues cfg))
|
||||
);
|
||||
|
||||
home.activation.onFilesChange = dag.entryAfter ["linkGeneration"] (
|
||||
home.activation.onFilesChange = hm.dag.entryAfter ["linkGeneration"] (
|
||||
concatMapStrings (v: ''
|
||||
if [[ ${"$\{changedFiles"}["${v.target}"]} -eq 1 ]]; then
|
||||
${v.onChange}
|
||||
|
|
|
@ -6,9 +6,6 @@ let
|
|||
|
||||
cfg = config.home;
|
||||
|
||||
dag = config.lib.dag;
|
||||
dagOf = (import ./lib/types.nix { inherit dag lib; }).dagOf;
|
||||
|
||||
languageSubModule = types.submodule {
|
||||
options = {
|
||||
base = mkOption {
|
||||
|
@ -235,11 +232,11 @@ in
|
|||
};
|
||||
|
||||
home.activation = mkOption {
|
||||
type = dagOf types.str;
|
||||
type = hm.types.dagOf types.str;
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{
|
||||
myActivationAction = config.lib.dag.entryAfter ["writeBoundary"] '''
|
||||
myActivationAction = lib.hm.dag.entryAfter ["writeBoundary"] '''
|
||||
$DRY_RUN_CMD ln -s $VERBOSE_ARG \
|
||||
''${builtins.toPath ./link-me-directly} $HOME
|
||||
''';
|
||||
|
@ -362,7 +359,7 @@ in
|
|||
|
||||
# A dummy entry acting as a boundary between the activation
|
||||
# script's "check" and the "write" phases.
|
||||
home.activation.writeBoundary = dag.entryAnywhere "";
|
||||
home.activation.writeBoundary = hm.dag.entryAnywhere "";
|
||||
|
||||
# Install packages to the user environment.
|
||||
#
|
||||
|
@ -379,7 +376,7 @@ in
|
|||
# In case the user has moved from a user-install of Home Manager
|
||||
# to a submodule managed one we attempt to uninstall the
|
||||
# `home-manager-path` package if it is installed.
|
||||
home.activation.installPackages = dag.entryAfter ["writeBoundary"] (
|
||||
home.activation.installPackages = hm.dag.entryAfter ["writeBoundary"] (
|
||||
if config.submoduleSupport.externalPackageInstall
|
||||
then
|
||||
''
|
||||
|
@ -399,7 +396,7 @@ in
|
|||
noteEcho Activating ${res.name}
|
||||
${res.data}
|
||||
'';
|
||||
sortedCommands = dag.topoSort cfg.activation;
|
||||
sortedCommands = hm.dag.topoSort cfg.activation;
|
||||
activationCmds =
|
||||
if sortedCommands ? result then
|
||||
concatStringsSep "\n" (map mkCmd sortedCommands.result)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{ lib }:
|
||||
|
||||
{
|
||||
rec {
|
||||
dag =
|
||||
let
|
||||
d = import ./dag.nix { inherit lib; };
|
||||
|
@ -17,6 +17,7 @@
|
|||
};
|
||||
|
||||
strings = import ./strings.nix { inherit lib; };
|
||||
types = import ./types.nix { inherit dag lib; };
|
||||
|
||||
shell = import ./shell.nix { inherit lib; };
|
||||
zsh = import ./zsh.nix { inherit lib; };
|
||||
|
|
|
@ -2,12 +2,6 @@
|
|||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
stringsExtra = import ./strings.nix { inherit lib; };
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
# Constructs a type suitable for a `home.file` like option. The
|
||||
# target path may be either absolute or relative, in which case it
|
||||
|
@ -93,7 +87,7 @@ in
|
|||
source = mkIf (config.text != null) (
|
||||
mkDefault (pkgs.writeTextFile {
|
||||
inherit (config) executable text;
|
||||
name = stringsExtra.storeFileName name;
|
||||
name = hm.strings.storeFileName name;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
11
modules/lib/stdlib-extended.nix
Normal file
11
modules/lib/stdlib-extended.nix
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Just a convenience function that returns the given Nixpkgs standard
|
||||
# library extended with the HM library.
|
||||
|
||||
nixpkgsLib:
|
||||
|
||||
let
|
||||
mkHmLib = import ./.;
|
||||
in
|
||||
nixpkgsLib.extend (self: super: {
|
||||
hm = mkHmLib { lib = super; };
|
||||
})
|
|
@ -4,7 +4,6 @@ with lib;
|
|||
|
||||
let
|
||||
|
||||
hmLib = import ./default.nix { inherit lib; };
|
||||
typesDag = import ./types-dag.nix { inherit dag lib; };
|
||||
|
||||
in
|
||||
|
|
|
@ -6,7 +6,7 @@ let
|
|||
|
||||
cfg = config.manual;
|
||||
|
||||
docs = import ../doc { inherit pkgs; };
|
||||
docs = import ../doc { inherit lib pkgs; };
|
||||
|
||||
in
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ with lib;
|
|||
let
|
||||
|
||||
cfg = config.dconf;
|
||||
dag = config.lib.dag;
|
||||
|
||||
toDconfIni = generators.toINI { mkKeyValue = mkIniKeyValue; };
|
||||
|
||||
|
@ -65,7 +64,7 @@ in
|
|||
};
|
||||
|
||||
config = mkIf (cfg.enable && cfg.settings != {}) {
|
||||
home.activation.dconfSettings = dag.entryAfter ["installPackages"] (
|
||||
home.activation.dconfSettings = hm.dag.entryAfter ["installPackages"] (
|
||||
let
|
||||
iniFile = pkgs.writeText "hm-dconf.ini" (toDconfIni cfg.settings);
|
||||
in
|
||||
|
|
|
@ -5,7 +5,6 @@ with lib;
|
|||
let
|
||||
|
||||
cfg = config.qt;
|
||||
dag = config.lib.dag;
|
||||
|
||||
in
|
||||
|
||||
|
@ -69,7 +68,7 @@ in
|
|||
|
||||
# Enable GTK+ style for Qt4 in either case.
|
||||
# It doesn’t support the platform theme packages.
|
||||
home.activation.useGtkThemeInQt4 = dag.entryAfter ["writeBoundary"] ''
|
||||
home.activation.useGtkThemeInQt4 = hm.dag.entryAfter ["writeBoundary"] ''
|
||||
$DRY_RUN_CMD ${pkgs.crudini}/bin/crudini $VERBOSE_ARG \
|
||||
--set "${config.xdg.configHome}/Trolltech.conf" Qt style GTK+
|
||||
'';
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
{ pkgs
|
||||
|
||||
# Note, this should be "the standard library" + HM extensions.
|
||||
, lib
|
||||
|
||||
# Whether to enable module type checking.
|
||||
|
@ -167,7 +169,7 @@ let
|
|||
config._module.args.baseModules = modules;
|
||||
config._module.args.pkgs = lib.mkDefault pkgs;
|
||||
config._module.check = check;
|
||||
config.lib = import ./lib { inherit lib; };
|
||||
config.lib = lib.hm;
|
||||
config.nixpkgs.system = mkDefault pkgs.system;
|
||||
};
|
||||
|
||||
|
|
|
@ -26,8 +26,6 @@ let
|
|||
|
||||
cfg = config.programs.info;
|
||||
|
||||
dag = config.lib.dag;
|
||||
|
||||
# Indexes info files found in this location
|
||||
homeInfoPath = "${config.home.profileDirectory}/share/info";
|
||||
|
||||
|
@ -57,7 +55,7 @@ in
|
|||
home.sessionVariables.INFOPATH =
|
||||
"${cfg.homeInfoDirLocation}\${INFOPATH:+:}\${INFOPATH}";
|
||||
|
||||
home.activation.createHomeInfoDir = dag.entryAfter ["installPackages"] ''
|
||||
home.activation.createHomeInfoDir = hm.dag.entryAfter ["installPackages"] ''
|
||||
oPATH=$PATH
|
||||
export PATH="${lib.makeBinPath [ pkgs.gzip ]}''${PATH:+:}$PATH"
|
||||
$DRY_RUN_CMD mkdir -p "${cfg.homeInfoDirLocation}"
|
||||
|
|
|
@ -4,8 +4,6 @@ with lib;
|
|||
|
||||
let
|
||||
|
||||
dag = config.lib.dag;
|
||||
|
||||
cfg = config.programs.mbsync;
|
||||
|
||||
# Accounts for which mbsync is enabled.
|
||||
|
@ -180,7 +178,7 @@ in
|
|||
|
||||
home.activation = mkIf (mbsyncAccounts != []) {
|
||||
createMaildir =
|
||||
dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
|
||||
hm.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
|
||||
$DRY_RUN_CMD mkdir -m700 -p $VERBOSE_ARG ${
|
||||
concatMapStringsSep " " (a: a.maildir.absPath) mbsyncAccounts
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@ let
|
|||
|
||||
cfg = config.systemd.user;
|
||||
|
||||
dag = config.lib.dag;
|
||||
|
||||
enabled = cfg.services != {}
|
||||
|| cfg.sockets != {}
|
||||
|| cfg.targets != {}
|
||||
|
@ -230,7 +228,7 @@ in
|
|||
# running this from the NixOS module then XDG_RUNTIME_DIR is not
|
||||
# set and systemd commands will fail. We'll therefore have to
|
||||
# set it ourselves in that case.
|
||||
home.activation.reloadSystemD = dag.entryAfter ["linkGeneration"] (
|
||||
home.activation.reloadSystemD = hm.dag.entryAfter ["linkGeneration"] (
|
||||
let
|
||||
autoReloadCmd = ''
|
||||
${pkgs.ruby}/bin/ruby ${./systemd-activate.rb} \
|
||||
|
|
|
@ -6,17 +6,27 @@ let
|
|||
|
||||
cfg = config.home-manager;
|
||||
|
||||
hmModule = types.submodule ({name, ...}: {
|
||||
imports = import ../modules/modules.nix { inherit lib pkgs; };
|
||||
extendedLib = import ../modules/lib/stdlib-extended.nix pkgs.lib;
|
||||
|
||||
config = {
|
||||
submoduleSupport.enable = true;
|
||||
submoduleSupport.externalPackageInstall = cfg.useUserPackages;
|
||||
hmModule = types.submoduleWith {
|
||||
specialArgs = { lib = extendedLib; };
|
||||
modules = [(
|
||||
{name, ...}: {
|
||||
imports = import ../modules/modules.nix {
|
||||
inherit pkgs;
|
||||
lib = extendedLib;
|
||||
};
|
||||
|
||||
home.username = config.users.users.${name}.name;
|
||||
home.homeDirectory = config.users.users.${name}.home;
|
||||
};
|
||||
});
|
||||
config = {
|
||||
submoduleSupport.enable = true;
|
||||
submoduleSupport.externalPackageInstall = cfg.useUserPackages;
|
||||
|
||||
home.username = config.users.users.${name}.name;
|
||||
home.homeDirectory = config.users.users.${name}.home;
|
||||
};
|
||||
}
|
||||
)];
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
|
|
|
@ -6,22 +6,32 @@ let
|
|||
|
||||
cfg = config.home-manager;
|
||||
|
||||
hmModule = types.submodule ({name, ...}: {
|
||||
imports = import ../modules/modules.nix { inherit lib pkgs; };
|
||||
extendedLib = import ../modules/lib/stdlib-extended.nix pkgs.lib;
|
||||
|
||||
config = {
|
||||
submoduleSupport.enable = true;
|
||||
submoduleSupport.externalPackageInstall = cfg.useUserPackages;
|
||||
hmModule = types.submoduleWith {
|
||||
specialArgs = { lib = extendedLib; };
|
||||
modules = [(
|
||||
{name, ...}: {
|
||||
imports = import ../modules/modules.nix {
|
||||
inherit pkgs;
|
||||
lib = extendedLib;
|
||||
};
|
||||
|
||||
# The per-user directory inside /etc/profiles is not known by
|
||||
# fontconfig by default.
|
||||
fonts.fontconfig.enable =
|
||||
cfg.useUserPackages && config.fonts.fontconfig.enable;
|
||||
config = {
|
||||
submoduleSupport.enable = true;
|
||||
submoduleSupport.externalPackageInstall = cfg.useUserPackages;
|
||||
|
||||
home.username = config.users.users.${name}.name;
|
||||
home.homeDirectory = config.users.users.${name}.home;
|
||||
};
|
||||
});
|
||||
# The per-user directory inside /etc/profiles is not known by
|
||||
# fontconfig by default.
|
||||
fonts.fontconfig.enable =
|
||||
cfg.useUserPackages && config.fonts.fontconfig.enable;
|
||||
|
||||
home.username = config.users.users.${name}.name;
|
||||
home.homeDirectory = config.users.users.${name}.home;
|
||||
};
|
||||
}
|
||||
)];
|
||||
};
|
||||
|
||||
serviceEnvironment =
|
||||
optionalAttrs (cfg.backupFileExtension != null) {
|
||||
|
|
|
@ -2,18 +2,21 @@
|
|||
|
||||
let
|
||||
|
||||
lib = import ../modules/lib/stdlib-extended.nix pkgs.lib;
|
||||
|
||||
nmt = pkgs.fetchFromGitLab {
|
||||
owner = "rycee";
|
||||
repo = "nmt";
|
||||
rev = "89fb12a2aaa8ec671e22a033162c7738be714305";
|
||||
sha256 = "07yc1jkgw8vhskzk937k9hfba401q8rn4sgj9baw3fkjl9zrbcyf";
|
||||
rev = "6f866d1acb89fa15cd3b62baa052deae1f685c0c";
|
||||
sha256 = "1qr1shhapjn4nnd4k6hml69ri8vgz4l8lakjll5hc516shs9a9nn";
|
||||
};
|
||||
|
||||
modules = import ../modules/modules.nix { inherit lib pkgs; check = false; };
|
||||
|
||||
in
|
||||
|
||||
import nmt {
|
||||
inherit pkgs;
|
||||
modules = import ../modules/modules.nix { inherit pkgs; lib = pkgs.lib; };
|
||||
inherit lib pkgs modules;
|
||||
testedAttrPath = [ "home" "activationPackage" ];
|
||||
tests = {
|
||||
browserpass = ./modules/programs/browserpass.nix;
|
||||
|
|
Loading…
Reference in a new issue