Created
January 30, 2018 23:49
-
-
Save throwup/4ba545d77fe5d33e2cf29c9c868a0026 to your computer and use it in GitHub Desktop.
home-manager-generation/activate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/nix/store/i0ay05pqkbnvpfijm52mmlrp6kmkl80c-bash-4.4-p12/bin/bash | |
set -eu | |
set -o pipefail | |
cd $HOME | |
export PATH="/nix/store/i0ay05pqkbnvpfijm52mmlrp6kmkl80c-bash-4.4-p12/bin:/nix/store/qd55j183ym04y43aam889xkimq704rdx-coreutils-8.29/bin:/nix/store/18ak9x2mqr2inprnr4biad04n6pi4bc5-diffutils-3.6/bin:/nix/store/8x05myb28xqwixakpz0xhqyb8735kvy7-findutils-4.6.0/bin:/nix/store/rhbm7javg5n5zmhhld7qbi23n5qc0srf-gnugrep-3.1/bin:/nix/store/zgr9zbw7p8gihn9h0nj8ggkcplrd9g7f-gnused-4.4/bin:/nix/store/hk3s7q3486lkkipv291m7y498q6rj0pp-ncurses-6.0-20171125/bin:/nix/store/ggj0xvnkx0r22x21z4jnz16vq6k76wx0-nix-1.11.16/bin${PATH:+:}$PATH" | |
. /nix/store/nwyv4ajhvn210ppigg1g9z177g0g4ls4-color-echo.sh | |
function setupVars() { | |
local profilesPath="/nix/var/nix/profiles/per-user/$USER" | |
local gcPath="/nix/var/nix/gcroots/per-user/$USER" | |
local greatestGenNum | |
greatestGenNum=$( \ | |
find "$profilesPath" -name 'home-manager-*-link' \ | |
| sed 's/^.*-\([0-9]*\)-link$/\1/' \ | |
| sort -rn \ | |
| head -1) | |
if [[ -n "$greatestGenNum" ]] ; then | |
oldGenNum=$greatestGenNum | |
newGenNum=$((oldGenNum + 1)) | |
else | |
newGenNum=1 | |
fi | |
if [[ -e "$gcPath/current-home" ]] ; then | |
oldGenPath="$(readlink -e "$gcPath/current-home")" | |
fi | |
genProfilePath="$profilesPath/home-manager" | |
newGenPath="/nix/store/35ifr39r4119si4a7mij5dl8vs571c7c-home-manager-generation"; | |
newGenProfilePath="$profilesPath/home-manager-$newGenNum-link" | |
newGenGcPath="$gcPath/current-home" | |
} | |
setupVars | |
echo "Starting home manager activation" | |
if [[ -v VERBOSE ]]; then | |
export VERBOSE_ECHO=echo | |
export VERBOSE_ARG="--verbose" | |
else | |
export VERBOSE_ECHO=true | |
export VERBOSE_ARG="" | |
fi | |
if [[ -v DRY_RUN ]] ; then | |
echo "This is a dry run" | |
export DRY_RUN_CMD=echo | |
else | |
$VERBOSE_ECHO "This is a live run" | |
export DRY_RUN_CMD="" | |
fi | |
$VERBOSE_ECHO "Activation variables:" | |
if [[ -v oldGenNum ]] ; then | |
$VERBOSE_ECHO " oldGenNum=$oldGenNum" | |
$VERBOSE_ECHO " oldGenPath=$oldGenPath" | |
else | |
$VERBOSE_ECHO " oldGenNum undefined (first run?)" | |
$VERBOSE_ECHO " oldGenPath undefined (first run?)" | |
fi | |
$VERBOSE_ECHO " newGenPath=$newGenPath" | |
$VERBOSE_ECHO " newGenNum=$newGenNum" | |
$VERBOSE_ECHO " newGenProfilePath=$newGenProfilePath" | |
$VERBOSE_ECHO " newGenGcPath=$newGenGcPath" | |
$VERBOSE_ECHO " genProfilePath=$genProfilePath" | |
noteEcho Activating checkLinkTargets | |
function checkNewGenCollision() { | |
local newGenFiles | |
newGenFiles="$(readlink -e "$newGenPath/home-files")" | |
find "$newGenFiles" -type f -print0 -or -type l -print0 \ | |
| xargs -0 bash /nix/store/82x5wqxp7fiblr0h4kn1a288d4wqhd0x-check "$newGenFiles" | |
} | |
checkNewGenCollision || exit 1 | |
noteEcho Activating writeBoundary | |
noteEcho Activating installPackages | |
if nix-env -q | grep '^home-manager-path$'; then | |
nix-env -e home-manager-path | |
fi | |
noteEcho Activating linkGeneration | |
function linkNewGen() { | |
echo "Creating home file links in $HOME" | |
local newGenFiles | |
newGenFiles="$(readlink -e "$newGenPath/home-files")" | |
find "$newGenFiles" -type f -print0 -or -type l -print0 \ | |
| xargs -0 bash /nix/store/6cy75vf9p441gv614gdc654183dv0cgr-link "$newGenFiles" | |
} | |
function cleanOldGen() { | |
if [[ ! -v oldGenPath ]] ; then | |
return | |
fi | |
echo "Cleaning up orphan links from $HOME" | |
local newGenFiles oldGenFiles | |
newGenFiles="$(readlink -e "$newGenPath/home-files")" | |
oldGenFiles="$(readlink -e "$oldGenPath/home-files")" | |
# Apply the cleanup script on each leaf in the old | |
# generation. The find command below will print the | |
# relative path of the entry. | |
find "$oldGenFiles" '(' -type f -or -type l ')' -printf '%P\0' \ | |
| xargs -0 bash /nix/store/4rbvm2brng1fz7qi11sha2890pp4lk36-cleanup "$newGenFiles" | |
} | |
cleanOldGen | |
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then | |
echo "Creating profile generation $newGenNum" | |
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenProfilePath" | |
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG $(basename "$newGenProfilePath") "$genProfilePath" | |
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenGcPath" | |
else | |
echo "No change so reusing latest profile generation $oldGenNum" | |
fi | |
linkNewGen | |
noteEcho Activating reloadSystemD | |
if who | grep -q '^leo '; then | |
XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-/run/user/$(id -u)} \ | |
function isStartable() { | |
local service="$1" | |
[[ $(/nix/store/kassxrnp9s64mxg98dm4hh1h0138cgnl-systemd-234/bin/systemctl --user show -p RefuseManualStart "$service") == *=no ]] | |
} | |
function isStoppable() { | |
if [[ -v oldGenPath ]] ; then | |
local service="$1" | |
[[ $(/nix/store/kassxrnp9s64mxg98dm4hh1h0138cgnl-systemd-234/bin/systemctl --user show -p RefuseManualStop "$service") == *=no ]] | |
fi | |
} | |
function systemdPostReload() { | |
local workDir | |
workDir="$(mktemp -d)" | |
if [[ -v oldGenPath ]] ; then | |
local oldUserServicePath="$oldGenPath/home-files/.config/systemd/user" | |
fi | |
local newUserServicePath="$newGenPath/home-files/.config/systemd/user" | |
local oldServiceFiles="$workDir/old-files" | |
local newServiceFiles="$workDir/new-files" | |
local servicesDiffFile="$workDir/diff-files" | |
if [[ ! (-v oldUserServicePath && -d "$oldUserServicePath") \ | |
&& ! -d "$newUserServicePath" ]]; then | |
return | |
fi | |
if [[ ! (-v oldUserServicePath && -d "$oldUserServicePath") ]]; then | |
touch "$oldServiceFiles" | |
else | |
find "$oldUserServicePath" \ | |
-maxdepth 1 -name '*.service' -exec basename '{}' ';' \ | |
| sort \ | |
> "$oldServiceFiles" | |
fi | |
if [[ ! -d "$newUserServicePath" ]]; then | |
touch "$newServiceFiles" | |
else | |
find "$newUserServicePath" \ | |
-maxdepth 1 -name '*.service' -exec basename '{}' ';' \ | |
| sort \ | |
> "$newServiceFiles" | |
fi | |
diff \ | |
--new-line-format='+%L' \ | |
--old-line-format='-%L' \ | |
--unchanged-line-format=' %L' \ | |
"$oldServiceFiles" "$newServiceFiles" \ | |
> $servicesDiffFile || true | |
local -a maybeRestart=( $(grep '^ ' $servicesDiffFile | cut -c2-) ) | |
local -a maybeStop=( $(grep '^-' $servicesDiffFile | cut -c2-) ) | |
local -a maybeStart=( $(grep '^+' $servicesDiffFile | cut -c2-) ) | |
local -a toRestart=( ) | |
local -a toStop=( ) | |
local -a toStart=( ) | |
for f in ${maybeRestart[@]} ; do | |
if isStoppable "$f" \ | |
&& isStartable "$f" \ | |
&& /nix/store/kassxrnp9s64mxg98dm4hh1h0138cgnl-systemd-234/bin/systemctl --quiet --user is-active "$f" \ | |
&& ! cmp --quiet \ | |
"$oldUserServicePath/$f" \ | |
"$newUserServicePath/$f" ; then | |
toRestart+=("$f") | |
fi | |
done | |
for f in ${maybeStop[@]} ; do | |
if isStoppable "$f" ; then | |
toStop+=("$f") | |
fi | |
done | |
for f in ${maybeStart[@]} ; do | |
if isStartable "$f" ; then | |
toStart+=("$f") | |
fi | |
done | |
rm -r $workDir | |
local sugg="" | |
if [[ -n "${toRestart[@]}" ]] ; then | |
sugg="${sugg}systemctl --user restart ${toRestart[@]}\n" | |
fi | |
if [[ -n "${toStop[@]}" ]] ; then | |
sugg="${sugg}systemctl --user stop ${toStop[@]}\n" | |
fi | |
if [[ -n "${toStart[@]}" ]] ; then | |
sugg="${sugg}systemctl --user start ${toStart[@]}\n" | |
fi | |
if [[ -n "$sugg" ]] ; then | |
echo "Suggested commands:" | |
echo -n -e "$sugg" | |
fi | |
} | |
$DRY_RUN_CMD /nix/store/kassxrnp9s64mxg98dm4hh1h0138cgnl-systemd-234/bin/systemctl --user daemon-reload | |
systemdPostReload | |
else | |
echo "User leo not logged in. Skipping." | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment