Skip to content

Commit f1832f6

Browse files
committed
Make rosidl adapter work with rosidl cli
Signed-off-by: Gonzalo de Pedro <[email protected]>
1 parent c366f33 commit f1832f6

File tree

3 files changed

+169
-43
lines changed

3 files changed

+169
-43
lines changed

rosidl_adapter_proto/bin/rosidl_adapter_proto

+7-43
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ import sys
2323
import pathlib
2424
import os
2525

26-
from rosidl_cmake import read_generator_arguments
27-
from rosidl_adapter_proto import generate_proto
28-
from rosidl_adapter_proto import compile_proto
26+
from rosidl_adapter_proto import convert_to_proto
27+
2928

3029
def main(argv=sys.argv[1:]):
3130
parser = argparse.ArgumentParser(
@@ -41,47 +40,12 @@ def main(argv=sys.argv[1:]):
4140
help='Path to the protoc executable')
4241

4342
args = parser.parse_args(argv)
44-
45-
generator_args = read_generator_arguments(args.generator_arguments_file)
46-
47-
# Generate .proto files
48-
rc = generate_proto(args.generator_arguments_file)
49-
if rc:
50-
return rc
51-
52-
# Compile .proto files using protoc
53-
cpp_out_dir = str(pathlib.Path(generator_args["output_dir"] + "/..").resolve())
54-
proto_path_list = [str(pathlib.Path(generator_args["output_dir"] + "/..").resolve())]
55-
proto_files = []
56-
package_name = generator_args["package_name"]
57-
58-
if "additional_files" in generator_args:
59-
proto_path_list += generator_args["additional_files"]
60-
61-
pathlib.Path(cpp_out_dir).mkdir(parents=True, exist_ok=True)
62-
63-
for idl_tuple in generator_args.get('idl_tuples', []):
64-
idl_parts = idl_tuple.rsplit(':', 1)
65-
assert len(idl_parts) == 2
66-
idl_rel_path = pathlib.Path(idl_parts[1])
67-
idl_stem = idl_rel_path.stem
68-
generated_file = os.path.join(
69-
generator_args['output_dir'],
70-
str(idl_rel_path.parent),
71-
idl_stem + ".proto"
72-
)
73-
proto_files.append(str(pathlib.Path(generated_file).resolve()))
74-
75-
# compile proto files with protoc
76-
rc = compile_proto(protoc_path = args.protoc_path,
77-
proto_path_list = proto_path_list,
78-
cpp_out_dir = cpp_out_dir,
79-
proto_files = proto_files,
80-
package_name = package_name
81-
)
43+
try:
44+
translate_to_proto(args.generator_arguments_file, args.protoc_path)
45+
except RuntimeError:
46+
return 1
8247

83-
return rc
84-
48+
return 0
8549

