From f7f6a559c21dfe5e63108ded0d036ae15e6e9d57 Mon Sep 17 00:00:00 2001 From: William Phetsinorath Date: Thu, 9 Apr 2026 18:23:25 +0200 Subject: [PATCH] xdg: add support for local bin path Signed-off-by: William Phetsinorath Signed-off-by: William Phetsinorath Change-Id: I045f07415467ca6d409a6f4d52e753866a6a6964 --- modules/misc/xdg.nix | 28 +++++++++++++++++++ .../home-environment/session-variables.nix | 2 ++ tests/modules/misc/xdg/default.nix | 2 ++ tests/modules/misc/xdg/local-bin-in-path.nix | 10 +++++++ .../misc/xdg/local-bin-not-in-path.nix | 10 +++++++ tests/modules/misc/xdg/system-dirs.nix | 1 + tests/modules/systemd/session-variables.nix | 1 + 7 files changed, 54 insertions(+) create mode 100644 tests/modules/misc/xdg/local-bin-in-path.nix create mode 100644 tests/modules/misc/xdg/local-bin-not-in-path.nix diff --git a/modules/misc/xdg.nix b/modules/misc/xdg.nix index 218abc9ab..a8b49dd3b 100644 --- a/modules/misc/xdg.nix +++ b/modules/misc/xdg.nix @@ -7,6 +7,7 @@ let inherit (lib) + mkAfter mkOptionDefault mkIf mkOption @@ -29,6 +30,7 @@ let defaultConfigHome = "${config.home.homeDirectory}/.config"; defaultDataHome = "${config.home.homeDirectory}/.local/share"; defaultStateHome = "${config.home.homeDirectory}/.local/state"; + defaultBinHome = "${config.home.homeDirectory}/.local/bin"; getEnvFallback = name: fallback: @@ -102,6 +104,17 @@ in ''; }; + binHome = mkOption { + type = types.path; + defaultText = "~/.local/bin"; + apply = toString; + description = '' + Absolute path to directory holding user-specific executables. + + Sets `XDG_BIN_HOME` for the user if `xdg.enable` is set `true`. + ''; + }; + stateFile = mkOption { type = fileType "xdg.stateFile" "xdg.stateHome" cfg.stateHome; default = { }; @@ -121,12 +134,22 @@ in Sets `XDG_STATE_HOME` for the user if `xdg.enable` is set `true`. ''; }; + + localBinInPath = mkOption { + type = types.bool; + default = false; + description = '' + Whether to add {option}`xdg.binHome` to {env}`PATH` when + {option}`xdg.enable` is enabled. + ''; + }; }; config = lib.mkMerge [ ( let variables = { + XDG_BIN_HOME = cfg.binHome; XDG_CACHE_HOME = cfg.cacheHome; XDG_CONFIG_HOME = cfg.configHome; XDG_DATA_HOME = cfg.dataHome; @@ -137,10 +160,13 @@ in xdg.cacheHome = mkOptionDefault defaultCacheHome; xdg.configHome = mkOptionDefault defaultConfigHome; xdg.dataHome = mkOptionDefault defaultDataHome; + xdg.binHome = mkOptionDefault defaultBinHome; xdg.stateHome = mkOptionDefault defaultStateHome; home.sessionVariables = variables; systemd.user.sessionVariables = variables; + + home.sessionPath = mkIf cfg.localBinInPath (mkAfter [ cfg.binHome ]); } ) @@ -149,6 +175,7 @@ in xdg.cacheHome = mkOptionDefault (getEnvFallback "XDG_CACHE_HOME" defaultCacheHome); xdg.configHome = mkOptionDefault (getEnvFallback "XDG_CONFIG_HOME" defaultConfigHome); xdg.dataHome = mkOptionDefault (getEnvFallback "XDG_DATA_HOME" defaultDataHome); + xdg.binHome = mkOptionDefault (getEnvFallback "XDG_BIN_HOME" defaultBinHome); xdg.stateHome = mkOptionDefault (getEnvFallback "XDG_STATE_HOME" defaultStateHome); }) @@ -157,6 +184,7 @@ in xdg.cacheHome = mkOptionDefault defaultCacheHome; xdg.configHome = mkOptionDefault defaultConfigHome; xdg.dataHome = mkOptionDefault defaultDataHome; + xdg.binHome = mkOptionDefault defaultBinHome; xdg.stateHome = mkOptionDefault defaultStateHome; }) diff --git a/tests/modules/home-environment/session-variables.nix b/tests/modules/home-environment/session-variables.nix index 2cd4d2301..4c0d2f4be 100644 --- a/tests/modules/home-environment/session-variables.nix +++ b/tests/modules/home-environment/session-variables.nix @@ -12,6 +12,7 @@ let export LOCALE_ARCHIVE_2_27="${config.i18n.glibcLocales}/lib/locale/locale-archive" export V1="v1" export V2="v2-v1" + export XDG_BIN_HOME="/home/hm-user/.local/bin" 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" @@ -26,6 +27,7 @@ let export V1="v1" export V2="v2-v1" + export XDG_BIN_HOME="/home/hm-user/.local/bin" 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" diff --git a/tests/modules/misc/xdg/default.nix b/tests/modules/misc/xdg/default.nix index 59606edc3..c73c2e9ab 100644 --- a/tests/modules/misc/xdg/default.nix +++ b/tests/modules/misc/xdg/default.nix @@ -4,6 +4,8 @@ xdg-mime-disabled = ./mime-disabled.nix; xdg-autostart = ./autostart.nix; xdg-autostart-readonly = ./autostart-readonly.nix; + xdg-local-bin-in-path = ./local-bin-in-path.nix; + xdg-local-bin-not-in-path = ./local-bin-not-in-path.nix; xdg-user-dirs-mixed = ./user-dirs-mixed.nix; xdg-user-dirs-null = ./user-dirs-null.nix; xdg-user-dirs-short = ./user-dirs-short.nix; diff --git a/tests/modules/misc/xdg/local-bin-in-path.nix b/tests/modules/misc/xdg/local-bin-in-path.nix new file mode 100644 index 000000000..0b5ed0e20 --- /dev/null +++ b/tests/modules/misc/xdg/local-bin-in-path.nix @@ -0,0 +1,10 @@ +{ + xdg.enable = true; + xdg.localBinInPath = true; + + nmt.script = '' + assertFileExists home-path/etc/profile.d/hm-session-vars.sh + assertFileContains home-path/etc/profile.d/hm-session-vars.sh \ + 'export PATH="/home/hm-user/.local/bin''${PATH:+:}$PATH"' + ''; +} diff --git a/tests/modules/misc/xdg/local-bin-not-in-path.nix b/tests/modules/misc/xdg/local-bin-not-in-path.nix new file mode 100644 index 000000000..55071fdc4 --- /dev/null +++ b/tests/modules/misc/xdg/local-bin-not-in-path.nix @@ -0,0 +1,10 @@ +{ + xdg.localBinInPath = false; + xdg.enable = true; + + nmt.script = '' + assertFileExists home-path/etc/profile.d/hm-session-vars.sh + assertFileNotRegex home-path/etc/profile.d/hm-session-vars.sh \ + '^export PATH="/home/hm-user/\.local/bin' + ''; +} diff --git a/tests/modules/misc/xdg/system-dirs.nix b/tests/modules/misc/xdg/system-dirs.nix index 240e5ef9a..15049e6bd 100644 --- a/tests/modules/misc/xdg/system-dirs.nix +++ b/tests/modules/misc/xdg/system-dirs.nix @@ -21,6 +21,7 @@ assertFileExists $envFile assertFileContent $envFile ${pkgs.writeText "expected" '' LOCALE_ARCHIVE_2_27=${config.i18n.glibcLocales}/lib/locale/locale-archive + XDG_BIN_HOME=/home/hm-user/.local/bin XDG_CACHE_HOME=/home/hm-user/.cache XDG_CONFIG_DIRS=/etc/xdg:/foo/bar''${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS} XDG_CONFIG_HOME=/home/hm-user/.config diff --git a/tests/modules/systemd/session-variables.nix b/tests/modules/systemd/session-variables.nix index 583d01695..1a172b0ae 100644 --- a/tests/modules/systemd/session-variables.nix +++ b/tests/modules/systemd/session-variables.nix @@ -13,6 +13,7 @@ LOCALE_ARCHIVE_2_27=${config.i18n.glibcLocales}/lib/locale/locale-archive V_int=1 V_str=2 + XDG_BIN_HOME=/home/hm-user/.local/bin XDG_CACHE_HOME=/home/hm-user/.cache XDG_CONFIG_HOME=/home/hm-user/.config XDG_DATA_HOME=/home/hm-user/.local/share