From 9d028feedb348962e5f57b616f3cd16101d3d53c Mon Sep 17 00:00:00 2001 From: Gonzalo de Pedro Date: Fri, 22 Mar 2024 16:14:45 -0300 Subject: [PATCH 1/7] Added test cases for rosidl cli into protobuf typesupports Signed-off-by: Gonzalo de Pedro --- rosidl_typesupport_protobuf_c/CMakeLists.txt | 2 + .../rosidl_typesupport_protobuf_c/cli.py | 72 ++++++++++++++++++ rosidl_typesupport_protobuf_c/setup.cfg | 3 + .../test/test_rosidl_cli_ts_pb_c.py | 28 +++++++ .../CMakeLists.txt | 2 + .../rosidl_typesupport_protobuf_cpp/cli.py | 73 +++++++++++++++++++ rosidl_typesupport_protobuf_cpp/setup.cfg | 3 + .../test/test_rosidl_cli_ts_pb_cpp.py | 29 ++++++++ 8 files changed, 212 insertions(+) create mode 100644 rosidl_typesupport_protobuf_c/rosidl_typesupport_protobuf_c/cli.py create mode 100644 rosidl_typesupport_protobuf_c/setup.cfg create mode 100644 rosidl_typesupport_protobuf_c/test/test_rosidl_cli_ts_pb_c.py create mode 100644 rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/cli.py create mode 100644 rosidl_typesupport_protobuf_cpp/setup.cfg create mode 100644 rosidl_typesupport_protobuf_cpp/test/test_rosidl_cli_ts_pb_cpp.py diff --git a/rosidl_typesupport_protobuf_c/CMakeLists.txt b/rosidl_typesupport_protobuf_c/CMakeLists.txt index dd473d2..97047bf 100644 --- a/rosidl_typesupport_protobuf_c/CMakeLists.txt +++ b/rosidl_typesupport_protobuf_c/CMakeLists.txt @@ -115,6 +115,8 @@ if(BUILD_TESTING) target_link_libraries(test_wstring_conversion ${PROJECT_NAME}) endif() + find_package(ament_cmake_pytest REQUIRED) + ament_add_pytest_test(test_rosidl_cli_ts_pb_c test/test_rosidl_cli_ts_pb_c.py) endif() ament_package( diff --git a/rosidl_typesupport_protobuf_c/rosidl_typesupport_protobuf_c/cli.py b/rosidl_typesupport_protobuf_c/rosidl_typesupport_protobuf_c/cli.py new file mode 100644 index 0000000..877cfd6 --- /dev/null +++ b/rosidl_typesupport_protobuf_c/rosidl_typesupport_protobuf_c/cli.py @@ -0,0 +1,72 @@ +import pathlib + +from ament_index_python import get_package_share_directory + +from rosidl_cli.command.generate.extensions import GenerateCommandExtension +from rosidl_cli.command.helpers import generate_visibility_control_file +from rosidl_cli.command.helpers import legacy_generator_arguments_file +from rosidl_cli.command.translate.api import translate + +from rosidl_typesupport_protobuf_c import generate_typesupport_protobuf_c + + +class GenerateProtobufCTypesupport(GenerateCommandExtension): + + def generate( + self, + package_name, + interface_files, + include_paths, + output_path + ): + generated_files = [] + + package_share_path = pathlib.Path( + get_package_share_directory('rosidl_typesupport_protobuf_c')) + templates_path = package_share_path / 'resource' + + # Normalize interface definition format to .idl + idl_interface_files = [] + non_idl_interface_files = [] + for path in interface_files: + if not path.endswith('.idl'): + non_idl_interface_files.append(path) + else: + idl_interface_files.append(path) + if non_idl_interface_files: + idl_interface_files.extend(translate( + package_name=package_name, + interface_files=non_idl_interface_files, + include_paths=include_paths, + output_format='idl', + output_path=output_path / 'tmp', + )) + + # Generate visibility control file + visibility_control_file_template_path = \ + 'rosidl_typesupport_protobuf_c__visibility_control.h.in' + visibility_control_file_template_path = \ + templates_path / visibility_control_file_template_path + visibility_control_file_path = \ + 'rosidl_typesupport_protobuf_c__visibility_control.h' + visibility_control_file_path = \ + output_path / 'msg' / visibility_control_file_path + + generate_visibility_control_file( + package_name=package_name, + template_path=visibility_control_file_template_path, + output_path=visibility_control_file_path + ) + generated_files.append(visibility_control_file_path) + + # Generate code + with legacy_generator_arguments_file( + package_name=package_name, + interface_files=idl_interface_files, + include_paths=include_paths, + templates_path=templates_path, + output_path=output_path + ) as path_to_arguments_file: + generated_files.extend(generate_typesupport_protobuf_c(path_to_arguments_file)) + + return generated_files diff --git a/rosidl_typesupport_protobuf_c/setup.cfg b/rosidl_typesupport_protobuf_c/setup.cfg new file mode 100644 index 0000000..80b42be --- /dev/null +++ b/rosidl_typesupport_protobuf_c/setup.cfg @@ -0,0 +1,3 @@ +[options.entry_points] +rosidl_cli.command.generate.typesupport_extensions = + protobuf_c = rosidl_typesupport_protobuf_c.cli:GenerateProtobufCTypesupport diff --git a/rosidl_typesupport_protobuf_c/test/test_rosidl_cli_ts_pb_c.py b/rosidl_typesupport_protobuf_c/test/test_rosidl_cli_ts_pb_c.py new file mode 100644 index 0000000..43dea3b --- /dev/null +++ b/rosidl_typesupport_protobuf_c/test/test_rosidl_cli_ts_pb_c.py @@ -0,0 +1,28 @@ +import pytest +import os +import pathlib +import shutil +import subprocess + + +def test_ts_files_generation(): + build_then_install('/tmp/pb') + files_exists('/tmp/pb') + +def build_then_install(output_path): + if os.path.exists(output_path): + shutil.rmtree(output_path) + os.makedirs(output_path) + +#rosidl generate -ts protobuf_c -o /tmp/pb std_msgs ./install/std_msgs/share/std_msgs/msg/String.msg + + subprocess.run([ + 'rosidl', 'generate', '-ts', 'protobuf_c', '-o', output_path, 'std_msgs', './msg/String.msg' + ], cwd='/home/aeten/ros2_rolling/install/std_msgs/share/std_msgs', check=True) + +def files_exists(output_path): + assert pathlib.Path('/tmp/pb/tmp/msg/String.idl').exists() + assert pathlib.Path('/tmp/pb/msg/rosidl_typesupport_protobuf_c__visibility_control.h').exists() + assert pathlib.Path('/tmp/pb/msg/string__rosidl_typesupport_protobuf_c.hpp').exists() + assert pathlib.Path('/tmp/pb/msg/detail/string__type_support.cpp').exists() + \ No newline at end of file diff --git a/rosidl_typesupport_protobuf_cpp/CMakeLists.txt b/rosidl_typesupport_protobuf_cpp/CMakeLists.txt index ccac6d0..85072b9 100644 --- a/rosidl_typesupport_protobuf_cpp/CMakeLists.txt +++ b/rosidl_typesupport_protobuf_cpp/CMakeLists.txt @@ -96,6 +96,8 @@ if(BUILD_TESTING) target_link_libraries(test_wstring_conversion ${PROJECT_NAME}) endif() + find_package(ament_cmake_pytest REQUIRED) + ament_add_pytest_test(test_rosidl_cli_ts_pb_cpp test/test_rosidl_cli_ts_pb_cpp.py) endif() ament_package(CONFIG_EXTRAS "cmake/rosidl_typesupport_protobuf_cpp-extras.cmake.in") diff --git a/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/cli.py b/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/cli.py new file mode 100644 index 0000000..fde7a23 --- /dev/null +++ b/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/cli.py @@ -0,0 +1,73 @@ +import pathlib + +from ament_index_python import get_package_share_directory + +from rosidl_cli.command.generate.extensions import GenerateCommandExtension +from rosidl_cli.command.helpers import generate_visibility_control_file +from rosidl_cli.command.helpers import legacy_generator_arguments_file +from rosidl_cli.command.translate.api import translate + +from rosidl_typesupport_protobuf_cpp import generate_cpp + + +class GenerateProtobufCppTypesupport(GenerateCommandExtension): + + def generate( + self, + package_name, + interface_files, + include_paths, + output_path + ): + generated_files = [] + + package_share_path = pathlib.Path( + get_package_share_directory('rosidl_typesupport_protobuf_cpp')) + templates_path = package_share_path / 'resource' + + # Normalize interface definition format to .idl + idl_interface_files = [] + non_idl_interface_files = [] + for path in interface_files: + if not path.endswith('.idl'): + non_idl_interface_files.append(path) + else: + idl_interface_files.append(path) + if non_idl_interface_files: + idl_interface_files.extend(translate( + package_name=package_name, + interface_files=non_idl_interface_files, + include_paths=include_paths, + output_format='idl', + output_path=output_path / 'tmp', + )) + + # Generate visibility control file + visibility_control_file_template_path = \ + 'rosidl_typesupport_protobuf_cpp__visibility_control.h.in' + visibility_control_file_template_path = \ + templates_path / visibility_control_file_template_path + visibility_control_file_path = \ + 'rosidl_typesupport_protobuf_cpp__visibility_control.h' + visibility_control_file_path = \ + output_path / 'msg' / visibility_control_file_path + + generate_visibility_control_file( + package_name=package_name, + template_path=visibility_control_file_template_path, + output_path=visibility_control_file_path + ) + generated_files.append(visibility_control_file_path) + + # Generate code + with legacy_generator_arguments_file( + package_name=package_name, + interface_files=idl_interface_files, + include_paths=include_paths, + templates_path=templates_path, + output_path=output_path + ) as path_to_arguments_file: + print('PATH: ', path_to_arguments_file) + generated_files.extend(generate_cpp(path_to_arguments_file)) + + return generated_files diff --git a/rosidl_typesupport_protobuf_cpp/setup.cfg b/rosidl_typesupport_protobuf_cpp/setup.cfg new file mode 100644 index 0000000..b272e07 --- /dev/null +++ b/rosidl_typesupport_protobuf_cpp/setup.cfg @@ -0,0 +1,3 @@ +[options.entry_points] +rosidl_cli.command.generate.typesupport_extensions = + protobuf_cpp = rosidl_typesupport_protobuf_cpp.cli:GenerateProtobufCppTypesupport diff --git a/rosidl_typesupport_protobuf_cpp/test/test_rosidl_cli_ts_pb_cpp.py b/rosidl_typesupport_protobuf_cpp/test/test_rosidl_cli_ts_pb_cpp.py new file mode 100644 index 0000000..3567bc6 --- /dev/null +++ b/rosidl_typesupport_protobuf_cpp/test/test_rosidl_cli_ts_pb_cpp.py @@ -0,0 +1,29 @@ +import pytest +import os +import pathlib +import shutil +import subprocess + + +def test_ts_files_generation(): + build_then_install('/tmp/pb') + files_exists('/tmp/pb') + +def build_then_install(output_path): + if os.path.exists(output_path): + shutil.rmtree(output_path) + os.makedirs(output_path) + +#rosidl generate -ts protobuf_c -o /tmp/pb std_msgs ./install/std_msgs/share/std_msgs/msg/String.msg + + subprocess.run([ + 'rosidl', 'generate', '-ts', 'protobuf_cpp', '-o', output_path, 'std_msgs', './msg/String.msg' + ], cwd='/home/aeten/ros2_rolling/install/std_msgs/share/std_msgs', check=True) + +def files_exists(output_path): + assert pathlib.Path('/tmp/pb/tmp/msg/String.idl').exists() + assert pathlib.Path('/tmp/pb/msg/rosidl_typesupport_protobuf_cpp__visibility_control.h').exists() + assert pathlib.Path('/tmp/pb/msg/string__rosidl_typesupport_protobuf_cpp.hpp').exists() + assert pathlib.Path('/tmp/pb/msg/string__typeadapter_protobuf_cpp.hpp').exists() + assert pathlib.Path('/tmp/pb/msg/detail/string__type_support.cpp').exists() + \ No newline at end of file From e08db98ea04119d9b2499fb7e095be50e3956899 Mon Sep 17 00:00:00 2001 From: Gonzalo de Pedro Date: Fri, 22 Mar 2024 16:33:36 -0300 Subject: [PATCH 2/7] Removed dead code Signed-off-by: Gonzalo de Pedro --- .../rosidl_typesupport_protobuf_cpp/__init__.py | 3 --- .../rosidl_typesupport_protobuf_cpp/cli.py | 1 - 2 files changed, 4 deletions(-) diff --git a/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/__init__.py b/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/__init__.py index 806324c..4252ef8 100644 --- a/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/__init__.py +++ b/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/__init__.py @@ -15,9 +15,6 @@ # limitations under the License. # # ================================= Apache 2.0 ================================= - -from rosidl_cmake import generate_files - from rosidl_pycommon import generate_files def get_template_mapping(): diff --git a/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/cli.py b/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/cli.py index fde7a23..51239f3 100644 --- a/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/cli.py +++ b/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/cli.py @@ -67,7 +67,6 @@ def generate( templates_path=templates_path, output_path=output_path ) as path_to_arguments_file: - print('PATH: ', path_to_arguments_file) generated_files.extend(generate_cpp(path_to_arguments_file)) return generated_files From 0665f21f5eda4c136a24da2b2f5f1f30c70492e8 Mon Sep 17 00:00:00 2001 From: Gonzalo de Pedro Date: Fri, 22 Mar 2024 22:41:38 -0300 Subject: [PATCH 3/7] Get package share directory using ament_index_python Signed-off-by: Gonzalo de Pedro --- .../test/test_rosidl_cli_ts_pb_c.py | 8 +++++--- .../test/test_rosidl_cli_ts_pb_cpp.py | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/rosidl_typesupport_protobuf_c/test/test_rosidl_cli_ts_pb_c.py b/rosidl_typesupport_protobuf_c/test/test_rosidl_cli_ts_pb_c.py index 43dea3b..ca69223 100644 --- a/rosidl_typesupport_protobuf_c/test/test_rosidl_cli_ts_pb_c.py +++ b/rosidl_typesupport_protobuf_c/test/test_rosidl_cli_ts_pb_c.py @@ -4,6 +4,7 @@ import shutil import subprocess +from ament_index_python import get_package_share_directory def test_ts_files_generation(): build_then_install('/tmp/pb') @@ -14,11 +15,12 @@ def build_then_install(output_path): shutil.rmtree(output_path) os.makedirs(output_path) -#rosidl generate -ts protobuf_c -o /tmp/pb std_msgs ./install/std_msgs/share/std_msgs/msg/String.msg - + package_share_path = pathlib.Path( + get_package_share_directory('std_msgs')) + subprocess.run([ 'rosidl', 'generate', '-ts', 'protobuf_c', '-o', output_path, 'std_msgs', './msg/String.msg' - ], cwd='/home/aeten/ros2_rolling/install/std_msgs/share/std_msgs', check=True) + ], cwd=package_share_path, check=True) def files_exists(output_path): assert pathlib.Path('/tmp/pb/tmp/msg/String.idl').exists() diff --git a/rosidl_typesupport_protobuf_cpp/test/test_rosidl_cli_ts_pb_cpp.py b/rosidl_typesupport_protobuf_cpp/test/test_rosidl_cli_ts_pb_cpp.py index 3567bc6..d4bc740 100644 --- a/rosidl_typesupport_protobuf_cpp/test/test_rosidl_cli_ts_pb_cpp.py +++ b/rosidl_typesupport_protobuf_cpp/test/test_rosidl_cli_ts_pb_cpp.py @@ -4,6 +4,7 @@ import shutil import subprocess +from ament_index_python import get_package_share_directory def test_ts_files_generation(): build_then_install('/tmp/pb') @@ -14,11 +15,12 @@ def build_then_install(output_path): shutil.rmtree(output_path) os.makedirs(output_path) -#rosidl generate -ts protobuf_c -o /tmp/pb std_msgs ./install/std_msgs/share/std_msgs/msg/String.msg - + package_share_path = pathlib.Path( + get_package_share_directory('std_msgs')) + subprocess.run([ 'rosidl', 'generate', '-ts', 'protobuf_cpp', '-o', output_path, 'std_msgs', './msg/String.msg' - ], cwd='/home/aeten/ros2_rolling/install/std_msgs/share/std_msgs', check=True) + ], cwd=package_share_path, check=True) def files_exists(output_path): assert pathlib.Path('/tmp/pb/tmp/msg/String.idl').exists() From c366f33ca98b9c50490513aaeb5ea927ff0af155 Mon Sep 17 00:00:00 2001 From: Gonzalo de Pedro Date: Mon, 25 Mar 2024 14:01:11 -0300 Subject: [PATCH 4/7] Added ament_python_test to package.xml Signed-off-by: Gonzalo de Pedro --- rosidl_typesupport_protobuf_c/package.xml | 1 + rosidl_typesupport_protobuf_cpp/package.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/rosidl_typesupport_protobuf_c/package.xml b/rosidl_typesupport_protobuf_c/package.xml index f61936a..a98fa3a 100644 --- a/rosidl_typesupport_protobuf_c/package.xml +++ b/rosidl_typesupport_protobuf_c/package.xml @@ -30,6 +30,7 @@ rosidl_typesupport_interface ament_cmake_gtest + ament_cmake_pytest rosidl_typesupport_c_packages diff --git a/rosidl_typesupport_protobuf_cpp/package.xml b/rosidl_typesupport_protobuf_cpp/package.xml index 485900b..b2f1943 100644 --- a/rosidl_typesupport_protobuf_cpp/package.xml +++ b/rosidl_typesupport_protobuf_cpp/package.xml @@ -29,6 +29,7 @@ rosidl_typesupport_protobuf ament_cmake_gtest + ament_cmake_pytest rosidl_typesupport_cpp_packages From f1832f674c3a37c4e63d78b67596c35a6ea8b246 Mon Sep 17 00:00:00 2001 From: Gonzalo de Pedro Date: Fri, 22 Mar 2024 22:29:34 -0300 Subject: [PATCH 5/7] Make rosidl adapter work with rosidl cli Signed-off-by: Gonzalo de Pedro --- rosidl_adapter_proto/bin/rosidl_adapter_proto | 50 +----- .../rosidl_adapter_proto/cli.py | 157 ++++++++++++++++++ rosidl_adapter_proto/setup.cfg | 5 + 3 files changed, 169 insertions(+), 43 deletions(-) create mode 100644 rosidl_adapter_proto/rosidl_adapter_proto/cli.py create mode 100644 rosidl_adapter_proto/setup.cfg diff --git a/rosidl_adapter_proto/bin/rosidl_adapter_proto b/rosidl_adapter_proto/bin/rosidl_adapter_proto index bf49b23..eb98bd7 100644 --- a/rosidl_adapter_proto/bin/rosidl_adapter_proto +++ b/rosidl_adapter_proto/bin/rosidl_adapter_proto @@ -23,9 +23,8 @@ import sys import pathlib import os -from rosidl_cmake import read_generator_arguments -from rosidl_adapter_proto import generate_proto -from rosidl_adapter_proto import compile_proto +from rosidl_adapter_proto import convert_to_proto + def main(argv=sys.argv[1:]): parser = argparse.ArgumentParser( @@ -41,47 +40,12 @@ def main(argv=sys.argv[1:]): help='Path to the protoc executable') args = parser.parse_args(argv) - - generator_args = read_generator_arguments(args.generator_arguments_file) - - # Generate .proto files - rc = generate_proto(args.generator_arguments_file) - if rc: - return rc - - # Compile .proto files using protoc - cpp_out_dir = str(pathlib.Path(generator_args["output_dir"] + "/..").resolve()) - proto_path_list = [str(pathlib.Path(generator_args["output_dir"] + "/..").resolve())] - proto_files = [] - package_name = generator_args["package_name"] - - if "additional_files" in generator_args: - proto_path_list += generator_args["additional_files"] - - pathlib.Path(cpp_out_dir).mkdir(parents=True, exist_ok=True) - - for idl_tuple in generator_args.get('idl_tuples', []): - idl_parts = idl_tuple.rsplit(':', 1) - assert len(idl_parts) == 2 - idl_rel_path = pathlib.Path(idl_parts[1]) - idl_stem = idl_rel_path.stem - generated_file = os.path.join( - generator_args['output_dir'], - str(idl_rel_path.parent), - idl_stem + ".proto" - ) - proto_files.append(str(pathlib.Path(generated_file).resolve())) - - # compile proto files with protoc - rc = compile_proto(protoc_path = args.protoc_path, - proto_path_list = proto_path_list, - cpp_out_dir = cpp_out_dir, - proto_files = proto_files, - package_name = package_name - ) + try: + translate_to_proto(args.generator_arguments_file, args.protoc_path) + except RuntimeError: + return 1 - return rc - + return 0 if __name__ == '__main__': sys.exit(main()) diff --git a/rosidl_adapter_proto/rosidl_adapter_proto/cli.py b/rosidl_adapter_proto/rosidl_adapter_proto/cli.py new file mode 100644 index 0000000..7fd452d --- /dev/null +++ b/rosidl_adapter_proto/rosidl_adapter_proto/cli.py @@ -0,0 +1,157 @@ +import argparse +import os +import pathlib +import sys + +from ament_index_python import get_package_share_directory + +from catkin_pkg.package import package_exists_at +from catkin_pkg.package import parse_package + +from rosidl_adapter.action import convert_action_to_idl +from rosidl_adapter.msg import convert_msg_to_idl +from rosidl_adapter.srv import convert_srv_to_idl + +from rosidl_cmake import read_generator_arguments + +from rosidl_cli.command.helpers import interface_path_as_tuple +from rosidl_cli.command.helpers import legacy_generator_arguments_file +from rosidl_cli.command.translate.extensions import TranslateCommandExtension +from rosidl_cli.command.translate.api import translate + +from rosidl_adapter_proto import generate_proto +from rosidl_adapter_proto import compile_proto + +def convert_to_proto(generator_arguments_file, protoc_path): + generator_args = read_generator_arguments(generator_arguments_file) + + # Generate .proto files + rc = generate_proto(generator_arguments_file) + if rc : + raise RuntimeError + + # Compile .proto files using protoc + cpp_out_dir = str(pathlib.Path(generator_args["output_dir"] + "/..").resolve()) + proto_path_list = [str(pathlib.Path(generator_args["output_dir"] + "/..").resolve())] + proto_files = [] + package_name = generator_args["package_name"] + + if "additional_files" in generator_args: + proto_path_list += generator_args["additional_files"] + + pathlib.Path(cpp_out_dir).mkdir(parents=True, exist_ok=True) + + for idl_tuple in generator_args.get('idl_tuples', []): + idl_parts = idl_tuple.rsplit(':', 1) + assert len(idl_parts) == 2 + idl_rel_path = pathlib.Path(idl_parts[1]) + idl_stem = idl_rel_path.stem + generated_file = os.path.join( + generator_args['output_dir'], + str(idl_rel_path.parent), + idl_stem + ".proto" + ) + proto_files.append(str(pathlib.Path(generated_file).resolve())) + + # compile proto files with protoc + rc = compile_proto(protoc_path = protoc_path, + proto_path_list = proto_path_list, + cpp_out_dir = cpp_out_dir, + proto_files = proto_files, + package_name = package_name + ) + if rc : + raise RuntimeError + + return proto_files + + +def convert_files_to_idl(extension, conversion_function, argv=sys.argv[1:]): + parser = argparse.ArgumentParser( + description=f'Convert {extension} files to .idl') + parser.add_argument( + 'interface_files', nargs='+', + help='The interface files to convert') + args = parser.parse_args(argv) + + for interface_file in args.interface_files: + interface_file = pathlib.Path(interface_file) + package_dir = interface_file.parent.absolute() + while ( + len(package_dir.parents) and + not package_exists_at(str(package_dir)) + ): + package_dir = package_dir.parent + if not package_dir.parents: + print( + f"Could not find package for '{interface_file}'", + file=sys.stderr) + continue + warnings = [] + pkg = parse_package(package_dir, warnings=warnings) + + conversion_function( + package_dir, pkg.name, + interface_file.absolute().relative_to(package_dir), + interface_file.parent) + + +class TranslateToProto(TranslateCommandExtension): + + output_format = 'proto' + + def translate( + self, + package_name, + interface_files, + include_paths, + output_path + ): + + generated_files = [] + + package_share_path = pathlib.Path( + get_package_share_directory('rosidl_adapter_proto')) + templates_path = package_share_path / 'resource' + + + idl_interface_files = [] + non_idl_interface_files = [] + for path in interface_files: + if not path.endswith('.idl'): + non_idl_interface_files.append(path) + else: + idl_interface_files.append(path) + if non_idl_interface_files: + idl_interface_files.extend(translate( + package_name=package_name, + interface_files=non_idl_interface_files, + include_paths=include_paths, + output_format='idl', + output_path=output_path / 'tmp', + )) + + + # Generate code + with legacy_generator_arguments_file( + package_name=package_name, + interface_files=idl_interface_files, + include_paths=include_paths, + templates_path=templates_path, + output_path=output_path + ) as path_to_arguments_file: + generated_files.extend(convert_to_proto(path_to_arguments_file, '/usr/bin/protoc')) + return generated_files + + + +class TranslateMsgToProto(TranslateToProto): + input_format = 'msg' + + +class TranslateSrvToProto(TranslateToProto): + input_format = 'srv' + + +class TranslateActionToProto(TranslateToProto): + input_format = 'action' diff --git a/rosidl_adapter_proto/setup.cfg b/rosidl_adapter_proto/setup.cfg new file mode 100644 index 0000000..b0a21ca --- /dev/null +++ b/rosidl_adapter_proto/setup.cfg @@ -0,0 +1,5 @@ +[options.entry_points] +rosidl_cli.command.translate.extensions = + msg2proto = rosidl_adapter_proto.cli:TranslateMsgToProto + srv2proto = rosidl_adapter_proto.cli:TranslateSrvToProto + action2proto = rosidl_adapter_proto.cli:TranslateActionToProto From 622c671bceab99df86163d88b3a88ec886a11c40 Mon Sep 17 00:00:00 2001 From: Gonzalo de Pedro Date: Mon, 25 Mar 2024 18:43:54 -0300 Subject: [PATCH 6/7] fixes import Signed-off-by: Gonzalo de Pedro --- rosidl_adapter_proto/bin/rosidl_adapter_proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rosidl_adapter_proto/bin/rosidl_adapter_proto b/rosidl_adapter_proto/bin/rosidl_adapter_proto index eb98bd7..f99c314 100644 --- a/rosidl_adapter_proto/bin/rosidl_adapter_proto +++ b/rosidl_adapter_proto/bin/rosidl_adapter_proto @@ -23,7 +23,7 @@ import sys import pathlib import os -from rosidl_adapter_proto import convert_to_proto +from rosidl_adapter_proto.cli import convert_to_proto def main(argv=sys.argv[1:]): @@ -41,7 +41,7 @@ def main(argv=sys.argv[1:]): args = parser.parse_args(argv) try: - translate_to_proto(args.generator_arguments_file, args.protoc_path) + convert_to_proto(args.generator_arguments_file, args.protoc_path) except RuntimeError: return 1 From 8d31a11cf6d28488bb65a6470317e9513a5fe7fa Mon Sep 17 00:00:00 2001 From: Gonzalo de Pedro Date: Wed, 27 Mar 2024 21:00:34 -0300 Subject: [PATCH 7/7] Added test for rosidl_adapter_proto cli Signed-off-by: Gonzalo de Pedro --- .../test/test_rosidl_cli_translate.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 rosidl_adapter_proto/test/test_rosidl_cli_translate.py diff --git a/rosidl_adapter_proto/test/test_rosidl_cli_translate.py b/rosidl_adapter_proto/test/test_rosidl_cli_translate.py new file mode 100644 index 0000000..a996569 --- /dev/null +++ b/rosidl_adapter_proto/test/test_rosidl_cli_translate.py @@ -0,0 +1,30 @@ +import pytest +import os +import pathlib +import shutil +import subprocess + +from ament_index_python import get_package_share_directory + +def test_ts_files_generation(): + build_then_install('/tmp/tr') + files_exists('/tmp/tr') + +def build_then_install(output_path): + if os.path.exists(output_path): + shutil.rmtree(output_path) + os.makedirs(output_path) + + package_share_path = pathlib.Path( + get_package_share_directory('std_msgs')) + + subprocess.run([ + 'rosidl', 'translate', '-o', output_path, '--from', 'msg', '--to', 'proto', 'std_msgs', './msg/String.msg' + ], cwd=package_share_path, check=True) + +def files_exists(output_path): + assert pathlib.Path('/tmp/tr/msg/String.pb.cc').exists() + assert pathlib.Path('/tmp/tr/msg/String.pb.h').exists() + assert pathlib.Path('/tmp/tr/msg/String.proto').exists() + assert pathlib.Path('/tmp/tr/tmp/msg/String.idl').exists() + \ No newline at end of file