#! /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 <] 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 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 # 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