Installs the core script + lib/ under XDG_DATA_HOME/floppy-utils and generates thin wrappers in ~/.local/bin. Updates floppy resolver, install.sh, README, and adds early returns in check-deps logging helpers.
230 lines
5.5 KiB
Bash
Executable File
230 lines
5.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Verify dependencies for floppy-utils on Debian-based systems; optionally install via apt.
|
|
set -euo pipefail
|
|
|
|
INSTALL=0
|
|
QUIET=0
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage: check-deps.sh [OPTIONS]
|
|
|
|
Check that base tools required by floppy-utils are available.
|
|
On Debian, Ubuntu, Raspberry Pi OS, and derivatives, missing packages can be
|
|
installed with apt when --install is passed.
|
|
|
|
Options:
|
|
--install, -i Install missing packages (requires apt and root/sudo)
|
|
--quiet, -q Only print errors and the install command
|
|
-h, --help Show this help
|
|
|
|
Examples:
|
|
./check-deps.sh
|
|
./check-deps.sh --install
|
|
sudo ./check-deps.sh -i
|
|
EOF
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--install|-i) INSTALL=1; shift ;;
|
|
--quiet|-q) QUIET=1; shift ;;
|
|
-h|--help) usage; exit 0 ;;
|
|
*) echo "check-deps.sh: unknown option: $1" >&2; usage >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
log() {
|
|
if [[ "$QUIET" -eq 0 ]]; then
|
|
echo "$@"
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
warn() {
|
|
echo "check-deps.sh: $*" >&2
|
|
return 0
|
|
}
|
|
|
|
die() {
|
|
warn "$*"
|
|
exit 1
|
|
}
|
|
|
|
is_debian_like() {
|
|
if [[ -f /etc/debian_version ]]; then
|
|
return 0
|
|
fi
|
|
if [[ -f /etc/os-release ]]; then
|
|
# shellcheck source=/dev/null
|
|
source /etc/os-release
|
|
case "${ID:-}:${ID_LIKE:-}" in
|
|
debian:*|*debian*|ubuntu:*|*ubuntu*|raspbian:*|linuxmint:*|pop:*|elementary:*|kali:*|devuan:*)
|
|
return 0
|
|
;;
|
|
esac
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
os_description() {
|
|
if [[ -f /etc/os-release ]]; then
|
|
# shellcheck source=/dev/null
|
|
source /etc/os-release
|
|
printf '%s %s\n' "${NAME:-Linux}" "${VERSION_ID:-}"
|
|
elif [[ -f /etc/debian_version ]]; then
|
|
printf 'Debian %s\n' "$(cat /etc/debian_version)"
|
|
else
|
|
echo "Unknown"
|
|
fi
|
|
}
|
|
|
|
# command -> Debian package providing it
|
|
declare -A CMD_PKG=(
|
|
[lsblk]=util-linux
|
|
[blockdev]=util-linux
|
|
[losetup]=util-linux
|
|
[findmnt]=util-linux
|
|
[fdisk]=util-linux
|
|
[blkid]=util-linux
|
|
[mount]=mount
|
|
[umount]=mount
|
|
[dd]=coreutils
|
|
[readlink]=coreutils
|
|
[mkfs.vfat]=dosfstools
|
|
[sudo]=sudo
|
|
[udisksctl]=udisks2
|
|
[udevadm]=udev
|
|
[eject]=eject
|
|
)
|
|
|
|
REQUIRED_CMDS=(
|
|
lsblk blockdev losetup findmnt blkid mount umount dd readlink mkfs.vfat
|
|
)
|
|
|
|
RECOMMENDED_CMDS=(
|
|
sudo udisksctl udevadm eject fdisk
|
|
)
|
|
|
|
have_cmd() {
|
|
command -v "$1" >/dev/null 2>&1
|
|
}
|
|
|
|
packages_for_cmds() {
|
|
local -A seen=()
|
|
local cmd pkg
|
|
for cmd in "$@"; do
|
|
pkg="${CMD_PKG[$cmd]:-}"
|
|
[[ -n "$pkg" && -z "${seen[$pkg]:-}" ]] || continue
|
|
seen[$pkg]=1
|
|
printf '%s\n' "$pkg"
|
|
done
|
|
}
|
|
|
|
check_cmds() {
|
|
local label="$1"
|
|
local required="$2"
|
|
shift 2
|
|
local cmd
|
|
local -a missing=()
|
|
|
|
log "$label"
|
|
for cmd in "$@"; do
|
|
if have_cmd "$cmd"; then
|
|
log " OK $cmd"
|
|
else
|
|
if [[ "$required" -eq 1 ]]; then
|
|
log " MISS $cmd (required)"
|
|
else
|
|
log " MISS $cmd (recommended)"
|
|
fi
|
|
missing+=("$cmd")
|
|
fi
|
|
done
|
|
log ""
|
|
|
|
MISSING_RESULT=("${missing[@]}")
|
|
}
|
|
|
|
run_apt_install() {
|
|
local -a packages=("$@")
|
|
[[ ${#packages[@]} -gt 0 ]] || return 0
|
|
|
|
if ! command -v apt-get >/dev/null 2>&1; then
|
|
die "apt-get not found; install manually: ${packages[*]}"
|
|
fi
|
|
|
|
local -a apt_cmd=(apt-get)
|
|
if [[ "$(id -u)" -ne 0 ]]; then
|
|
command -v sudo >/dev/null 2>&1 || die "root or sudo required to install: ${packages[*]}"
|
|
apt_cmd=(sudo apt-get)
|
|
fi
|
|
|
|
log "Installing: ${packages[*]}"
|
|
"${apt_cmd[@]}" update -qq
|
|
DEBIAN_FRONTEND=noninteractive "${apt_cmd[@]}" install -y --no-install-recommends "${packages[@]}"
|
|
}
|
|
|
|
main() {
|
|
local -a missing_required=() missing_recommended=() packages=()
|
|
local debian=0
|
|
|
|
log "floppy-utils dependency check"
|
|
log "OS: $(os_description)"
|
|
|
|
if is_debian_like; then
|
|
debian=1
|
|
log "Debian-based system detected."
|
|
else
|
|
warn "Not a Debian-based system — will check commands only (no apt install)."
|
|
fi
|
|
log ""
|
|
|
|
check_cmds "Required commands:" 1 "${REQUIRED_CMDS[@]}"
|
|
missing_required=("${MISSING_RESULT[@]}")
|
|
check_cmds "Recommended commands:" 0 "${RECOMMENDED_CMDS[@]}"
|
|
missing_recommended=("${MISSING_RESULT[@]}")
|
|
|
|
if [[ ${#missing_required[@]} -eq 0 && ${#missing_recommended[@]} -eq 0 ]]; then
|
|
log "All required and recommended commands are available."
|
|
exit 0
|
|
fi
|
|
|
|
if [[ ${#missing_required[@]} -gt 0 ]]; then
|
|
log "Missing required: ${missing_required[*]}"
|
|
fi
|
|
if [[ ${#missing_recommended[@]} -gt 0 ]]; then
|
|
log "Missing recommended: ${missing_recommended[*]}"
|
|
fi
|
|
|
|
mapfile -t packages < <(packages_for_cmds "${missing_required[@]}" "${missing_recommended[@]}")
|
|
if [[ ${#packages[@]} -gt 0 ]]; then
|
|
log "Debian packages: ${packages[*]}"
|
|
fi
|
|
|
|
if [[ "$INSTALL" -eq 1 ]]; then
|
|
[[ "$debian" -eq 1 ]] || die "refusing --install on non-Debian system"
|
|
run_apt_install "${packages[@]}"
|
|
log ""
|
|
log "Re-checking..."
|
|
INSTALL=0
|
|
main
|
|
return
|
|
fi
|
|
|
|
if [[ "$debian" -eq 1 && ${#packages[@]} -gt 0 ]]; then
|
|
log ""
|
|
log "To install:"
|
|
log " sudo ./check-deps.sh --install"
|
|
log " # or: sudo apt-get install -y ${packages[*]}"
|
|
fi
|
|
|
|
if [[ ${#missing_required[@]} -gt 0 ]]; then
|
|
die "required dependencies missing"
|
|
fi
|
|
|
|
warn "recommended tools missing — floppy-utils works with reduced functionality"
|
|
exit 0
|
|
}
|
|
|
|
main |