diff options
Diffstat (limited to 'pkgs/by-name/fu/fupdate/fupdate.sh')
-rwxr-xr-x | pkgs/by-name/fu/fupdate/fupdate.sh | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/pkgs/by-name/fu/fupdate/fupdate.sh b/pkgs/by-name/fu/fupdate/fupdate.sh new file mode 100755 index 00000000..4322610a --- /dev/null +++ b/pkgs/by-name/fu/fupdate/fupdate.sh @@ -0,0 +1,197 @@ +#! /usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +UPDATE_SCRIPT_NAME="update.sh" +CONFIG_DIRECTORY_PATH="$HOME/.local/share/flake-update" + +# Both are used in version() +# shellcheck disable=SC2034 +AUTHORS="Soispha" +# shellcheck disable=SC2034 +YEARS="2023" + +UPDATE_SCRIPT_NOT_WANTED=false + +# Searches upward for a `UPDATE_SCRIPT_NAME` script +# Returns a path to the script if it exists, otherwise nothing is returned +check_for_update_script() { + dirname="$(search_upward_files "$UPDATE_SCRIPT_NAME")" + if [ "$dirname" ]; then + printf "%s/%s" "$dirname" "$UPDATE_SCRIPT_NAME" + fi +} + +# Checks if a given path to the update script is allowed. +# Takes the path as input +# Return 0, if allowed, 1 if not. +check_for_allowed_update_script() { + update_script="$1" + config_path="${CONFIG_DIRECTORY_PATH}${update_script}" + update_script_hash="$(sha256sum "$update_script")" + if [ -f "$config_path" ]; then + if [ "$(cat "$config_path")" = "$update_script_hash" ]; then + dbg "Recorded hash matches" + return 0 + else + dbg "Recorded hash \'$(cat "$config_path")\' does not match real hash \'$update_script_hash\', assuming not allowed" + return 1 + fi + else + dbg "Path \'$config_path\' does not exist, assuming not allowed" + return 1 + fi +} + +# Asks the user if they want to allow a given script. +# Takes the path as input +ask_to_allow_update_script() { + update_script="$1" + config_path="${CONFIG_DIRECTORY_PATH}${update_script}" + update_script_hash="$(sha256sum "$update_script")" + println "\033[2J" # clear the screen + cat "$update_script" + readp "Do you want to allow this script?[N/y]: " allow + # shellcheck disable=SC2154 + dbg "allow is: $allow" + case "$allow" in + [yY]) + dbg "allowed script" + dbg "storing contents in: $config_path" + mkdir --parents "$(dirname "$config_path")" + print "$update_script_hash" >"$config_path" + ;; + *) + UPDATE_SCRIPT_NOT_ALLOWED=true + ;; + esac +} + +# Runs the provided script and continues to update the nix flake +# Takes the path to the script and the directory to the flake as arguments +# If the path to the update script is empty, it will be ignored +update() { + update_script="$1" + flake_base_dir="$2" + shift 2 + dbg "Provided following args to update script: '$*'" + + cd "$flake_base_dir" || die "Provided dir \'$flake_base_dir\' can not be accessed" + dbg "changed directory to: $flake_base_dir" + + nix flake update + + if ! [ "$update_script" = "" ] && ! [ "$UPDATE_SCRIPT_NOT_WANTED" = "true" ]; then + "$update_script" "$@" + fi + + if grep '[^0-9]_[0-9]' flake.lock >/dev/null; then + batgrep '[^0-9]_[0-9]' flake.lock + die "Your flake.nix contains duplicate inputs!" + fi +} + +help() { + cat <<EOF +This is a Nix flake update manager. + +USAGE: + $NAME [--help | --version] [flake [--no-script] | <some other command>] + +OPTIONS: + --help | -h + Display this help and exit. + + --version | -v + Display version and copyright information and exit. + + --no-script + Avoid running the 'update.sh' script +COMMANDS: + flake + update the flake project + + <some other command> + runs a executable called "update-<some other command>", if it exists +EOF +} + +main() { + if ! [ "$UPDATE_SCRIPT_NOT_ALLOWED" = true ]; then + update_script="$(check_for_update_script)" + flake_base_dir="$(search_flake_base_dir)" # Assume, that the update script is in the base dir + dbg "update_script is: $update_script" + dbg "flake_base_dir is: $flake_base_dir" + + if [ "$update_script" = "" ]; then + update "" "$flake_base_dir" "$@" + elif check_for_allowed_update_script "$update_script" && ! [ "$update_script" = "" ]; then + update "$update_script" "$flake_base_dir" "$@" + else + ask_to_allow_update_script "$update_script" + main "$@" + fi + fi +} + +if [ "$#" -eq 0 ]; then + main + exit 0 +fi + +for input in "$@"; do + case "$input" in + "--help" | "-h") + help + exit 0 + ;; + "--version" | "-v") + version + exit 0 + ;; + "--no-script" | "-n") + UPDATE_SCRIPT_NOT_WANTED=true + ;; + "--") + end_of_cli_options=true + + # Stop processing args after that marker. + break + ;; + esac + [ "$end_of_cli_options" = "true" ] && break +done + +case "$1" in +"flake") + shift 1 + + # Filter out fupdate specific flags + while [ "$1" != "--" ]; do + # FIXME: This check allows to add a flag multiple times, but this should probably + # not be allowed <2024-03-29> + case "$1" in + "--no-script" | "-n") + shift 1 + ;; + *) + break + ;; + esac + done + + [ "$1" = "--" ] && shift 1 + main "$@" + ;; +*) + command="$1" + shift 1 + [ "$1" = "--" ] && shift 1 + if which update-"$command" >/dev/null 2>&1; then + update-"$command" "$@" + else + die "command \"update-$command\" is not executable, or does not exist" + fi + ;; +esac |