Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ros2cli_test_interfaces/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ find_package(rosidl_default_generators REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
"action/ShortVariedMultiNested.action"
"msg/IdlOnly.idl"
"msg/ShortVaried.msg"
"msg/ShortVariedIdlNested.msg"
"msg/ShortVariedMultiNested.msg"
"msg/ShortVariedNested.msg"
"srv/ShortVariedMultiNested.srv"
Expand Down
7 changes: 7 additions & 0 deletions ros2cli_test_interfaces/msg/IdlOnly.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module ros2cli_test_interfaces {
module msg {
struct IdlOnly {
uint32 value;
};
};
};
1 change: 1 addition & 0 deletions ros2cli_test_interfaces/msg/ShortVariedIdlNested.msg
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
IdlOnly idl_only
19 changes: 16 additions & 3 deletions ros2interface/ros2interface/verb/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,17 @@ def _is_nested(self) -> bool:
return False


def _get_interface_lines(interface_identifier: str) -> typing.Iterable[InterfaceTextLine]:
def _get_interface_lines(
interface_identifier: str,
file_path: str,
) -> typing.Iterable[InterfaceTextLine]:
parts: typing.List[str] = interface_identifier.split('/')
if len(parts) != 3:
raise ValueError(
f"Invalid name '{interface_identifier}'. Expected three parts separated by '/'"
)
pkg_name, _, msg_name = parts

file_path = get_interface_path(interface_identifier)
with open(file_path) as file_handler:
for line in file_handler:
yield InterfaceTextLine(
Expand Down Expand Up @@ -147,7 +149,18 @@ def _show_interface(
is_show_nested_comments: bool = False,
indent_level: int = 0
):
for line in _get_interface_lines(interface_identifier):
file_path = get_interface_path(interface_identifier)
if file_path.endswith('.idl'):
with open(file_path) as file_handler:
content = file_handler.read()
indent_string = indent_level * '\t'
for line in content.splitlines():
print(f'{indent_string}{line}' if line else '')
if not content or not content.endswith('\n'):
print()
return

for line in _get_interface_lines(interface_identifier, file_path):
Comment on lines +152 to +163

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this just displays whatever format the original is in. but it's a UX regression relative to what users get for .msg, where the whole point of interface show is that you see the full recursive structure without opening more files. i think recursive approach or consideration is completely off from this PR.

and what if the case with " .msg parent with an .idl-only nested type"?
the new IDL branch ignores indent_level (and the comment flags) entirely, raw module/struct boilerplate lands un-indented, i think this prints ugly...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I agree that an unindented raw IDL block in a nested expansion is poor UX. In 1aea823, the raw-IDL branch now applies the existing indent_level recursively to every line. The new CLI integration test covers a .msg parent with an IDL-only nested type.

I kept the IDL body in its original format intentionally: the maintainer guidance in #780 is that ros2 interface show should display the original format because some IDL cannot be converted to .msg / .srv (#780 (comment)).

That decision means the raw IDL branch currently preserves IDL comments for both comment options. Applying --no-comments / --all-comments to raw IDL would require defining an IDL-specific transformation rather than displaying its source. Could you please confirm whether you want that new formatting behavior, or whether preserving raw IDL with correct recursive indentation is the intended scope for this PR?


_print_interface_line(
line, is_show_comments=is_show_comments, indent_level=indent_level)
Expand Down
41 changes: 41 additions & 0 deletions ros2interface/test/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,47 @@ def test_show_message(self):
strict=True
)

def test_show_idl_message(self):
with self.launch_interface_command(
arguments=['show', 'ros2cli_test_interfaces/msg/IdlOnly']
) as interface_command:
assert interface_command.wait_for_shutdown(timeout=2)
assert interface_command.exit_code == launch_testing.asserts.EXIT_OK
assert launch_testing.tools.expect_output(
expected_lines=[
'module ros2cli_test_interfaces {',
' module msg {',
' struct IdlOnly {',
' uint32 value;',
' };',
' };',
'};',
],
text=interface_command.output,
strict=True
)

def test_show_message_with_idl_nested_type(self):
with self.launch_interface_command(
arguments=['show', 'ros2cli_test_interfaces/msg/ShortVariedIdlNested']
) as interface_command:
assert interface_command.wait_for_shutdown(timeout=2)
assert interface_command.exit_code == launch_testing.asserts.EXIT_OK
assert launch_testing.tools.expect_output(
expected_lines=[
'IdlOnly idl_only',
'\tmodule ros2cli_test_interfaces {',
'\t module msg {',
'\t struct IdlOnly {',
'\t uint32 value;',
'\t };',
'\t };',
'\t};',
],
text=interface_command.output,
strict=True
)

def test_show_message_with_all_comments(self):
with self.launch_interface_command(
arguments=[
Expand Down