1
0
Fork 0
mirror of https://github.com/nix-community/home-manager synced 2024-12-24 18:59:47 +01:00

home-manager: support username with special chars (#5609)

The home manager script fails when $USER contains special characters.

For example, my work PC is managed by company's LDAP and username is <COMPANY>\<user>). When running home-manager switch I get the following error:
```
error: flake 'path:/home/<COMPANY>/<user>/.config/home-manager' does not provide attribute 'packages.x86_64-linux.homeConfigurations."<COMPANY>\<user>".activationPackage', 'legacyPackages.x86_64-linux.homeConfigurations."<COMPANY>\<user>".activationPackage' or 'homeConfigurations."<COMPANY>\<user>".activationPackage'
       Did you mean <COMPANY><user>?
```
There are two types of strings that need escaping:

    strings in Nix expressions (e.g. home.nix generated by home-manager init)
    they need backslashes before special chars
    flake URI (passed to nix build)
    they need URI's percent encoding, luckily jq supports that
This commit is contained in:
DDoSolitary 2024-12-12 05:13:27 +08:00 committed by GitHub
parent f26aa4b76f
commit 6e5b2d9e80
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -52,6 +52,11 @@ function hasFlakeSupport() {
| grep -q nix-command | grep -q nix-command
} }
# Escape string for use in Nix files.
function escapeForNix() {
printf %s "$1" | sed 's/["$\\]/\\\0/g'
}
# Attempts to set the HOME_MANAGER_CONFIG global variable. # Attempts to set the HOME_MANAGER_CONFIG global variable.
# #
# If no configuration file can be found then this function will print # If no configuration file can be found then this function will print
@ -201,7 +206,7 @@ function setFlakeAttribute() {
# Check FQDN, long, and short hostnames; long first to preserve # Check FQDN, long, and short hostnames; long first to preserve
# pre-existing behaviour in case both happen to be defined. # pre-existing behaviour in case both happen to be defined.
for n in "$USER@$(hostname -f)" "$USER@$(hostname)" "$USER@$(hostname -s)"; do for n in "$USER@$(hostname -f)" "$USER@$(hostname)" "$USER@$(hostname -s)"; do
if [[ "$(nix eval "$flake#homeConfigurations" --apply "x: x ? \"$n\"")" == "true" ]]; then if [[ "$(nix eval "$flake#homeConfigurations" --apply "x: x ? \"$(escapeForNix "$n")\"")" == "true" ]]; then
name="$n" name="$n"
if [[ -v VERBOSE ]]; then if [[ -v VERBOSE ]]; then
echo "Using flake homeConfiguration for $name" echo "Using flake homeConfiguration for $name"
@ -210,7 +215,7 @@ function setFlakeAttribute() {
done done
;; ;;
esac esac
export FLAKE_CONFIG_URI="$flake#homeConfigurations.\"$name\"" export FLAKE_CONFIG_URI="$flake#homeConfigurations.\"$(printf %s "$name" | jq -sRr @uri)\""
fi fi
} }
@ -349,8 +354,8 @@ function doInit() {
{ {
# Home Manager needs a bit of information about you and the paths it should # Home Manager needs a bit of information about you and the paths it should
# manage. # manage.
home.username = "$USER"; home.username = "$(escapeForNix "$USER")";
home.homeDirectory = "$HOME"; home.homeDirectory = "$(escapeForNix "$HOME")";
$xdgVars $xdgVars
# This value determines the Home Manager release that your configuration is # This value determines the Home Manager release that your configuration is
# compatible with. This helps avoid breakage when a new Home Manager release # compatible with. This helps avoid breakage when a new Home Manager release
@ -439,7 +444,7 @@ EOF
mkdir -p "$confDir" mkdir -p "$confDir"
cat > "$flakeFile" <<EOF cat > "$flakeFile" <<EOF
{ {
description = "Home Manager configuration of $USER"; description = "Home Manager configuration of $(escapeForNix "$USER")";
inputs = { inputs = {
# Specify the source of Home Manager and Nixpkgs. # Specify the source of Home Manager and Nixpkgs.
@ -455,7 +460,7 @@ EOF
system = "$nixSystem"; system = "$nixSystem";
pkgs = nixpkgs.legacyPackages.\${system}; pkgs = nixpkgs.legacyPackages.\${system};
in { in {
homeConfigurations."$USER" = home-manager.lib.homeManagerConfiguration { homeConfigurations."$(escapeForNix "$USER")" = home-manager.lib.homeManagerConfiguration {
inherit pkgs; inherit pkgs;
# Specify your home configuration modules here, for example, # Specify your home configuration modules here, for example,
@ -855,8 +860,8 @@ function doUninstall() {
cat > "$HOME_MANAGER_CONFIG" <<EOF cat > "$HOME_MANAGER_CONFIG" <<EOF
{ {
uninstall = true; uninstall = true;
home.username = "$USER"; home.username = "$(escapeForNix "$USER")";
home.homeDirectory = "$HOME"; home.homeDirectory = "$(escapeForNix "$HOME")";
home.stateVersion = "24.11"; home.stateVersion = "24.11";
} }
EOF EOF