diff --git a/ros2action/ros2action/verb/find.py b/ros2action/ros2action/verb/find.py new file mode 100644 index 000000000..36a18c227 --- /dev/null +++ b/ros2action/ros2action/verb/find.py @@ -0,0 +1,46 @@ +# Copyright 2024 Sony Group Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ros2action.api import action_type_completer +from ros2action.api import get_action_names_and_types +from ros2action.verb import VerbExtension +from ros2cli.node.strategy import NodeStrategy + + +class FindVerb(VerbExtension): + """Find actions from type.""" + + def add_arguments(self, parser, cli_name): + arg = parser.add_argument( + 'action_type', + help="Name of the ROS action type to find (e.g. 'test_msgs/action/Fibonacci')") + arg.completer = action_type_completer + parser.add_argument( + '-c', '--count-actions', action='store_true', + help='Only display the number of actions discovered') + + def main(self, *, args): + with NodeStrategy(args) as node: + action_names_and_types = get_action_names_and_types(node=node) + + filtered_actions = [] + for (action_name, action_types) in action_names_and_types: + if args.action_type in action_types: + filtered_actions.append(action_name) + + if args.count_actions: + print(len(filtered_actions)) + else: + for filtered_action in filtered_actions: + print(filtered_action) diff --git a/ros2action/setup.py b/ros2action/setup.py index b0a8ee7bd..e127d6b01 100644 --- a/ros2action/setup.py +++ b/ros2action/setup.py @@ -44,6 +44,7 @@ 'list = ros2action.verb.list:ListVerb', 'send_goal = ros2action.verb.send_goal:SendGoalVerb', 'type = ros2action.verb.type:TypeVerb', + 'find = ros2action.verb.find:FindVerb', ], } ) diff --git a/ros2action/test/test_cli.py b/ros2action/test/test_cli.py index bd3b86f66..affda6d4d 100644 --- a/ros2action/test/test_cli.py +++ b/ros2action/test/test_cli.py @@ -231,6 +231,27 @@ def test_type(self): text=action_command.output, strict=True ) + @launch_testing.markers.retry_on_failure(times=5, delay=1) + def test_find(self): + with self.launch_action_command( + arguments=['find', 'test_msgs/action/Fibonacci']) as action_command: + assert action_command.wait_for_shutdown(timeout=10) + assert action_command.exit_code == launch_testing.asserts.EXIT_OK + assert launch_testing.tools.expect_output( + expected_lines=['/fibonacci'], + text=action_command.output, strict=True + ) + + @launch_testing.markers.retry_on_failure(times=5, delay=1) + def test_find_count(self): + with self.launch_action_command( + arguments=['find', '-c', 'test_msgs/action/Fibonacci']) as action_command: + assert action_command.wait_for_shutdown(timeout=10) + assert action_command.exit_code == launch_testing.asserts.EXIT_OK + command_output_lines = action_command.output.splitlines() + assert len(command_output_lines) == 1 + assert int(command_output_lines[0]) == 1 + @launch_testing.markers.retry_on_failure(times=5, delay=1) def test_send_fibonacci_goal(self): with self.launch_action_command(