about summary refs log blame commit diff stats
path: root/hm/soispha/pkgs/scripts/apps/fupdate
blob: e18aae1fc7f63e2ede9cdad6f51308fdabc124b1 (plain) (tree)
1
2
3
4

                             
                                                    

































































































































































                                                                                                                                 
#! /usr/bin/env dash

# shellcheck source=/dev/null
SHELL_LIBRARY_VERSION="1.10.0" . %SHELL_LIBRARY_PATH


UPDATE_SCRIPT_NAME="update.sh";
CONFIG_DIRECTORY_PATH="$HOME/.local/share/flake-update";

AUTHORS="Soispha"
YEARS="2023"

# 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;
    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";

    [ "$update_script" = "" ] || "$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 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]

Options:
    --help   | -h
                            Display this help and exit.
    --version   | -v
                            Display version and copyright information and exit.

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;
fi

for input in "$@"; do
    case "$input" in
        "--help" | "-h")
            help;
            exit 0;
            ;;
        "--version" | "-v")
            version;
            exit 0;
            ;;
        "--")
            end_of_cli_options=true;
            ;;
    esac
    [ "$end_of_cli_options" = "true" ] && break
done

while [ "$#" -ne 0 ]; do
    case "$1" in
        "flake")
            main;
            shift 1;
            ;;
        *)
            command="$1";
            shift 1;
            [ "$1" = "--" ] && shift 1
            if which update-"$command" > /dev/null 2>&1;then
                if [ "$end_of_cli_options" = "true" ]; then
                    update-"$command" "$@";
                else
                    update-"$command";
                fi
            else
                die "command \"update-$command\" is not executable, or does not exist";
            fi
            ;;
    esac
    [ "$end_of_cli_options" = "true" ] && break
done