From eaeb2a537e80445625aba8ae1f2fb1f99060f7a5 Mon Sep 17 00:00:00 2001 From: Brandon Shrewsbury Date: Thu, 2 Jul 2026 15:15:33 -0600 Subject: [PATCH] Coverage: guard missing proto overrides + remove navigation (#5126) Two of the crashes that were stacked behind the gripper KeyError (#5139), both surfaced once that one was fixed: (a) Missing proto-description override files crashed the generator. Proto descriptions come from override files (static/include/.../overrides/protos/ {resource}.{proto}.md), but the description-reading open() was not guarded by the os.path.isfile check the content-writing branch already uses. Guard it and fall back to a blank description so a missing override reports gracefully instead of crashing (same spirit as #5139). (b) Fully remove navigation. #5067 removed the navigation docs section (redirected to motion-planning) and deleted its override files, but left navigation in the CSV and in the generator's services list, so coverage still tried to document it and crashed on the deleted navigation.GetMode.md override. Remove navigation from sdk_protos_map.csv, the `services` list, the proto-URL map, and the service anchor logic. (Removing only the CSV rows would leave navigation still scraped and flag its methods as "unused"; dropping it from the services list stops that.) Verified by running the generator locally: it now completes with no crash (previously KeyError then FileNotFoundError), and navigation no longer appears. Note: this does not make check-methods green -- with the crashes gone, the check now reports ~110 pre-existing "unused" warnings it had been masking (SDK methods not mapped in the CSV). Each is a separate document-vs-ignore decision. Refs #5126 --- .github/workflows/sdk_protos_map.csv | 15 --------- .github/workflows/update_sdk_methods.py | 45 +++++++++++++------------ 2 files changed, 24 insertions(+), 36 deletions(-) diff --git a/.github/workflows/sdk_protos_map.csv b/.github/workflows/sdk_protos_map.csv index 78dacdd25a..b15c8dbe61 100644 --- a/.github/workflows/sdk_protos_map.csv +++ b/.github/workflows/sdk_protos_map.csv @@ -296,21 +296,6 @@ motion,DoCommand,,do_command,DoCommand,,doCommand motion,GetResourceName,,get_resource_name,Name,,name motion,Close,,close,Close,, -## Navigation -navigation,GetMode,,get_mode,Mode,,getMode -navigation,SetMode,,set_mode,SetMode,,setMode -navigation,GetLocation,,get_location,Location,,getLocation -navigation,GetWaypoints,,get_waypoints,Waypoints,,getWayPoints -navigation,AddWaypoint,,add_waypoint,AddWaypoint,,addWayPoint -navigation,RemoveWaypoint,,remove_waypoint,RemoveWaypoint,,removeWayPoint -navigation,GetObstacles,,get_obstacles,Obstacles,,getObstacles -navigation,GetPaths,,get_paths,Paths,,getPaths -navigation,GetProperties,,get_properties,Properties,,getProperties -## HACK: proto for these (and/or inherited in Go SDK), manually mapping: -navigation,Reconfigure,,,Reconfigure,, -navigation,DoCommand,,do_command,DoCommand,,doCommand -navigation,GetResourceName,,get_resource_name,Name,,name -navigation,Close,,close,Close,, ## SLAM slam,GetPosition,,get_position,Position,,getPosition diff --git a/.github/workflows/update_sdk_methods.py b/.github/workflows/update_sdk_methods.py index 4a7cb26e41..47778dfcf6 100755 --- a/.github/workflows/update_sdk_methods.py +++ b/.github/workflows/update_sdk_methods.py @@ -23,7 +23,7 @@ ## at runtime if desired: components = ["arm", "base", "board", "button", "camera", "encoder", "gantry", "generic_component", "gripper", "input_controller", "motor", "movement_sensor", "power_sensor", "sensor", "servo", "switch", "audio_in", "audio_out"] -services = ["base_remote_control", "data_manager", "discovery", "generic_service", "mlmodel", "motion", "navigation", "slam", "vision", "world_state_store"] +services = ["base_remote_control", "data_manager", "discovery", "generic_service", "mlmodel", "motion", "slam", "vision", "world_state_store"] app_apis = ["app", "billing", "data", "dataset", "data_sync", "mltraining"] robot_apis = ["robot"] @@ -279,11 +279,6 @@ "name": "MotionServiceClient", "methods": [] }, - "navigation": { - "url": "https://raw.githubusercontent.com/viamrobotics/api/main/service/navigation/v1/navigation_grpc.pb.go", - "name": "NavigationServiceClient", - "methods": [] - }, "slam": { "url": "https://raw.githubusercontent.com/viamrobotics/api/main/service/slam/v1/slam_grpc.pb.go", "name": "SLAMServiceClient", @@ -936,7 +931,7 @@ def write_markdown(type, names, methods): ## Replace underscores, and convert generic_component to just generic: resource_adjusted = resource.replace('generic_component', 'generic').replace('_','-') proto_anchor_link = '/dev/reference/apis/components/' + resource_adjusted + '/#' + proto_link - elif type == 'service' and resource in ['base_remote_control', 'motion', 'navigation', 'slam', 'vision']: + elif type == 'service' and resource in ['base_remote_control', 'motion', 'slam', 'vision']: proto_anchor_link = '/dev/reference/apis/services/' + resource.replace('base_remote_control', 'base-rc') + '/#' + proto_link elif type == 'service' and resource == 'data_manager': proto_anchor_link = '/dev/reference/apis/services/data/#' + proto_link @@ -966,20 +961,28 @@ def write_markdown(type, names, methods): ## first sentence: - with open(proto_override_file, 'r') as f: - file_contents = f.read().strip() - file_contents = regex.sub(r'\{\{\%.*\%\}\}.*\{\{\% \/[a-b].* \%\}\}', '', file_contents, flags=regex.DOTALL) - search_result = file_contents.split('.\n', 1)[0].strip().replace("\n", " ") - - ## If the proto description contains any MD links, strip them out: - search_result = regex.sub(r'\[([A-Za-z0-9\.\(\)\-\_\`\s]*)\]\([A-Za-z0-9\.\:\/\-\_\#]*\)', r'\1', search_result) - - ## If the proto description is missing a trailing period, or we stripped it off during the above matching, append - ## (restore) the period character: - if not search_result.endswith('.'): - proto_description_first_sentence = search_result + '.' - else: - proto_description_first_sentence = search_result + if os.path.isfile(proto_override_file): + with open(proto_override_file, 'r') as f: + file_contents = f.read().strip() + file_contents = regex.sub(r'\{\{\%.*\%\}\}.*\{\{\% \/[a-b].* \%\}\}', '', file_contents, flags=regex.DOTALL) + search_result = file_contents.split('.\n', 1)[0].strip().replace("\n", " ") + + ## If the proto description contains any MD links, strip them out: + search_result = regex.sub(r'\[([A-Za-z0-9\.\(\)\-\_\`\s]*)\]\([A-Za-z0-9\.\:\/\-\_\#]*\)', r'\1', search_result) + + ## If the proto description is missing a trailing period, or we stripped it off during the above matching, append + ## (restore) the period character: + if not search_result.endswith('.'): + proto_description_first_sentence = search_result + '.' + else: + proto_description_first_sentence = search_result + else: + ## No proto description override file (for example a proto whose + ## docs section was removed); leave the description blank instead + ## of crashing on the missing file, but warn so a genuinely + ## missing override (an authoring gap) is still surfaced. + print(f"WARNING: {type} {resource} {proto} has no proto description override file ({proto_override_file}); leaving description blank") + proto_description_first_sentence = '' ## Write out this proto's entry to this resource's table_file: if resource != 'movement_sensor':