8650
if __name__ == '__main__':
8751
sys.exit(main())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import argparse
2+
import os
3+
import pathlib
4+
import sys
5+
6+
from ament_index_python import get_package_share_directory
7+
8+
from catkin_pkg.package import package_exists_at
9+
from catkin_pkg.package import parse_package
10+
11+
from rosidl_adapter.action import convert_action_to_idl
12+
from rosidl_adapter.msg import convert_msg_to_idl
13+
from rosidl_adapter.srv import convert_srv_to_idl
14+
15+
from rosidl_cmake import read_generator_arguments
16+
17+
from rosidl_cli.command.helpers import interface_path_as_tuple
18+
from rosidl_cli.command.helpers import legacy_generator_arguments_file
19+
from rosidl_cli.command.translate.extensions import TranslateCommandExtension
20+
from rosidl_cli.command.translate.api import translate
21+
22+
from rosidl_adapter_proto import generate_proto
23+
from rosidl_adapter_proto import compile_proto
24+
25+
def convert_to_proto(generator_arguments_file, protoc_path):
26+
generator_args = read_generator_arguments(generator_arguments_file)
27+
28+
# Generate .proto files
29+
rc = generate_proto(generator_arguments_file)
30+
if rc :
31+
raise RuntimeError
32+
33+
# Compile .proto files using protoc
34+
cpp_out_dir = str(pathlib.Path(generator_args["output_dir"] + "/..").resolve())
35+
proto_path_list = [str(pathlib.Path(generator_args["output_dir"] + "/..").resolve())]
36+
proto_files = []
37+
package_name = generator_args["package_name"]
38+
39+
if "additional_files" in generator_args:
40+
proto_path_list += generator_args["additional_files"]
41+
42+
pathlib.Path(cpp_out_dir).mkdir(parents=True, exist_ok=True)
43+
44+
for idl_tuple in generator_args.get('idl_tuples', []):
45+
idl_parts = idl_tuple.rsplit(':', 1)
46+
assert len(idl_parts) == 2
47+
idl_rel_path = pathlib.Path(idl_parts[1])
48+
idl_stem = idl_rel_path.stem
49+
generated_file = os.path.join(
50+
generator_args['output_dir'],
51+
str(idl_rel_path.parent),
52+
idl_stem + ".proto"
53+
)
54+
proto_files.append(str(pathlib.Path(generated_file).resolve()))
55+
56+
# compile proto files with protoc
57+
rc = compile_proto(protoc_path = protoc_path,
58+
proto_path_list = proto_path_list,
59+
cpp_out_dir = cpp_out_dir,
60+
proto_files = proto_files,
61+
package_name = package_name
62+
)
63+
if rc :
64+
raise RuntimeError
65+
66+
return proto_files
67+
68+
69+
def convert_files_to_idl(extension, conversion_function, argv=sys.argv[1:]):
70+
parser = argparse.ArgumentParser(
71+
description=f'Convert {extension} files to .idl')
72+
parser.add_argument(
73+
'interface_files', nargs='+',
74+
help='The interface files to convert')
75+
args = parser.parse_args(argv)
76+
77+
for interface_file in args.interface_files:
78+
interface_file = pathlib.Path(interface_file)
79+
package_dir = interface_file.parent.absolute()
80+
while (
81+
len(package_dir.parents) and
82+
not package_exists_at(str(package_dir))
83+
):
84+
package_dir = package_dir.parent
85+
if not package_dir.parents:
86+
print(
87+
f"Could not find package for '{interface_file}'",
88+
file=sys.stderr)
89+
continue
90+
warnings = []
91+
pkg = parse_package(package_dir, warnings=warnings)
92+
93+
conversion_function(
94+
package_dir, pkg.name,
95+
interface_file.absolute().relative_to(package_dir),
96+
interface_file.parent)
97+
98+
99+
class TranslateToProto(TranslateCommandExtension):
100+
101+
output_format = 'proto'
102+
103+
def translate(
104+
self,
105+
package_name,
106+
interface_files,
107+
include_paths,
108+
output_path
109+
):
110+
111+
generated_files = []
112+
113+
package_share_path = pathlib.Path(
114+
get_package_share_directory('rosidl_adapter_proto'))
115+
templates_path = package_share_path / 'resource'
116+
117+
118+
idl_interface_files = []
119+
non_idl_interface_files = []
120+
for path in interface_files:
121+
if not path.endswith('.idl'):
122+
non_idl_interface_files.append(path)
123+
else:
124+
idl_interface_files.append(path)
125+
if non_idl_interface_files:
126+
idl_interface_files.extend(translate(
127+
package_name=package_name,
128+
interface_files=non_idl_interface_files,
129+
include_paths=include_paths,
130+
output_format='idl',
131+
output_path=output_path / 'tmp',
132+
))
133+
134+
135+
# Generate code
136+
with legacy_generator_arguments_file(
137+
package_name=package_name,
138+
interface_files=idl_interface_files,
139+
include_paths=include_paths,
140+
templates_path=templates_path,
141+
output_path=output_path
142+
) as path_to_arguments_file:
143+
generated_files.extend(convert_to_proto(path_to_arguments_file, '/usr/bin/protoc'))
144+
return generated_files
145+
146+
147+
148+
class TranslateMsgToProto(TranslateToProto):
149+
input_format = 'msg'
150+
151+
152+
class TranslateSrvToProto(TranslateToProto):
153+
input_format = 'srv'
154+
155+
156+
class TranslateActionToProto(TranslateToProto):
157+
input_format = 'action'

rosidl_adapter_proto/setup.cfg

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[options.entry_points]
2+
rosidl_cli.command.translate.extensions =
3+
msg2proto = rosidl_adapter_proto.cli:TranslateMsgToProto
4+
srv2proto = rosidl_adapter_proto.cli:TranslateSrvToProto
5+
action2proto = rosidl_adapter_proto.cli:TranslateActionToProto

0 commit comments

Comments
 (0)