feat(installer): richer disk picker (vendor, model, serial, type)
Replaces the bare `NAME SIZE` lsblk listing in select_disk with a six-column table — NAME, SIZE, TYPE, VENDOR, MODEL, SERIAL — aligned via column -t. TYPE is derived from ROTA + TRAN (NVMe / USB / SSD / HDD). Empty vendor/model/serial fields render as `--` instead of collapsing the alignment. Filters loop, ram, zram, sr devices. Roadmap row moves to Shipped. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -220,14 +220,68 @@ select_disk() {
|
||||
return
|
||||
fi
|
||||
|
||||
# Build a richer drive table than the bare `NAME SIZE` lsblk default.
|
||||
# Columns: NAME, SIZE, TYPE (NVMe/USB/SSD/HDD), VENDOR, MODEL, SERIAL.
|
||||
# Empty fields render as "--" so column -t can still align them.
|
||||
local raw rows=""
|
||||
raw=$(lsblk -d -n -p -o NAME,SIZE,ROTA,TRAN,VENDOR,MODEL,SERIAL 2>/dev/null \
|
||||
| grep -vE '^(/dev/(loop|ram|zram|sr))')
|
||||
|
||||
while IFS= read -r line; do
|
||||
[[ -z "$line" ]] && continue
|
||||
# NAME and SIZE are reliably whitespace-free; ROTA/TRAN are short
|
||||
# tokens; VENDOR/MODEL/SERIAL can carry internal spaces. Pull the
|
||||
# first four fields off the front, treat the rest as the
|
||||
# vendor/model/serial trio split via the original lsblk column
|
||||
# widths — easier to just re-query each device for clean values.
|
||||
local dev size rota tran
|
||||
read -r dev size rota tran _ <<<"$line"
|
||||
|
||||
local type vendor model serial
|
||||
case "$tran" in
|
||||
nvme) type="NVMe" ;;
|
||||
usb) type="USB" ;;
|
||||
sata|scsi)
|
||||
if [[ "$rota" == "1" ]]; then type="HDD"; else type="SSD"; fi
|
||||
;;
|
||||
*)
|
||||
if [[ "$rota" == "1" ]]; then type="HDD"; else type="SSD"; fi
|
||||
;;
|
||||
esac
|
||||
|
||||
vendor=$(lsblk -d -n -o VENDOR "$dev" 2>/dev/null | sed -E 's/^[[:space:]]+//;s/[[:space:]]+$//')
|
||||
model=$(lsblk -d -n -o MODEL "$dev" 2>/dev/null | sed -E 's/^[[:space:]]+//;s/[[:space:]]+$//')
|
||||
serial=$(lsblk -d -n -o SERIAL "$dev" 2>/dev/null | sed -E 's/^[[:space:]]+//;s/[[:space:]]+$//')
|
||||
[[ -z "$vendor" ]] && vendor="--"
|
||||
[[ -z "$model" ]] && model="--"
|
||||
[[ -z "$serial" ]] && serial="--"
|
||||
|
||||
# Tab-separated for column -t -s, then collapse internal whitespace
|
||||
# in MODEL so multi-space brand strings don't break alignment.
|
||||
rows+=$(printf '%s\t%s\t%s\t%s\t%s\t%s\n' \
|
||||
"$dev" "$size" "$type" "$vendor" "${model//$'\t'/ }" "$serial")
|
||||
rows+=$'\n'
|
||||
done <<<"$raw"
|
||||
|
||||
if [[ -z "$rows" ]]; then
|
||||
error "No installable drives found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
info "Available drives:"
|
||||
echo ""
|
||||
lsblk -d -n -p -o NAME,SIZE,MODEL | grep -v loop
|
||||
{
|
||||
printf 'NAME\tSIZE\tTYPE\tVENDOR\tMODEL\tSERIAL\n'
|
||||
printf '%s' "$rows"
|
||||
} | column -t -s $'\t'
|
||||
echo ""
|
||||
|
||||
local drives
|
||||
drives=$(lsblk -d -n -p -o NAME,SIZE | grep -v loop)
|
||||
TARGET_DRIVE=$(echo "$drives" | gum choose --header "Select target drive" | awk '{print $1}')
|
||||
# gum choose gets the same aligned rows so the picker reads like the table.
|
||||
local picker
|
||||
picker=$(printf '%s' "$rows" | column -t -s $'\t')
|
||||
local choice
|
||||
choice=$(printf '%s\n' "$picker" | gum choose --header "Select target drive")
|
||||
TARGET_DRIVE=$(awk '{print $1}' <<<"$choice")
|
||||
|
||||
if [[ -z "$TARGET_DRIVE" ]]; then
|
||||
error "No drive selected"
|
||||
|
||||
Reference in New Issue
Block a user