diff --git a/bin/fix-broken-symlinks.sh b/bin/fix-broken-symlinks.sh new file mode 100644 index 0000000..a83cf1f --- /dev/null +++ b/bin/fix-broken-symlinks.sh @@ -0,0 +1,93 @@ +#!/bin/bash + +# A script to find and remove broken symbolic links in a directory. +# +# OPTIONS: +# -y: Automatically remove all broken links without confirmation. +# -q: Quiet mode. Suppress all non-error output. + +set -euo pipefail + +# --- Default settings --- +FORCE_DELETE=0 +QUIET=0 +TARGET_DIR="." + +# --- Helper function for logging --- +log() { + if [ "${QUIET}" -eq 0 ]; then + echo "$@" + fi +} + +# --- Usage function --- +usage() { + echo "Usage: $0 [-y] [-q] [TARGET_DIRECTORY]" + echo " -y: Yes. Automatically remove broken symlinks without confirmation." + echo " -q: Quiet. Suppress all output except for errors." + echo " TARGET_DIRECTORY: The directory to scan. Defaults to the current directory." + exit 1 +} + +# --- Parse command-line options --- +while getopts "yq" opt; do + case ${opt} in + y) + FORCE_DELETE=1 + ;; + q) + QUIET=1 + ;; + *) + usage + ;; + esac +done +shift $((OPTIND - 1)) # Remove the parsed options + +# --- Set target directory --- +# Use the first remaining argument as the target directory. +if [ -n "$1" ]; then + TARGET_DIR="$1" +fi + +if [ ! -d "${TARGET_DIR}" ]; then + echo "Error: Directory '${TARGET_DIR}' not found." >&2 + exit 1 +fi + +log "Searching for broken symlinks in '${TARGET_DIR}'..." + +# --- Main logic --- +# Find broken symlinks and process them. +find "${TARGET_DIR}" -type l ! -exec test -e {} \; -print0 | while IFS= read -r -d '' link; do + if [ "${FORCE_DELETE}" -eq 1 ]; then + # No confirmation needed, just delete. + if rm "${link}"; then + log "Removed '${link}'." + else + # Errors should still be reported. + echo "Failed to remove '${link}'." >&2 + fi + else + # If in quiet mode but not force mode, we can't prompt, so we skip. + if [ "${QUIET}" -eq 1 ]; then + continue + fi + # Ask the user for confirmation. + read -p "Remove broken symlink '${link}'? [y/N] " -n 1 -r + echo # Move to a new line after input. + + if [[ $REPLY =~ ^[Yy]$ ]]; then + if rm "${link}"; then + log "Removed '${link}'." + else + echo "Failed to remove '${link}'." >&2 + fi + else + log "Skipped '${link}'." + fi + fi +done + +log "Cleanup complete." \ No newline at end of file diff --git a/bin/restic-backup.sh b/bin/restic-backup.sh index 07acd05..71893e2 100755 --- a/bin/restic-backup.sh +++ b/bin/restic-backup.sh @@ -12,7 +12,7 @@ case "${RESTIC_BACKEND:=${RESTIC_DEFAULT_BE}}" in export RESTIC_REPOSITORY="gs:systemoverlord-backups-scar-2:/" ;; b2) - . ${HOME}/.restic-backups-scar-creds + . "${HOME}/.restic-backups-scar-creds" export AWS_ACCESS_KEY_ID export AWS_SECRET_ACCESS_KEY export RESTIC_REPOSITORY="s3:s3.us-west-004.backblazeb2.com/systemoverlord-backups-scar" @@ -23,7 +23,7 @@ case "${RESTIC_BACKEND:=${RESTIC_DEFAULT_BE}}" in ;; esac -cd ${HOME} +cd "${HOME}" if [ -z "${1}" ] ; then diff --git a/clone.sh b/clone.sh index e2988ad..9eeacde 100755 --- a/clone.sh +++ b/clone.sh @@ -2,22 +2,68 @@ set -ue -# Script to clone and install +# --- Helper function to install git --- +install_git() { + echo "Git not found. Attempting to install..." >&2 + case "$(uname)" in + Darwin) + if command -v brew >/dev/null 2>&1; then + echo "Using Homebrew to install git..." >&2 + brew install git + else + echo "Error: Homebrew not found on your macOS system." >&2 + echo "Please install Homebrew first by visiting https://brew.sh/ then run this script again." >&2 + return 1 + fi + ;; + Linux) + if command -v apt-get >/dev/null 2>&1; then + echo "Using apt-get to install git..." >&2 + if [ "${EUID:-$(id -u)}" -ne 0 ]; then + sudo apt-get update && sudo apt-get install -y git + else + apt-get update && apt-get install -y git + fi + else + echo "Error: This script requires 'apt-get' on Linux to install git." >&2 + echo "Please install git using your system's package manager and run this script again." >&2 + return 1 + fi + ;; + *) + echo "Error: Unsupported operating system '$(uname)'." >&2 + echo "Please install git manually and run this script again." >&2 + return 1 + ;; + esac +} -# Wrapped in a function to prevent incomplete execution if download is -# interrupted -function installer_main { - if ! command -v git >/dev/null 2>&1 ; then - ( if [ "$EUID" != 0 ] ; then - sudo apt install -y git - else - apt install -y git - fi ) || ( echo 'Failed to install git!' >/dev/stderr; false) +# --- Main script logic --- +installer_main() { + # 1. Check for git, and try to install it if it's missing. + if ! command -v git >/dev/null 2>&1; then + install_git + # Final check after attempting installation + if ! command -v git >/dev/null 2>&1; then + echo "ERROR: git installation failed or was not found." >&2 + echo "Please install git manually and re-run this script." >&2 + exit 1 + fi fi - git clone --depth 1 https://github.com/Matir/skel.git ${HOME}/.skel + # 2. Clone the repository if it doesn't exist + local dest="${HOME}/.skel" + if [ -d "${dest}" ]; then + echo "Repository already exists in ${dest}. Skipping clone." >&2 + else + echo "Cloning repository..." >&2 + git clone --depth 1 https://github.com/Matir/skel.git "${dest}" + fi - ${HOME}/.skel/install.sh + # 3. Run the main installer + echo "Running main installer..." >&2 + "${dest}/install.sh" } installer_main +