Switch xdg.userDirs.setSessionVariables to the shared state-version default helper so older configurations get an explicit warning before the legacy default is removed. Add focused tests for the legacy and current branches to verify that the session variable exports remain enabled before 26.05 and are disabled by default starting at 26.05. Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
210 lines
6.3 KiB
Nix
210 lines
6.3 KiB
Nix
{
|
||
config,
|
||
lib,
|
||
pkgs,
|
||
...
|
||
}:
|
||
|
||
let
|
||
inherit (lib) literalExpression mkOption types;
|
||
|
||
cfg = config.xdg.userDirs;
|
||
|
||
in
|
||
{
|
||
meta.maintainers = with lib.maintainers; [ euxane ];
|
||
|
||
imports = [
|
||
(lib.mkRenamedOptionModule
|
||
[ "xdg" "userDirs" "publishShare" ]
|
||
[
|
||
"xdg"
|
||
"userDirs"
|
||
"publicShare"
|
||
]
|
||
)
|
||
];
|
||
|
||
options.xdg.userDirs = {
|
||
enable = mkOption {
|
||
type = types.bool;
|
||
default = false;
|
||
description = ''
|
||
Whether to manage {file}`$XDG_CONFIG_HOME/user-dirs.dirs`.
|
||
|
||
The generated file is read-only.
|
||
'';
|
||
};
|
||
|
||
package = lib.mkPackageOption pkgs "xdg-user-dirs" { nullable = true; };
|
||
|
||
# Well-known directory list from
|
||
# https://gitlab.freedesktop.org/xdg/xdg-user-dirs/blob/master/man/user-dirs.dirs.xml
|
||
|
||
desktop = mkOption {
|
||
type = with types; nullOr (coercedTo path toString str);
|
||
default = "${config.home.homeDirectory}/Desktop";
|
||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Desktop"'';
|
||
description = "The Desktop directory.";
|
||
};
|
||
|
||
documents = mkOption {
|
||
type = with types; nullOr (coercedTo path toString str);
|
||
default = "${config.home.homeDirectory}/Documents";
|
||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Documents"'';
|
||
description = "The Documents directory.";
|
||
};
|
||
|
||
download = mkOption {
|
||
type = with types; nullOr (coercedTo path toString str);
|
||
default = "${config.home.homeDirectory}/Downloads";
|
||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Downloads"'';
|
||
description = "The Downloads directory.";
|
||
};
|
||
|
||
music = mkOption {
|
||
type = with types; nullOr (coercedTo path toString str);
|
||
default = "${config.home.homeDirectory}/Music";
|
||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Music"'';
|
||
description = "The Music directory.";
|
||
};
|
||
|
||
pictures = mkOption {
|
||
type = with types; nullOr (coercedTo path toString str);
|
||
default = "${config.home.homeDirectory}/Pictures";
|
||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Pictures"'';
|
||
description = "The Pictures directory.";
|
||
};
|
||
|
||
publicShare = mkOption {
|
||
type = with types; nullOr (coercedTo path toString str);
|
||
default = "${config.home.homeDirectory}/Public";
|
||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Public"'';
|
||
description = "The Public share directory.";
|
||
};
|
||
|
||
templates = mkOption {
|
||
type = with types; nullOr (coercedTo path toString str);
|
||
default = "${config.home.homeDirectory}/Templates";
|
||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Templates"'';
|
||
description = "The Templates directory.";
|
||
};
|
||
|
||
videos = mkOption {
|
||
type = with types; nullOr (coercedTo path toString str);
|
||
default = "${config.home.homeDirectory}/Videos";
|
||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Videos"'';
|
||
description = "The Videos directory.";
|
||
};
|
||
|
||
extraConfig = mkOption {
|
||
type = with types; attrsOf (coercedTo path toString str);
|
||
default = { };
|
||
defaultText = literalExpression "{ }";
|
||
example = literalExpression ''
|
||
{
|
||
MISC = "''${config.home.homeDirectory}/Misc";
|
||
}
|
||
'';
|
||
apply =
|
||
if lib.versionOlder config.home.stateVersion "26.05" then
|
||
lib.mapAttrs' (
|
||
k:
|
||
let
|
||
matches = lib.match "XDG_(.*)_DIR" k;
|
||
in
|
||
lib.nameValuePair (
|
||
if matches == null then
|
||
k
|
||
else
|
||
let
|
||
name = lib.elemAt matches 0;
|
||
in
|
||
lib.warn "using keys like ‘${k}’ for xdg.userDirs.extraConfig is deprecated in favor of keys like ‘${name}’" name
|
||
)
|
||
)
|
||
else
|
||
lib.id;
|
||
description = ''
|
||
Other user directories.
|
||
|
||
The key ‘MISC’ corresponds to the user-dirs entry ‘XDG_MISC_DIR’.
|
||
'';
|
||
};
|
||
|
||
createDirectories = lib.mkEnableOption "automatic creation of the XDG user directories";
|
||
|
||
setSessionVariables = mkOption {
|
||
type = with types; bool;
|
||
inherit
|
||
(lib.hm.deprecations.mkStateVersionOptionDefault {
|
||
inherit (config.home) stateVersion;
|
||
since = "26.05";
|
||
optionPath = [
|
||
"xdg"
|
||
"userDirs"
|
||
"setSessionVariables"
|
||
];
|
||
legacy.value = true;
|
||
current.value = false;
|
||
})
|
||
default
|
||
defaultText
|
||
;
|
||
description = ''
|
||
Whether to set the XDG user dir environment variables, like
|
||
`XDG_DESKTOP_DIR`.
|
||
|
||
::: {.note}
|
||
The recommended way to get these values is via the `xdg-user-dir`
|
||
command or by processing `$XDG_CONFIG_HOME/user-dirs.dirs` directly in
|
||
your application.
|
||
:::
|
||
|
||
This defaults to `true` for state version < 26.05 and `false` otherwise.
|
||
'';
|
||
};
|
||
};
|
||
|
||
config =
|
||
let
|
||
directories =
|
||
(lib.filterAttrs (n: v: !isNull v) {
|
||
DESKTOP = cfg.desktop;
|
||
DOCUMENTS = cfg.documents;
|
||
DOWNLOAD = cfg.download;
|
||
MUSIC = cfg.music;
|
||
PICTURES = cfg.pictures;
|
||
PUBLICSHARE = cfg.publicShare;
|
||
TEMPLATES = cfg.templates;
|
||
VIDEOS = cfg.videos;
|
||
})
|
||
// cfg.extraConfig;
|
||
|
||
bindings = lib.mapAttrs' (k: lib.nameValuePair "XDG_${k}_DIR") directories;
|
||
in
|
||
lib.mkIf cfg.enable {
|
||
xdg.configFile."user-dirs.dirs".text =
|
||
let
|
||
# For some reason, these need to be wrapped with quotes to be valid.
|
||
wrapped = lib.mapAttrs (_: value: ''"${value}"'') bindings;
|
||
in
|
||
lib.generators.toKeyValue { } wrapped;
|
||
|
||
xdg.configFile."user-dirs.conf".text = "enabled=False";
|
||
|
||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||
|
||
home.sessionVariables = lib.mkIf cfg.setSessionVariables bindings;
|
||
|
||
home.activation.createXdgUserDirectories = lib.mkIf cfg.createDirectories (
|
||
let
|
||
directoriesList = lib.attrValues directories;
|
||
mkdir = (dir: ''[[ -L "${dir}" ]] || run mkdir -p $VERBOSE_ARG "${dir}"'');
|
||
in
|
||
lib.hm.dag.entryAfter [ "linkGeneration" ] (
|
||
lib.strings.concatMapStringsSep "\n" mkdir directoriesList
|
||
)
|
||
);
|
||
};
|
||
}
|