mirror of
https://github.com/nix-community/home-manager
synced 2024-06-02 21:13:33 +02:00
9c1b3735b4
This command allows the user to examine the news items generated by the news module. See #52. Many thanks to @nonsequitur and @uvNikita for suggestions and improvements.
291 lines
7.4 KiB
Bash
291 lines
7.4 KiB
Bash
#!@bash@/bin/bash
|
|
|
|
# This code explicitly requires GNU Core Utilities and we therefore
|
|
# need to ensure they are prioritized over any other similarly named
|
|
# tools on the system.
|
|
PATH=@coreutils@/bin:@less@/bin${PATH:+:}$PATH
|
|
|
|
set -euo pipefail
|
|
|
|
function errorEcho() {
|
|
echo $* >&2
|
|
}
|
|
|
|
# Attempts to set the HOME_MANAGER_CONFIG global variable.
|
|
#
|
|
# If no configuration file can be found then this function will print
|
|
# an error message and exit with an error code.
|
|
function setConfigFile() {
|
|
if [[ -v HOME_MANAGER_CONFIG ]] ; then
|
|
if [[ ! -e "$HOME_MANAGER_CONFIG" ]] ; then
|
|
errorEcho "No configure file found at $HOME_MANAGER_CONFIG"
|
|
exit 1
|
|
fi
|
|
|
|
HOME_MANAGER_CONFIG="$(realpath "$HOME_MANAGER_CONFIG")"
|
|
return
|
|
fi
|
|
|
|
local confFile
|
|
for confFile in "$HOME/.config/nixpkgs/home.nix" \
|
|
"$HOME/.nixpkgs/home.nix" ; do
|
|
if [[ -e "$confFile" ]] ; then
|
|
HOME_MANAGER_CONFIG="$confFile"
|
|
return
|
|
fi
|
|
done
|
|
|
|
errorEcho "No configuration file found." \
|
|
"Please create one at ~/.config/nixpkgs/home.nix"
|
|
exit 1
|
|
}
|
|
|
|
function setHomeManagerModulesPath() {
|
|
local modulesPath
|
|
for modulesPath in "@MODULES_PATH@" \
|
|
"$HOME/.config/nixpkgs/home-manager/modules" \
|
|
"$HOME/.nixpkgs/home-manager/modules" ; do
|
|
if [[ -e "$modulesPath" ]] ; then
|
|
export NIX_PATH="$NIX_PATH${NIX_PATH:+:}home-manager=$modulesPath"
|
|
return
|
|
fi
|
|
done
|
|
}
|
|
|
|
function doBuildAttr() {
|
|
setConfigFile
|
|
setHomeManagerModulesPath
|
|
|
|
local extraArgs="$*"
|
|
|
|
for p in "${EXTRA_NIX_PATH[@]}"; do
|
|
extraArgs="$extraArgs -I $p"
|
|
done
|
|
|
|
if [[ -v VERBOSE ]]; then
|
|
extraArgs="$extraArgs --show-trace"
|
|
fi
|
|
|
|
nix-build \
|
|
"@HOME_MANAGER_EXPR_PATH@" \
|
|
$extraArgs \
|
|
--argstr confPath "$HOME_MANAGER_CONFIG" \
|
|
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
|
|
}
|
|
|
|
function presentNews() {
|
|
local infoFile
|
|
infoFile=$(doBuildNews -A newsInfo) || return 1
|
|
|
|
# shellcheck source=/dev/null
|
|
. "$infoFile"
|
|
|
|
if [[ $newsNumUnread -eq 0 ]]; then
|
|
return
|
|
elif [[ "$newsDisplay" == "silent" ]]; then
|
|
return
|
|
elif [[ "$newsDisplay" == "notify" ]]; then
|
|
local msg
|
|
if [[ $newsNumUnread -eq 1 ]]; then
|
|
msg="There is an unread and relevant news item.\n"
|
|
msg+="Read it by running the command '$(basename "$0") news'."
|
|
else
|
|
msg="There are $newsNumUnread unread and relevant news items.\n"
|
|
msg+="Read them by running the command '$(basename "$0") news'."
|
|
fi
|
|
|
|
# Not actually an error but here stdout is reserved for
|
|
# nix-build output.
|
|
errorEcho
|
|
errorEcho -e "$msg"
|
|
errorEcho
|
|
|
|
if [[ -v DISPLAY ]] && type -P notify-send > /dev/null; then
|
|
notify-send "Home Manager" "$msg"
|
|
fi
|
|
elif [[ "$newsDisplay" == "show" ]]; then
|
|
doShowNews --unread
|
|
else
|
|
errorEcho "Unknown 'news.display' setting '$newsDisplay'."
|
|
fi
|
|
}
|
|
|
|
function doBuild() {
|
|
doBuildAttr -A activationPackage
|
|
presentNews
|
|
}
|
|
|
|
function doSwitch() {
|
|
local generation
|
|
local exitCode=0
|
|
local wrkdir
|
|
|
|
# Build the generation and run the activate script. Note, we
|
|
# specify an output link si that it is treated as a GC root. This
|
|
# prevents an unfortunately timed GC from removing the generation
|
|
# before activation completes.
|
|
wrkdir="$(mktemp -d)"
|
|
generation=$(doBuildAttr -o "$wrkdir/result" -A activationPackage) \
|
|
&& $generation/activate || exitCode=1
|
|
|
|
# Because the previous command never fails, the script keeps
|
|
# running and $wrkdir is always removed.
|
|
rm -r "$wrkdir"
|
|
|
|
if [[ $exitCode -eq 0 ]]; then
|
|
presentNews
|
|
fi
|
|
|
|
return $exitCode
|
|
}
|
|
|
|
function doListGens() {
|
|
pushd "/nix/var/nix/profiles/per-user/$USER" > /dev/null
|
|
ls --color=yes -gG --sort time home-manager-*-link \
|
|
| cut -d' ' -f 4-
|
|
popd > /dev/null
|
|
}
|
|
|
|
function doListPackages() {
|
|
local outPath
|
|
outPath="$(nix-env -q --out-path | grep -o '/.*home-manager-path$')"
|
|
if [[ -n "$outPath" ]] ; then
|
|
nix-store -q --references "$outPath" | sed 's/[^-]*-//'
|
|
else
|
|
errorEcho "No home-manager packages seem to be installed."
|
|
fi
|
|
}
|
|
|
|
function newsReadIdsFile() {
|
|
local dataDir="${XDG_DATA_HOME:-$HOME/.local/share}/home-manager"
|
|
local path="$dataDir/news-read-ids"
|
|
|
|
# If the path doesn't exist then we should create it, otherwise
|
|
# Nix will error out when we attempt to use builtins.readFile.
|
|
if [[ ! -f "$path" ]]; then
|
|
mkdir -p "$dataDir"
|
|
touch "$path"
|
|
fi
|
|
|
|
echo "$path"
|
|
}
|
|
|
|
function doBuildNews() {
|
|
doBuildAttr "$*" \
|
|
--no-out-link \
|
|
--arg check false \
|
|
--argstr newsReadIdsFile "$(newsReadIdsFile)"
|
|
}
|
|
|
|
function doShowNews() {
|
|
local infoFile
|
|
infoFile=$(doBuildNews -A newsInfo) || return 1
|
|
|
|
# shellcheck source=/dev/null
|
|
. "$infoFile"
|
|
|
|
case $1 in
|
|
--all)
|
|
${PAGER:-less} "$newsFileAll"
|
|
;;
|
|
--unread)
|
|
${PAGER:-less} "$newsFileUnread"
|
|
;;
|
|
*)
|
|
errorEcho "Unknown argument $1"
|
|
return 1
|
|
esac
|
|
|
|
if [[ -s "$newsUnreadIdsFile" ]]; then
|
|
local newsReadIdsFile
|
|
newsReadIdsFile="$(newsReadIdsFile)"
|
|
cat "$newsUnreadIdsFile" >> "$newsReadIdsFile"
|
|
fi
|
|
}
|
|
|
|
function doHelp() {
|
|
echo "Usage: $0 [OPTION] COMMAND"
|
|
echo
|
|
echo "Options"
|
|
echo
|
|
echo " -f FILE The home configuration file."
|
|
echo " Default is '~/.config/nixpkgs/home.nix'."
|
|
echo " -A ATTRIBUTE Optional attribute that selects a configuration"
|
|
echo " expression in the configuration file."
|
|
echo " -I PATH Add a path to the Nix expression search path."
|
|
echo " -v Verbose output"
|
|
echo " -n Do a dry run, only prints what actions would be taken"
|
|
echo " -h Print this help"
|
|
echo
|
|
echo "Commands"
|
|
echo " help Print this help"
|
|
echo " build Build configuration into result directory"
|
|
echo " switch Build and activate configuration"
|
|
echo " generations List all home environment generations"
|
|
echo " packages List all packages installed in home-manager-path"
|
|
echo " news Show news entries in a pager"
|
|
}
|
|
|
|
EXTRA_NIX_PATH=()
|
|
HOME_MANAGER_CONFIG_ATTRIBUTE=""
|
|
|
|
while getopts f:I:A:vnh opt; do
|
|
case $opt in
|
|
f)
|
|
HOME_MANAGER_CONFIG="$OPTARG"
|
|
;;
|
|
I)
|
|
EXTRA_NIX_PATH+=("$OPTARG")
|
|
;;
|
|
A)
|
|
HOME_MANAGER_CONFIG_ATTRIBUTE="$OPTARG"
|
|
;;
|
|
v)
|
|
export VERBOSE=1
|
|
;;
|
|
n)
|
|
export DRY_RUN=1
|
|
;;
|
|
h)
|
|
doHelp
|
|
exit 0
|
|
;;
|
|
*)
|
|
errorEcho "Unknown option -$OPTARG"
|
|
doHelp >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Get rid of the options.
|
|
shift "$((OPTIND-1))"
|
|
|
|
cmd="$*"
|
|
|
|
case "$cmd" in
|
|
build)
|
|
doBuild
|
|
;;
|
|
switch)
|
|
doSwitch
|
|
;;
|
|
generations)
|
|
doListGens
|
|
;;
|
|
packages)
|
|
doListPackages
|
|
;;
|
|
news)
|
|
doShowNews --all
|
|
;;
|
|
help|--help)
|
|
doHelp
|
|
;;
|
|
*)
|
|
errorEcho "Unknown command: $cmd"
|
|
doHelp >&2
|
|
exit 1
|
|
;;
|
|
esac
|