Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make flash script more interactive #13

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 102 additions & 54 deletions packages/flash.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
# Builds the firmware and copies it to the plugged-in keyboard half
packages.flash = pkgs.writeShellApplication {
name = "flash";
runtimeInputs = [
# Use Charm Gum for fancy interactivity
pkgs.gum
];
text = ''
set +e

Expand All @@ -17,74 +21,118 @@
# Enable nullglob so that non-matching globs have no output
shopt -s nullglob

# Store a reference to the CLI args for use within functions
declare -a args=("$@")

# Style
export GUM_SPIN_SPINNER="minidot"

# Indent piped input 4 spaces
indent() {
sed -e 's/^/ /'
}

# Platform specific disk candidates
declare -a disks
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
# Linux/GNU
# - /run/media/<user>/<disk>
disks=(/run/media/"$(whoami)"/GLV80*)
elif [[ "$OSTYPE" == "darwin"* ]]; then
# Mac OSX
# - /Volumes/<disk>
disks=(/Volumes/GLV80*)
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" ]]; then
# Cygwin or Msys2
# - /<drive letter>
disks=(/?)
elif (grep -sq Microsoft /proc/version); then
# WSL
# - /mnt/<drive letter>
disks=(/mnt/?)
else
echo "Error: Unable to detect platform!"
echo "OSTYPE=$OSTYPE"
echo "/proc/version"
indent < /proc/version
exit 1
fi

# Disks that have a matching INFO_UF2
declare -a matches
for disk in "''${disks[@]}"; do
if (grep -sq Glove80 "$disk"/INFO_UF2.TXT); then
matches+=("$disk")
# Prints a list of connected glove80s
list_keyboards() {
# Platform specific disk candidates
declare -a disks
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
# Linux/GNU
# - /run/media/<user>/<disk>
disks+=(/run/media/"$(whoami)"/GLV80*)
disks+=(/media/GLV80*)
disks+=(/mnt/*)
elif [[ "$OSTYPE" == "darwin"* ]]; then
# Mac OSX
# - /Volumes/<disk>
disks=(/Volumes/GLV80*)
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" ]]; then
# Cygwin or Msys2
# - /<drive letter>
disks=(/?)
elif grep -sq Microsoft /proc/version; then
# WSL
# - /mnt/<drive letter>
disks=(/mnt/?)
else
echo "Error: Unable to detect platform!" >&2
echo "OSTYPE=$OSTYPE" >&2
echo "/proc/version" >&2
indent < /proc/version >&2
fi
done

# Assert we found exactly one keyboard
count="''${#matches[@]}"
if [[ "$count" -lt 1 ]]; then
# No matches. Exit
echo "Error: No Glove80 connected!"
exit 1
elif [[ "$count" -gt 1 ]]; then
# Multiple matches. Print them and exit
echo "Error: $count Glove80s connected. Expected 1!"
# Check CLI args first
# Warn if any don't have a valid INFO_UF2
for disk in "''${args[@]}"; do
if grep -sq Glove80 "$disk"/INFO_UF2.TXT; then
echo "$disk"
else
echo "Not a Glove80 keyboard: $disk" >&2
fi
done

# Print disks that have a matching INFO_UF2
for disk in "''${disks[@]}"; do
if grep -sq Glove80 "$disk"/INFO_UF2.TXT; then
echo "$disk"
fi
done
}

# Flash all keyboards found by `list_keyboards`
flash_keyboards() {
declare -a matches
readarray -t matches < <(list_keyboards)
count="''${#matches[@]}"

# Print a summary of what `list_keyboards` has found
echo "Found $count keyboards connected."
for i in "''${!matches[@]}"; do
kb="''${matches[$i]}"
# Print the relevant lines from INFO_UF2
echo "$((i + 1)). $kb"
grep --no-filename --color=never Glove80 "$kb"/INFO_UF2.TXT | indent
indent < "$kb"/INFO_UF2.TXT
done
exit 1
fi
echo # blankline

for i in "''${!matches[@]}"; do
flash_keyboard "$((i + 1))" "''${matches[$i]}"
done
}

# We have a winner!
kb="''${matches[0]}"
echo "Found keyboard:"
echo "$kb"
indent < "$kb"/INFO_UF2.TXT
echo
# Flash the given keyboard
flash_keyboard() {
i="$1"
kb="$2"

# Flash by copying the firmware package
echo "Flashing firmware..."
cp -r "${config.packages.firmware}" "$kb" \
&& echo "Done!" || echo "Error: Unable to flash firmware!"
# Ask before flashing...
if gum confirm "$i. $kb" \
--default="yes" \
--affirmative="Flash" \
--negative="Cancel"
then
# Flash by copying the firmware package
gum spin --title "Flashing $kb" \
-- cp -Tfr "${config.packages.firmware}" "$kb" \
&& echo "$i. Flashed $kb" \
|| echo "$i. Error flashing $kb!"
else
echo "$i. Skipped $kb"
fi
}

# Run the script
flash_keyboards
while
gum confirm "Done" \
--default="no" \
--affirmative="Run again" \
--negative="Quit"
do
echo # blankline
echo "Running again"
flash_keyboards
done
'';
};
};
Expand Down