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:
Bernardo Magri
2026-04-25 21:49:36 +01:00
parent c9ff6f26f3
commit bf30cd07d8
2 changed files with 60 additions and 6 deletions

View File

@@ -20,7 +20,6 @@ Guardrails (apply when adding anything):
### Now (ready to pick up)
- **Software-profile multi-select in the installer.** Carryover from the old TODO. Add a `gum choose --no-limit` step in `installer/install.sh` (between hardware and impermanence) for opt-in profiles (Dev, Gaming, Office, Media, …). Each profile maps to a list of `home.packages` and optional `nomarchy.system.*` toggles emitted into the generated `home.nix`/`system.nix`.
- **Richer disk metadata.** Carryover from the old TODO. Replace the bare `lsblk` line in `select_disk` with `lsblk -O -J` parsed via `jq`, surfacing vendor, model, serial, and size in the picker.
- **Menu cleanup of orphaned references.** Walk `features/scripts/utils/nomarchy-menu` (379 lines, 23 submenus) and either wire each menu item to a real script or replace the `case` arm with a stubbed `notify-send` until the script is ported. See Pillar 3 below.
- **Form-factor → laptop preset auto-enable.** When the installer writes `nomarchy.system.formFactor = "laptop"`, also flip on a yet-to-be-built laptop preset (TLP, brightness keys, lid handling). The option exists; the preset module doesn't.
@@ -82,7 +81,7 @@ Each PR description should reference the row(s) in `docs/SCRIPTS.md` it closes,
## 4. Pillar: Installer
- Software-profile multi-select (Now).
- Richer disk metadata (Now).
- Richer disk metadata (Shipped).
- Form-factor → laptop preset (Now, depends on Pillar 5).
- `disko-golden.nix` variants for software-RAID and BTRFS-pool-as-root.
- Pre-flight resume polish (Next).
@@ -130,5 +129,6 @@ Each PR description should reference the row(s) in `docs/SCRIPTS.md` it closes,
(Move items here when they land — keep them brief, link the commit/PR.)
- _2026-04-25_ — `docs/KEYBINDINGS.md` auto-generator. New repo-tooling script `bin/utils/nomarchy-docs-keybindings` parses every `bindd =` / `bindeld =` line into a Markdown doc; README's keybinding table slimmed to highlights + link.
- _2026-04-25_ — Installer disk picker shows NAME / SIZE / TYPE / VENDOR / MODEL / SERIAL columns instead of bare `lsblk`. Type derived from `ROTA` + `TRAN` (NVMe / USB / SSD / HDD). Filters loop, ram, zram, sr.
- _2026-04-25_ — Installer prompts for keyboard layout + locale, applies live; new `nomarchy.{system,}.formFactor` option; waybar drops battery widget on desktop; nm-applet visibility fix in default theme; live-ISO baseline keymap/locale (`a7e7fa9`).
- _2026-04-25_ — `docs/OPTIONS.md` reference; `docs/MIGRATION.md` linked from `README.md` (`3cb012b`, `6ef28f0`).

View File

@@ -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"