diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0a8cb5e57..6b0f08dfa 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -34,6 +34,9 @@ /modules/misc/xdg-user-dirs.nix @pacien +/modules/misc/xdg-system-dirs.nix @tadfisher +/tests/modules/misc/xdg/system-dirs.nix @tadfisher + /modules/programs/aria2.nix @JustinLovinger /modules/programs/autojump.nix @evanjs diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 6234dc7bd..daa866652 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1965,7 +1965,7 @@ in The option 'services.sxhkd.extraPath' has been deprecated. ''; } - + { time = "2021-05-06T20:47:37+00:00"; condition = hostPlatform.isLinux; @@ -1980,6 +1980,26 @@ in A new module is available: 'programs.nix-index'. ''; } + + { + time = "2021-05-10T18:50:07+00:00"; + message = '' + A new module is available: 'xdg.systemDirs'. Options are: + + - xdg.systemDirs.config + + Extra directory names to add to $XDG_CONFIG_DIRS in the user + session. + + - xdg.systemDirs.data + + Extra directory names to add to $XDG_DATA_DIRS in the user + session. + + These variables are visible in both systemd user services and + login shells. + ''; + } ]; }; } diff --git a/modules/misc/xdg-system-dirs.nix b/modules/misc/xdg-system-dirs.nix new file mode 100644 index 000000000..d3fad015a --- /dev/null +++ b/modules/misc/xdg-system-dirs.nix @@ -0,0 +1,49 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.xdg.systemDirs; + + configDirs = concatStringsSep ":" cfg.config; + + dataDirs = concatStringsSep ":" cfg.data; + +in { + meta.maintainers = with maintainers; [ tadfisher ]; + + options.xdg.systemDirs = { + config = mkOption { + type = types.listOf types.str; + default = [ ]; + example = literalExample ''[ "/etc/xdg" ]''; + description = '' + Directory names to add to XDG_CONFIG_DIRS + in the user session. + ''; + }; + + data = mkOption { + type = types.listOf types.str; + default = [ ]; + example = literalExample ''[ "/usr/share" "/usr/local/share" ]''; + description = '' + Directory names to add to XDG_DATA_DIRS + in the user session. + ''; + }; + }; + + config = mkMerge [ + (mkIf (cfg.config != [ ]) { + systemd.user.sessionVariables.XDG_CONFIG_DIRS = + "${configDirs}\${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}"; + }) + + (mkIf (cfg.data != [ ]) { + systemd.user.sessionVariables.XDG_DATA_DIRS = + "${dataDirs}\${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}"; + }) + ]; +} diff --git a/modules/modules.nix b/modules/modules.nix index 6a6f4f085..573764b3f 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -40,6 +40,7 @@ let (loadModule ./misc/tmpfiles.nix { condition = hostPlatform.isLinux; }) (loadModule ./misc/version.nix { }) (loadModule ./misc/vte.nix { }) + (loadModule ./misc/xdg-system-dirs.nix { condition = hostPlatform.isLinux; }) (loadModule ./misc/xdg-mime.nix { condition = hostPlatform.isLinux; }) (loadModule ./misc/xdg-mime-apps.nix { condition = hostPlatform.isLinux; }) (loadModule ./misc/xdg-user-dirs.nix { condition = hostPlatform.isLinux; }) diff --git a/modules/systemd.nix b/modules/systemd.nix index e1261b7b4..7c03b5625 100644 --- a/modules/systemd.nix +++ b/modules/systemd.nix @@ -333,6 +333,11 @@ in unset systemdStatus '' ); + + # Export environment variables in systemd.user.sessionVariables to login shells. + home.sessionVariablesExtra = optionalString (cfg.sessionVariables != {}) '' + export $(${pkgs.systemd}/lib/systemd/user-environment-generators/30-systemd-environment-d-generator) + ''; }) ]; } diff --git a/modules/targets/generic-linux.nix b/modules/targets/generic-linux.nix index a6486d734..6e17bd282 100644 --- a/modules/targets/generic-linux.nix +++ b/modules/targets/generic-linux.nix @@ -4,9 +4,19 @@ with lib; let + cfg = config.targets.genericLinux; + profileDirectory = config.home.profileDirectory; in { + imports = [ + (mkRenamedOptionModule [ "targets" "genericLinux" "extraXdgDataDirs" ] [ + "xdg" + "systemDirs" + "data" + ]) + ]; + options.targets.genericLinux = { enable = mkEnableOption "" // { description = '' @@ -14,39 +24,20 @@ in { GNU/Linux distributions other than NixOS. ''; }; - - extraXdgDataDirs = mkOption { - type = types.listOf types.str; - default = [ ]; - example = [ "/usr/share" "/usr/local/share" ]; - description = '' - List of directory names to add to XDG_DATA_DIRS. - ''; - }; }; - config = mkIf config.targets.genericLinux.enable { - home.sessionVariables = let - profiles = - [ "\${NIX_STATE_DIR:-/nix/var/nix}/profiles/default" profileDirectory ]; - dataDirs = concatStringsSep ":" - (map (profile: "${profile}/share") profiles - ++ config.targets.genericLinux.extraXdgDataDirs); + config = mkIf cfg.enable { + xdg.systemDirs.data = [ + # Nix profiles + "\${NIX_STATE_DIR:-/nix/var/nix}/profiles/default/share" + "${profileDirectory}/share" - # https://github.com/archlinux/svntogit-packages/blob/packages/ncurses/trunk/PKGBUILD - # https://salsa.debian.org/debian/ncurses/-/blob/master/debian/rules - # https://src.fedoraproject.org/rpms/ncurses/blob/main/f/ncurses.spec - # https://gitweb.gentoo.org/repo/gentoo.git/tree/sys-libs/ncurses/ncurses-6.2-r1.ebuild - distroTerminfoDirs = concatStringsSep ":" [ - "/etc/terminfo" # debian, fedora, gentoo - "/lib/terminfo" # debian - "/usr/share/terminfo" # package default, all distros - ]; - in { - XDG_DATA_DIRS = "${dataDirs}\${XDG_DATA_DIRS:+:}$XDG_DATA_DIRS"; - TERMINFO_DIRS = - "${profileDirectory}/share/terminfo:$TERMINFO_DIRS\${TERMINFO_DIRS:+:}${distroTerminfoDirs}"; - }; + # Distribution-specific + "/usr/share/ubuntu" + "/usr/local/share" + "/usr/share" + "/var/lib/snapd/desktop" + ]; home.sessionVariablesExtra = '' . "${pkgs.nix}/etc/profile.d/nix.sh" @@ -62,8 +53,20 @@ in { . "${profileDirectory}/etc/profile.d/hm-session-vars.sh" ''; - systemd.user.sessionVariables = { + systemd.user.sessionVariables = let + # https://github.com/archlinux/svntogit-packages/blob/packages/ncurses/trunk/PKGBUILD + # https://salsa.debian.org/debian/ncurses/-/blob/master/debian/rules + # https://src.fedoraproject.org/rpms/ncurses/blob/main/f/ncurses.spec + # https://gitweb.gentoo.org/repo/gentoo.git/tree/sys-libs/ncurses/ncurses-6.2-r1.ebuild + distroTerminfoDirs = concatStringsSep ":" [ + "/etc/terminfo" # debian, fedora, gentoo + "/lib/terminfo" # debian + "/usr/share/terminfo" # package default, all distros + ]; + in { NIX_PATH = "$HOME/.nix-defexpr/channels\${NIX_PATH:+:}$NIX_PATH"; + TERMINFO_DIRS = + "${profileDirectory}/share/terminfo:$TERMINFO_DIRS\${TERMINFO_DIRS:+:}${distroTerminfoDirs}"; }; }; } diff --git a/tests/modules/home-environment/session-variables.nix b/tests/modules/home-environment/session-variables.nix index d939c05eb..5f52b620e 100644 --- a/tests/modules/home-environment/session-variables.nix +++ b/tests/modules/home-environment/session-variables.nix @@ -15,6 +15,7 @@ let export XDG_CACHE_HOME="/home/hm-user/.cache" export XDG_CONFIG_HOME="/home/hm-user/.config" export XDG_DATA_HOME="/home/hm-user/.local/share" + export $(${pkgs.systemd}/lib/systemd/user-environment-generators/30-systemd-environment-d-generator) ''; darwinExpected = '' diff --git a/tests/modules/misc/xdg/default.nix b/tests/modules/misc/xdg/default.nix index 813a25202..45610154c 100644 --- a/tests/modules/misc/xdg/default.nix +++ b/tests/modules/misc/xdg/default.nix @@ -1,4 +1,5 @@ { xdg-mime-apps-basics = ./mime-apps-basics.nix; xdg-file-attr-names = ./file-attr-names.nix; + xdg-system-dirs = ./system-dirs.nix; } diff --git a/tests/modules/misc/xdg/system-dirs.nix b/tests/modules/misc/xdg/system-dirs.nix new file mode 100644 index 000000000..d2913b239 --- /dev/null +++ b/tests/modules/misc/xdg/system-dirs.nix @@ -0,0 +1,25 @@ +{ config, lib, pkgs, ... }: + +{ + config = { + xdg.systemDirs.config = [ "/etc/xdg" "/foo/bar" ]; + xdg.systemDirs.data = [ "/usr/local/share" "/usr/share" "/baz/quux" ]; + + nmt.script = '' + envFile=home-files/.config/environment.d/10-home-manager.conf + assertFileExists $envFile + assertFileContent $envFile ${ + pkgs.writeText "expected" '' + LOCALE_ARCHIVE_2_27=${pkgs.glibcLocales}/lib/locale/locale-archive + XDG_CONFIG_DIRS=/etc/xdg:/foo/bar''${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS} + XDG_DATA_DIRS=/usr/local/share:/usr/share:/baz/quux''${XDG_DATA_DIRS:+:$XDG_DATA_DIRS} + '' + } + + sessionVarsFile=home-path/etc/profile.d/hm-session-vars.sh + assertFileExists $sessionVarsFile + assertFileContains $sessionVarsFile \ + 'export $(${pkgs.systemd}/lib/systemd/user-environment-generators/30-systemd-environment-d-generator)' + ''; + }; +} diff --git a/tests/modules/systemd/session-variables.nix b/tests/modules/systemd/session-variables.nix index 59d1a4d3a..21d96d449 100644 --- a/tests/modules/systemd/session-variables.nix +++ b/tests/modules/systemd/session-variables.nix @@ -15,6 +15,11 @@ V_int=1 V_str=2 ''} + + sessionVarsFile=home-path/etc/profile.d/hm-session-vars.sh + assertFileExists $sessionVarsFile + assertFileContains $sessionVarsFile \ + 'export $(${pkgs.systemd}/lib/systemd/user-environment-generators/30-systemd-environment-d-generator)' ''; }; } diff --git a/tests/modules/targets-linux/generic-linux.nix b/tests/modules/targets-linux/generic-linux.nix index 530137cfb..88cec8a00 100644 --- a/tests/modules/targets-linux/generic-linux.nix +++ b/tests/modules/targets-linux/generic-linux.nix @@ -2,26 +2,36 @@ with lib; -{ +let + expectedXdgDataDirs = concatStringsSep ":" [ + "\${NIX_STATE_DIR:-/nix/var/nix}/profiles/default/share" + "/home/hm-user/.nix-profile/share" + "/usr/share/ubuntu" + "/usr/local/share" + "/usr/share" + "/var/lib/snapd/desktop" + "/foo" + ]; + +in { config = { - targets.genericLinux = { - enable = true; - extraXdgDataDirs = [ "/foo" ]; - }; + targets.genericLinux.enable = true; + + xdg.systemDirs.data = [ "/foo" ]; nmt.script = '' - assertFileExists home-path/etc/profile.d/hm-session-vars.sh + envFile=home-files/.config/environment.d/10-home-manager.conf + assertFileExists $envFile + assertFileContains $envFile \ + 'XDG_DATA_DIRS=${expectedXdgDataDirs}''${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}' + assertFileContains $envFile \ + 'TERMINFO_DIRS=/home/hm-user/.nix-profile/share/terminfo:$TERMINFO_DIRS''${TERMINFO_DIRS:+:}/etc/terminfo:/lib/terminfo:/usr/share/terminfo' - assertFileContains \ - home-path/etc/profile.d/hm-session-vars.sh \ - 'export XDG_DATA_DIRS="''${NIX_STATE_DIR:-/nix/var/nix}/profiles/default/share:/home/hm-user/.nix-profile/share:/foo''${XDG_DATA_DIRS:+:}$XDG_DATA_DIRS"' - assertFileContains \ - home-path/etc/profile.d/hm-session-vars.sh \ + sessionVarsFile=home-path/etc/profile.d/hm-session-vars.sh + assertFileExists $sessionVarsFile + assertFileContains $sessionVarsFile \ '. "${pkgs.nix}/etc/profile.d/nix.sh"' - assertFileContains \ - home-path/etc/profile.d/hm-session-vars.sh \ - 'export TERMINFO_DIRS="/home/hm-user/.nix-profile/share/terminfo:$TERMINFO_DIRS''${TERMINFO_DIRS:+:}/etc/terminfo:/lib/terminfo:/usr/share/terminfo"' assertFileContains \ home-path/etc/profile.d/hm-session-vars.sh \ 'export TERM="$TERM"'