From 0d3132d26681a85c8cc3bc8ff29d3f8737090b96 Mon Sep 17 00:00:00 2001 From: xin700 Date: Mon, 29 Jun 2026 17:42:37 +0800 Subject: [PATCH] Fix ros2 interface show for msg files in subfolders (humble) Use rosidl_interfaces resource index instead of get_interface_path() so interface files under nested directories (e.g. msg-common/Foo.msg) resolve correctly. Backport of the approach from ros2cli#1205. Fixes ros2/ros2cli#1186 --- ros2interface/ros2interface/verb/show.py | 25 +++++++++++++++++++++--- ros2interface/test/test_cli.py | 2 +- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/ros2interface/ros2interface/verb/show.py b/ros2interface/ros2interface/verb/show.py index d97c713cd..8e4c62a87 100644 --- a/ros2interface/ros2interface/verb/show.py +++ b/ros2interface/ros2interface/verb/show.py @@ -13,9 +13,15 @@ # limitations under the License. import argparse +import os import sys import typing +from ament_index_python.packages import \ + get_package_share_directory, \ + PackageNotFoundError +from ament_index_python.resources import get_resource + from ros2interface.api import type_completer from ros2interface.verb import VerbExtension from rosidl_adapter.parser import \ @@ -25,7 +31,6 @@ MessageSpecification, \ parse_message_string, \ SERVICE_REQUEST_RESPONSE_SEPARATOR -from rosidl_runtime_py import get_interface_path class InterfaceTextLine: @@ -108,9 +113,23 @@ def _get_interface_lines(interface_identifier: str) -> typing.Iterable[Interface raise ValueError( f"Invalid name '{interface_identifier}'. Expected three parts separated by '/'" ) - pkg_name, _, msg_name = parts + pkg_name, msg_type, msg_name = parts + + try: + share_dir = get_package_share_directory(pkg_name) + except PackageNotFoundError: + raise LookupError(f"Unknown package '{pkg_name}'") + + interfaces, _ = get_resource('rosidl_interfaces', pkg_name) + interfaces = interfaces.splitlines() + + interface = [f for f in interfaces if f.endswith(msg_name + '.' + msg_type)] + if len(interface) == 0: + raise LookupError( + f"Interface '{msg_type}/{msg_name}' not found in package '{pkg_name}'" + ) - file_path = get_interface_path(interface_identifier) + file_path = os.path.join(share_dir, interface[0]) with open(file_path) as file_handler: for line in file_handler: yield InterfaceTextLine( diff --git a/ros2interface/test/test_cli.py b/ros2interface/test/test_cli.py index 8f1c91c5b..698afce86 100644 --- a/ros2interface/test/test_cli.py +++ b/ros2interface/test/test_cli.py @@ -479,7 +479,7 @@ def test_show_not_an_interface(self): assert interface_command.exit_code == 1 assert launch_testing.tools.expect_output( expected_lines=[re.compile( - r"Could not find the interface '.+NotAMessageTypeName\.idl'" + r"Interface 'msg/NotAMessageTypeName' not found in package 'test_msgs'" )], text=interface_command.output, strict=True