@@ -885,6 +885,11 @@ def parse_args(argv: List[str]):
885885 help = "Generate gcovr HTML coverage report (tests/report/index.html)" )
886886 parser .add_argument ("--skip_configure" , action = "store_true" , help = "Skip CMake configure step" )
887887 parser .add_argument ("--skip_build" , action = "store_true" , help = "Skip CMake build step" )
888+ parser .add_argument (
889+ "--compare-only" ,
890+ action = "store_true" ,
891+ help = "Do not clean/build/run tests; only compare existing *_err images against references" ,
892+ )
888893 parser .add_argument ("--lvgl-tests" , action = "store_true" , dest = "lvgl_tests" ,
889894 help = "Run lvgl unit tests (python tests/main.py) and use lvgl ref image dirs" )
890895 return parser .parse_args (argv )
@@ -998,6 +1003,8 @@ def detect_gcov_executable(build_dir: Path) -> Optional[str]:
9981003
9991004def main (argv : List [str ]) -> int :
10001005 args = parse_args (argv )
1006+ rc = 0
1007+ build_dir = None
10011008
10021009 # Choose which reference directories to operate on
10031010 global CURRENT_REF_DIRS
@@ -1006,96 +1013,99 @@ def main(argv: List[str]) -> int:
10061013 else :
10071014 CURRENT_REF_DIRS = [REF_IMGS_DIR ]
10081015
1009- log ("Step 1/5: Cleaning existing *_err images…" )
1010- removed = clean_err_images_in_dirs (CURRENT_REF_DIRS )
1011- if removed :
1012- log (f" Removed { len (removed )} file(s) from { ', ' .join (str (p ) for p in CURRENT_REF_DIRS )} " )
1016+ if getattr (args , "compare_only" , False ):
1017+ log ("Compare-only mode: skipping clean/build/test steps and reviewing existing *_err images." )
10131018 else :
1014- log (" Nothing to remove." )
1015-
1016- log ("Step 2/5: Ensure build is configured…" )
1017- # For lvgl tests we run the lvgl test runner directly and skip CMake configure/build
1018- if getattr (args , "lvgl_tests" , False ):
1019- log (" Running lvgl unit tests; skipping CMake configure/build." )
1020- build_dir = None
1021- else :
1022- # Try to configure automatically using a preset
1023- if args .skip_configure :
1024- log (" Skipping configure step as requested." )
1019+ log ("Step 1/5: Cleaning existing *_err images…" )
1020+ removed = clean_err_images_in_dirs (CURRENT_REF_DIRS )
1021+ if removed :
1022+ log (f" Removed { len (removed )} file(s) from { ', ' .join (str (p ) for p in CURRENT_REF_DIRS )} " )
10251023 else :
1026- if not configure_cmake ():
1027- log ("Failed to configure the project. Aborting." )
1028- return 2
1029-
1030- build_dir = find_build_dir ()
1031- if build_dir is None :
1032- log ("Error: Could not locate a CTest build directory after configure." )
1033- return 2
1024+ log (" Nothing to remove." )
10341025
1035- log ("Step 3/5: Building tests…" )
1036- if getattr (args , "lvgl_tests" , False ):
1037- log (" Skipping build step for lvgl tests (running test script)." )
1038- else :
1039- if args .skip_build :
1040- log (" Skipping build step as requested." )
1026+ if not getattr (args , "compare_only" , False ):
1027+ log ("Step 2/5: Ensure build is configured…" )
1028+ # For lvgl tests we run the lvgl test runner directly and skip CMake configure/build
1029+ if getattr (args , "lvgl_tests" , False ):
1030+ log (" Running lvgl unit tests; skipping CMake configure/build." )
10411031 else :
1042- brc = build_tests (build_dir )
1043- if brc != 0 :
1044- log (f"Build failed with return code { brc } ." )
1045- return brc
1032+ # Try to configure automatically using a preset
1033+ if args .skip_configure :
1034+ log (" Skipping configure step as requested." )
1035+ else :
1036+ if not configure_cmake ():
1037+ log ("Failed to configure the project. Aborting." )
1038+ return 2
10461039
1047- # Snapshot existing references before running tests so we can detect newly created ones
1048- before_snapshot = snapshot_existing_refs_in_dirs (CURRENT_REF_DIRS )
1040+ build_dir = find_build_dir ()
1041+ if build_dir is None :
1042+ log ("Error: Could not locate a CTest build directory after configure." )
1043+ return 2
10491044
1050- log ("Step 4/5: Running tests…" )
1051- if getattr (args , "lvgl_tests" , False ):
1052- rc = run_lvgl_tests (test_filter = args .test_filter )
1053- else :
1054- rc = run_tests (build_dir , test_filter = args .test_filter )
1055- if rc != 0 :
1056- log (f"Tests finished with return code { rc } (there may be failures)." )
1057- else :
1058- log ("Tests completed successfully." )
1045+ log ("Step 3/5: Building tests…" )
1046+ if getattr (args , "lvgl_tests" , False ):
1047+ log (" Skipping build step for lvgl tests (running test script)." )
1048+ else :
1049+ if args .skip_build :
1050+ log (" Skipping build step as requested." )
1051+ else :
1052+ brc = build_tests (build_dir )
1053+ if brc != 0 :
1054+ log (f"Build failed with return code { brc } ." )
1055+ return brc
10591056
1060- # First, check for any newly created reference images (created because a reference didn't exist)
1061- created_refs = list_new_refs_in_dirs (CURRENT_REF_DIRS , before_snapshot )
1062- if created_refs :
1063- log ("Review newly created reference images…" )
1064- # Try Pillow/Tk UI first (lazy-loading inside the UI)
1065- pil_ok = True
1066- try :
1067- reviewer_nr = UINewRefReviewer (created_refs )
1068- reviewer_nr .run ()
1069- except Exception as e :
1070- log (f"Failed to open Tk UI for new references: { e } " )
1071- pil_ok = False
1057+ # Snapshot existing references before running tests so we can detect newly created ones
1058+ before_snapshot = snapshot_existing_refs_in_dirs (CURRENT_REF_DIRS )
10721059
1073- if not pil_ok :
1074- # Fallback to CLI flow
1075- apply_all = False
1076- for p in created_refs :
1077- log ("" )
1078- log (f"New reference image created: { p .name } " )
1079- if apply_all :
1080- choice = "y"
1081- else :
1082- choice = ask_yes_no ("Keep this new reference image?" , default = "n" )
1083- if choice == "a" :
1084- apply_all = True
1060+ log ("Step 4/5: Running tests…" )
1061+ if getattr (args , "lvgl_tests" , False ):
1062+ rc = run_lvgl_tests (test_filter = args .test_filter )
1063+ else :
1064+ rc = run_tests (build_dir , test_filter = args .test_filter )
1065+ if rc != 0 :
1066+ log (f"Tests finished with return code { rc } (there may be failures)." )
1067+ else :
1068+ log ("Tests completed successfully." )
1069+
1070+ # First, check for any newly created reference images (created because a reference didn't exist)
1071+ created_refs = list_new_refs_in_dirs (CURRENT_REF_DIRS , before_snapshot )
1072+ if created_refs :
1073+ log ("Review newly created reference images…" )
1074+ # Try Pillow/Tk UI first (lazy-loading inside the UI)
1075+ pil_ok = True
1076+ try :
1077+ reviewer_nr = UINewRefReviewer (created_refs )
1078+ reviewer_nr .run ()
1079+ except Exception as e :
1080+ log (f"Failed to open Tk UI for new references: { e } " )
1081+ pil_ok = False
1082+
1083+ if not pil_ok :
1084+ # Fallback to CLI flow
1085+ apply_all = False
1086+ for p in created_refs :
1087+ log ("" )
1088+ log (f"New reference image created: { p .name } " )
1089+ if apply_all :
10851090 choice = "y"
1086- if choice == "q" :
1087- log ("Aborting by user request." )
1088- return 130
1089- if choice == "y" :
1090- log (" Kept." )
1091- else :
1092- try :
1093- p .unlink ()
1094- log (" Deleted." )
1095- except Exception as e :
1096- log (f" Failed to delete: { e } " )
1097- else :
1098- log ("No newly created reference images were detected." )
1091+ else :
1092+ choice = ask_yes_no ("Keep this new reference image?" , default = "n" )
1093+ if choice == "a" :
1094+ apply_all = True
1095+ choice = "y"
1096+ if choice == "q" :
1097+ log ("Aborting by user request." )
1098+ return 130
1099+ if choice == "y" :
1100+ log (" Kept." )
1101+ else :
1102+ try :
1103+ p .unlink ()
1104+ log (" Deleted." )
1105+ except Exception as e :
1106+ log (f" Failed to delete: { e } " )
1107+ else :
1108+ log ("No newly created reference images were detected." )
10991109
11001110 log ("Step 5/5: Scanning for *_err images…" )
11011111 err_images = list_err_images_in_dirs (CURRENT_REF_DIRS )
0 commit comments