From 903b0adc42c906dd12e234bf011cc53c7e137326 Mon Sep 17 00:00:00 2001 From: Kevin Weiss Date: Wed, 26 Aug 2026 13:05:30 +0200 Subject: [PATCH] fix: parse -dirty/-unknown suffix in firmware identifiers FirmwareID regex rejected version strings where the git describe suffix is followed by -dirty or -unknown, e.g. a locally built '0.14.0-rc.1-89-g04cac05-dirty'. Allow the suffixes after the describe part so FirmwareVersion can flag them. Add regression tests including the real id string from the app-nrf91-origin 0.14.0-rc.1-89-g04cac05 hex. Ignore Lobaro variant name 'lonly' in codespell. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .codespellrc | 2 +- src/lob_hlpr/lib_types.py | 4 +-- tests/test_firmware_id.py | 61 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/.codespellrc b/.codespellrc index b68e41b..65c08c8 100644 --- a/.codespellrc +++ b/.codespellrc @@ -1,2 +1,2 @@ [codespell] -ignore-words-list = ser +ignore-words-list = ser,lonly diff --git a/src/lob_hlpr/lib_types.py b/src/lob_hlpr/lib_types.py index ac7a211..44a2680 100644 --- a/src/lob_hlpr/lib_types.py +++ b/src/lob_hlpr/lib_types.py @@ -97,7 +97,7 @@ class FirmwareID: # Name group, non-greedy match up to the first space r"^(?P.+?)\s+" # Version group, matches a semantic versioning pattern - r"v(?P[0-9]+(?:\.[0-9]+){2}(?:-[\w]+(?:\.[\w]+)*)?(?:-\d+-g[0-9a-f]+)?)" + r"v(?P[0-9]+(?:\.[0-9]+){2}(?:-[\w]+(?:\.[\w]+)*)?(?:-\d+-g[0-9a-f]+)?(?:-dirty|-unknown)*)" # Optional variant group, matches anything after a '+' until a space or end r"(?:\+(?P[^\s]+))?" # Optional additional group, @@ -110,7 +110,7 @@ class FirmwareID: # Name group, non-greedy match up to the first + r"^(?P.+?)\+" # Version group, matches a semantic versioning pattern - r"(?P[0-9]+(?:\.[0-9]+){2}(?:-[\w]+(?:\.[\w]+)*)?(?:-\d+-g[0-9a-f]+)?)" + r"(?P[0-9]+(?:\.[0-9]+){2}(?:-[\w]+(?:\.[\w]+)*)?(?:-\d+-g[0-9a-f]+)?(?:-dirty|-unknown)*)" # Optional variant group, matches anything after a '+' until a space or end r"(?:\+(?P[^\s]+))?" # Optional additional group, diff --git a/tests/test_firmware_id.py b/tests/test_firmware_id.py index 6557079..e99b895 100644 --- a/tests/test_firmware_id.py +++ b/tests/test_firmware_id.py @@ -106,6 +106,67 @@ def test_valid_firmware_id_with_rc_version(): assert firmware_id.built == "2026-05-28T12:17:29" +def test_valid_firmware_id_origin_with_rc_commits_and_multi_variant(): + """Regression test for a real firmware id read from a built hex file.""" + id_str = ( + "app-nrf91-origin+0.14.0-rc.1-89-g04cac05+hw4.lonly TZ3 (Aug 24 2026 16:06:29)" + ) + firmware_id = FirmwareID(id_str) + assert firmware_id.name == "app-nrf91-origin" + assert firmware_id.version.version_string == "0.14.0-rc.1-89-g04cac05" + assert firmware_id.version.pre_release == "rc.1" + assert firmware_id.version.commits == 89 + assert firmware_id.version.commit == "04cac05" + assert firmware_id.version.dirty is False + assert firmware_id.variants == ["hw4", "lonly"] + assert firmware_id.built == "2026-08-24T16:06:29" + + +def test_valid_firmware_id_origin_with_dirty(): + """Tests origin-style firmware ID with a dirty suffix after the commit hash.""" + id_str = ( + "app-nrf91-origin+0.14.0-rc.1-89-g04cac05-dirty+hw4.lonly TZ3 " + "(Aug 24 2026 16:06:29)" + ) + firmware_id = FirmwareID(id_str) + assert firmware_id.name == "app-nrf91-origin" + assert firmware_id.version.version_string == "0.14.0-rc.1-89-g04cac05-dirty" + assert firmware_id.version.pre_release == "rc.1" + assert firmware_id.version.commits == 89 + assert firmware_id.version.commit == "04cac05" + assert firmware_id.version.dirty is True + assert firmware_id.version.unknown is False + assert firmware_id.variants == ["hw4", "lonly"] + assert firmware_id.built == "2026-08-24T16:06:29" + + +def test_valid_firmware_id_origin_with_dirty_unknown(): + """Tests origin-style firmware ID with both dirty and unknown suffixes.""" + id_str = ( + "app-nrf91-origin+0.14.0-89-g04cac05-dirty-unknown+hw4 TZ3 " + "(Aug 24 2026 16:06:29)" + ) + firmware_id = FirmwareID(id_str) + assert firmware_id.name == "app-nrf91-origin" + assert firmware_id.version.version_string == "0.14.0-89-g04cac05-dirty-unknown" + assert firmware_id.version.dirty is True + assert firmware_id.version.unknown is True + assert firmware_id.variants == ["hw4"] + + +def test_valid_firmware_id_with_dirty(): + """Tests standard-style firmware ID with a dirty suffix after the commit hash.""" + id_str = "app-nrf9160-wmbus v0.24.1-9-g8ad003f-dirty+hw3 TZ2 (Mar 11 2024 13:57:40)" + firmware_id = FirmwareID(id_str) + assert firmware_id.name == "app-nrf9160-wmbus" + assert firmware_id.version.version_string == "0.24.1-9-g8ad003f-dirty" + assert firmware_id.version.commits == 9 + assert firmware_id.version.commit == "8ad003f" + assert firmware_id.version.dirty is True + assert firmware_id.variants == ["hw3"] + assert firmware_id.built == "2024-03-11T13:57:40" + + def test_valid_firmware_id_with_rc_version_and_variant(): """Tests standard-style firmware ID with an rc pre-release version.""" id_str = "app-nrf9160-wmbus v0.5.0-rc.1+hw3.alt_phy TZ2 (Jun 01 2026 08:00:00)"