#! /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: '$*'" dbg "changed directory to: $flake_base_dir" cd "$flake_base_dir" || die "Provided dir \'$flake_base_dir\' can not be accessed" 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 < runs a executable called "update-", 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 ;; esac [ "$end_of_cli_options" = "true" ] && break done case "$1" in "flake") shift 1 [ "$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