From 947e81cc9a90d2f0f0b29f48952be311abfa6f32 Mon Sep 17 00:00:00 2001 From: William Vinnicombe Date: Thu, 11 Jun 2026 16:17:47 +0100 Subject: [PATCH] Check command order in README matches the order in `picotool help` --- README.md | 46 +++++++++++++++++++++++----------------------- gen_help_txt.sh | 47 +++++++++++++++++++++++++++++++++++++++++++++++ main.cpp | 28 +++++++++++++--------------- 3 files changed, 83 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 4c6a6682..3d764732 100644 --- a/README.md +++ b/README.md @@ -10,50 +10,50 @@ PICOTOOL: Tool for interacting with RP-series device(s) in BOOTSEL mode, or with an RP-series binary SYNOPSIS: + picotool help [] + picotool version [-s] [] picotool info [-b] [-m] [-p] [-d] [--debug] [-l] [-a] [device-selection] picotool info [-b] [-m] [-p] [-d] [--debug] [-l] [-a] [-t ] picotool config [-s ] [-g ] [device-selection] picotool config [-s ] [-g ] [-t ] picotool load [--ignore-partitions] [--family ] [-p ] [-n] [-N] [-u] [-v] [-x] [-t ] [-o ] [device-selection] - picotool encrypt [--quiet] [--verbose] [--embed] [--fast-rosc] [--use-mbedtls] [--otp-key-page ] [--hash] [--sign] [--no-clear] - [--pin-xip-sram] [-t ] [-o ] [-t ] - picotool seal [--quiet] [--verbose] [--hash] [--sign] [--clear] [--pin-xip-sram] [-t ] [-o ] [-t - ] [--major ] [--minor ] [--rollback [..]] - picotool link [--quiet] [--verbose] [-t ] [-t ] [-t ] [] [-t ] [-p ] picotool save [-p] [-v] [--family ] [-t ] [device-selection] picotool save -a [-v] [--family ] [-t ] [device-selection] picotool save -r [-v] [--family ] [-t ] [device-selection] + picotool verify [-t ] [device-selection] [-r ] [-o ] [device-selection] picotool erase [-a] [device-selection] picotool erase -p [device-selection] picotool erase -r [device-selection] - picotool verify [-t ] [device-selection] [-r ] [-o ] [device-selection] picotool reboot [-a] [-u] [-g ] [-c ] [device-selection] - picotool otp list|get|set|load|dump|permissions|white-label + picotool seal [--quiet] [--verbose] [--hash] [--sign] [--clear] [--pin-xip-sram] [-t ] [-o ] [-t + ] [--major ] [--minor ] [--rollback [..]] + picotool encrypt [--quiet] [--verbose] [--embed] [--fast-rosc] [--use-mbedtls] [--otp-key-page ] [--hash] [--sign] [--no-clear] + [--pin-xip-sram] [-t ] [-o ] [-t ] picotool partition info|create - picotool uf2 info|convert - picotool version [-s] [] + picotool uf2 convert|info + picotool otp get|set|load|white-label|permissions|dump|list picotool coprodis [--quiet] [--verbose] - picotool help [] + picotool link [--quiet] [--verbose] [-t ] [-t ] [-t ] [] [-t ] [-p ] COMMANDS: + help Show general help or help for a specific command + version Display picotool version info Display information from the target device(s) or file. Without any arguments, this will display basic information for all connected RP-series devices in BOOTSEL mode config Display or change program configuration settings from the target device(s) or file. load Load the program / memory range stored in a file onto the device. - encrypt Encrypt the program. - seal Add final metadata to a binary, optionally including a hash and/or signature. - link Link multiple binaries into one block loop. save Save the program / memory stored in flash on the device to a file. - erase Erase the program / memory stored in flash on the device. verify Check that the device contents match those in the file. + erase Erase the program / memory stored in flash on the device. reboot Reboot the device - otp Commands related to the RP2350 OTP (One-Time-Programmable) Memory + seal Add final metadata to a binary, optionally including a hash and/or signature. + encrypt Encrypt the program. partition Commands related to RP2350 Partition Tables uf2 Commands related to UF2 creation and status - version Display picotool version + otp Commands related to the RP2350 OTP (One-Time-Programmable) Memory coprodis Post-process coprocessor instructions in disassembly files. - help Show general help or help for a specific command + link Link multiple binaries into one block loop. Use "picotool help " for more info ``` @@ -1024,24 +1024,24 @@ OTP: Commands related to the RP2350 OTP (One-Time-Programmable) Memory SYNOPSIS: - picotool otp list [-p] [-n] [-f] [-i ] [..] picotool otp get [-c ] [-r] [-e] [-n] [-i ] [device-selection] [-z] [..] picotool otp set [-c ] [-r] [-e] [-s] [-i ] [-z] [device-selection] picotool otp load [-r] [-e] [-s ] [-i ] [-t ] [device-selection] + picotool otp white-label -s [device-selection] + picotool otp permissions [--led ] [--hash] [--sign] [device-selection] picotool otp dump [-r] [-e] [-p] [--output ] [device-selection] picotool otp dump [-r] [-e] [-p] [--output ] [-t ] - picotool otp permissions [--led ] [--hash] [--sign] [device-selection] - picotool otp white-label -s [device-selection] + picotool otp list [-p] [-n] [-f] [-i ] [..] SUB COMMANDS: - list List matching known registers/fields get Get the value of one or more OTP registers/fields (RP2350 only) set Set the value of an OTP row/field (RP2350 only) load Load the row range stored in a file into OTP and verify. Data is 2 bytes/row for ECC, 4 bytes/row for raw (MSB is ignored). (RP2350 only) - dump Dump entire OTP (RP2350 only) - permissions Set the OTP access permissions (RP2350 only) white-label Set the white labelling values in OTP (RP2350 only) + permissions Set the OTP access permissions (RP2350 only) + dump Dump entire OTP (RP2350 only) + list List matching known registers/fields ``` ### set/get diff --git a/gen_help_txt.sh b/gen_help_txt.sh index c68efb3d..4d3a7b3a 100755 --- a/gen_help_txt.sh +++ b/gen_help_txt.sh @@ -100,6 +100,49 @@ fi mv tmp/README.md README.md rm -rf tmp +# Check that command order in README matches picotool help output +echo "Checking command order..." + +order_mismatch=false + +check_cmd_order() { + local label="$1" tool_order="$2" readme_order="$3" + local fp="" fr="" + while IFS= read -r cmd; do + [ -z "$cmd" ] && continue + echo "$readme_order" | grep -qx "$cmd" && fp+="$cmd"$'\n' + done <<< "$tool_order" + while IFS= read -r cmd; do + [ -z "$cmd" ] && continue + echo "$tool_order" | grep -qx "$cmd" && fr+="$cmd"$'\n' + done <<< "$readme_order" + if [ "$fp" != "$fr" ]; then + echo "Order mismatch in $label!" + echo " picotool: $(echo "$fp" | tr '\n' ' ')" + echo " README: $(echo "$fr" | tr '\n' ' ')" + order_mismatch=true + fi +} + +# Check top-level command order +tool_top_order=$(picotool help 2>/dev/null | \ + awk '/^COMMANDS:/{f=1;next} f && /^[A-Z]/{exit} f && /^ [a-z]/{print $1}') +readme_top_order=$(grep -n '^\$ picotool help [a-z][a-z-]*$' README.md | \ + sed 's/^\([0-9]*\):.*\$ picotool help \([a-z][a-z-]*\)$/\1 \2/' | \ + sort -n | awk '{print $2}' | awk '!seen[$0]++') +check_cmd_order "top-level commands" "$tool_top_order" "$readme_top_order" + +# Check sub-command order for each parent command +for array in $sub_command_arrays; do + prefix=${array%_sub_commands} + tool_sub_order=$(picotool help "$prefix" 2>/dev/null | \ + awk '/^SUB COMMANDS:/{f=1;next} f && /^[A-Z]/{exit} f && /^ [a-z]/{print $1}') + readme_sub_order=$(grep -n "^\$ picotool help ${prefix} [a-z][a-z-]*$" README.md | \ + sed "s/^\([0-9]*\):.*\$ picotool help ${prefix} \([a-z][a-z-]*\)$/\1 \2/" | \ + sort -n | awk '{print $2}' | awk '!seen[$0]++') + check_cmd_order "${prefix} sub-commands" "$tool_sub_order" "$readme_sub_order" +done + echo "Help text sections have been updated in README.md" # Still fail if there are missing commands @@ -107,3 +150,7 @@ if [ ${#missing_commands[@]} -ne 0 ]; then echo "Failing job due to missing help text sections" exit 1 fi +if $order_mismatch; then + echo "Failing job due to command order mismatch in README" + exit 1 +fi diff --git a/main.cpp b/main.cpp index 81a9b0bb..dcee2ef0 100644 --- a/main.cpp +++ b/main.cpp @@ -1356,15 +1356,15 @@ struct otp_white_label_command : public cmd { vector> otp_sub_commands { - std::shared_ptr(new otp_list_command()), #if HAS_LIBUSB std::shared_ptr(new otp_get_command()), std::shared_ptr(new otp_set_command()), std::shared_ptr(new otp_load_command()), - std::shared_ptr(new otp_dump_command()), - std::shared_ptr(new otp_permissions_command()), std::shared_ptr(new otp_white_label_command()), + std::shared_ptr(new otp_permissions_command()), + std::shared_ptr(new otp_dump_command()), #endif + std::shared_ptr(new otp_list_command()), }; struct otp_command : public multi_cmd { @@ -1427,10 +1427,10 @@ struct uf2_convert_command : public cmd { }; vector> uf2_sub_commands { + std::shared_ptr(new uf2_convert_command()), #if HAS_LIBUSB std::shared_ptr(new uf2_info_command()), #endif - std::shared_ptr(new uf2_convert_command()), }; struct uf2_command : public multi_cmd { @@ -1558,28 +1558,26 @@ auto reboot_cmd = std::shared_ptr(new reboot_command()); auto help_cmd = std::shared_ptr(new help_command()); vector> commands { + help_cmd, + std::shared_ptr(new version_command()), std::shared_ptr(new info_command()), std::shared_ptr(new config_command()), #if HAS_LIBUSB std::shared_ptr(new load_command()), - #endif - #if HAS_MBEDTLS - std::shared_ptr(new encrypt_command()), - std::shared_ptr(new seal_command()), - #endif - std::shared_ptr(new link_command()), - #if HAS_LIBUSB std::shared_ptr(new save_command()), - std::shared_ptr(new erase_command()), std::shared_ptr(new verify_command()), + std::shared_ptr(new erase_command()), reboot_cmd, #endif - std::shared_ptr(new otp_command()), + #if HAS_MBEDTLS + std::shared_ptr(new seal_command()), + std::shared_ptr(new encrypt_command()), + #endif std::shared_ptr(new partition_command()), std::shared_ptr(new uf2_command()), - std::shared_ptr(new version_command()), + std::shared_ptr(new otp_command()), std::shared_ptr(new coprodis_command()), - help_cmd + std::shared_ptr(new link_command()), }; template