summary refs log tree commit diff stats
path: root/bin/home-manager
diff options
context:
space:
mode:
Diffstat (limited to 'bin/home-manager')
-rwxr-xr-xbin/home-manager152
1 files changed, 152 insertions, 0 deletions
diff --git a/bin/home-manager b/bin/home-manager
new file mode 100755
index 00000000..cf434738
--- /dev/null
+++ b/bin/home-manager
@@ -0,0 +1,152 @@
+#!/usr/bin/env fish
+
+if not set --query HOME
+    echo "error: no HOME"
+    exit 1
+end
+
+set --query XDG_STATE_HOME || set --function XDG_STATE_HOME $HOME/.local/state
+set --function nix_state_home $XDG_STATE_HOME/nix
+set --function channel_root $nix_state_home/channels
+set --function user_nixpkgs $HOME/.config/nixpkgs
+set --function nixfiles (path resolve (status dirname)/..)
+
+if set --query XDG_CONFIG_HOME
+    set --function hm_config_dir $XDG_CONFIG_HOME/home-manager
+else
+    set --function hm_config_dir $HOME/.config/home-manager
+end
+
+for i in 1
+    if test ! -d $user_nixpkgs
+        if test ! -e $user_nixpkgs && test -L $user_nixpkgs
+            echo "~/.config/nixpkgs is a broken symlink, deleting it"
+            rm $channel_root
+        end
+        echo "user nixpkgs folder $user_nixpkgs does not exist, creating it"
+        mkdir -p $user_nixpkgs
+    end
+    if test -L $hm_config_dir -a (path resolve $hm_config_dir) = (path resolve (status basename))
+        if test y = (read --nchars=1 --prompt-str="$hm_config_dir already exists as a symlink to the current directory. Remove it [yN]? ")
+            unlink $hm_config_dir
+        end
+    end
+    if test ! -d $hm_config_dir
+        echo "user home-manager configuration folder $hm_config_dir does not exist, creating it"
+        mkdir -p $hm_config_dir
+    end
+    if test ! -e $channel_root
+        if test -L $channel_root
+            # broken symlink
+            rm $channel_root
+        end
+        echo "channel root $channel_root does not exist, creating it"
+        mkdir -p $channel_root
+    else
+        if test ! -d $channel_root
+            echo "error: $channel_root is not a directory"
+        else if test -L $channel_root
+            echo "error: $channel_root is a symlink, please remove it"
+        else if path is --invert --perm write $channel_root
+            echo "error: $channel_root is not writable; might be a symlink"
+        else if path is --invert --type link $channel_root/*
+            for p in (path filter --invert --type link $channel_root/*)
+                # might be a broken symlink
+                if test -L $p -a ! -e $p
+                    rm $p
+                else
+                    echo "error: channel $p is not a broken symlink, don't know what to do with it"
+                end
+            end
+            # check again and fail if there are still unknown files
+            if path is --invert --type link $channel_root/*
+                echo "error: non-link(s) in $channel_root"
+                path filter --invert --type link $channel_root/*
+            else
+                continue
+            end
+        else
+            continue # with script
+        end
+        exit 1
+    end
+end
+
+set --function current_script_name (status basename)
+switch $current_script_name
+    case darwin-rebuild
+        set --local darwin_config_source $nixfiles/system/$hostname.nix
+        set --local darwin_config_target $user_nixpkgs/darwin-configuration.nix
+        if test ! -e $darwin_config_target
+            ln -s $darwin_config_source $darwin_config_target
+        end
+        set --append argv -I darwin-config=$darwin_config_source
+    case nixos-rebuild
+        set --local nixos_config_source $nixfiles/system/$hostname.nix
+        set --local nixos_config_target $user_nixpkgs/configuration.nix
+        if test ! -e $nixos_config_target
+            ln -s $nixos_config_source $nixos_config_target
+        end
+        if ! fish_is_root_user
+            set --append argv --use-remote-sudo
+        end
+        set --append argv -I nixos-config=$nixos_config_source
+    case home-manager
+        set --local hm_config_source $nixfiles/user/$hostname.nix
+        set --local hm_config_target $hm_config_dir/home.nix
+        if test ! -e $hm_config_target
+            ln -s $hm_config_source $hm_config_target
+        end
+        set --export HOME_MANAGER_CONFIG $hm_config_source
+end
+
+set --function old_channels (path basename $channel_root/*)
+
+function update_link --argument-names new_src target
+    set --function current_src (path resolve $target)
+    if test -e $current_src
+        if test $current_src = $new_src
+            # no need to re-link it
+            return
+        else
+            unlink $target
+        end
+    end
+    ln -s $new_src $target
+end
+
+for np in $NIX_PATH
+    if string match --quiet --entire "=" $np
+        echo $np | read --function --delimiter "=" channel new_src_rel
+        set --local new_src (path resolve $new_src_rel)
+
+        if test $channel = darwin-config
+            continue
+        end
+        if set --local i (contains --index $channel $old_channels)
+            set --erase old_channels[$i]
+        end
+
+        update_link $new_src $channel_root/$channel
+    end
+end
+
+for old in $channel_root/$old_channels
+    rm $old
+end
+
+if set --function i (contains --index (status dirname) $PATH) && test -n $i
+    set --erase PATH[$i]
+end
+
+set --function cmd $current_script_name $argv
+
+if contains -- -n $argv
+    set --prepend cmd echo
+end
+
+if set --query IN_NIX_SHELL
+    eval $cmd
+else
+    nix-shell --run "$cmd"
+end