fix(validate-json): use natural sort for fw.json target order (#7558)

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Peter Feerick
2026-07-15 10:37:12 +10:00
committed by GitHub
co-authored by Claude Sonnet 5
parent 8a28c4ab96
commit bbb2ddb1dd
2 changed files with 18 additions and 11 deletions
+2 -2
View File
@@ -20,8 +20,6 @@
["HelloRadioSky V16", "v16-"], ["HelloRadioSky V16", "v16-"],
["iFlight Commando 8", "commando8-"], ["iFlight Commando 8", "commando8-"],
["Jumper Bumblebee", "bumblebee-"], ["Jumper Bumblebee", "bumblebee-"],
["Jumper T-Pro S", "tpros-"],
["Jumper T-Pro V2", "tprov2-"],
["Jumper T12 MAX", "t12max-"], ["Jumper T12 MAX", "t12max-"],
["Jumper T14", "t14-"], ["Jumper T14", "t14-"],
["Jumper T15", "t15-"], ["Jumper T15", "t15-"],
@@ -31,6 +29,8 @@
["Jumper T20", "t20-"], ["Jumper T20", "t20-"],
["Jumper T20 V2", "t20v2-"], ["Jumper T20 V2", "t20v2-"],
["Jumper T22", "t22-"], ["Jumper T22", "t22-"],
["Jumper T-Pro S", "tpros-"],
["Jumper T-Pro V2", "tprov2-"],
["RadioMaster Boxer", "boxer-"], ["RadioMaster Boxer", "boxer-"],
["RadioMaster GX12", "gx12-"], ["RadioMaster GX12", "gx12-"],
["RadioMaster MT12","mt12-"], ["RadioMaster MT12","mt12-"],
+16 -9
View File
@@ -34,6 +34,7 @@ Exit codes:
""" """
import json import json
import re
import sys import sys
import os import os
import argparse import argparse
@@ -117,25 +118,31 @@ def validate_fw_schema(data):
return True return True
def natural_sort_key(s):
"""Split a string into text/number chunks so digit runs compare numerically."""
return [int(chunk) if chunk.isdigit() else chunk.lower()
for chunk in re.split(r'(\d+)', s)]
def validate_fw_alphabetical_order(data): def validate_fw_alphabetical_order(data):
"""Validate that fw.json targets are in case-insensitive alphabetical order.""" """Validate that fw.json targets are in case-insensitive natural alphabetical order."""
print('🔍 Validating fw.json targets alphabetical order (case-insensitive)...') print('🔍 Validating fw.json targets alphabetical order (case-insensitive, natural)...')
# Extract target names (first element of each target pair) # Extract target names (first element of each target pair)
target_names = [target[0] for target in data['targets']] target_names = [target[0] for target in data['targets']]
# Sort case-insensitively # Sort case-insensitively, treating embedded digit runs as numbers
sorted_names = sorted(target_names, key=str.lower) sorted_names = sorted(target_names, key=natural_sort_key)
# Check if they're in order # Check if they're in order
if target_names != sorted_names: if target_names != sorted_names:
print('❌ ERROR: Targets are not in alphabetical order (case-insensitive)!') print('❌ ERROR: Targets are not in alphabetical order (case-insensitive, natural)!')
print() print()
print('Current order:') print('Current order:')
for i, name in enumerate(target_names): for i, name in enumerate(target_names):
print(f' {i+1:2d}. {name}') print(f' {i+1:2d}. {name}')
print() print()
print('Expected alphabetical order (case-insensitive):') print('Expected alphabetical order (case-insensitive, natural):')
for i, name in enumerate(sorted_names): for i, name in enumerate(sorted_names):
print(f' {i+1:2d}. {name}') print(f' {i+1:2d}. {name}')
print() print()
@@ -155,7 +162,7 @@ def validate_fw_alphabetical_order(data):
return False return False
else: else:
print('✅ All targets are in alphabetical order (case-insensitive)!') print('✅ All targets are in alphabetical order (case-insensitive, natural)!')
print(f'Found {len(target_names)} targets, all properly sorted.') print(f'Found {len(target_names)} targets, all properly sorted.')
return True return True