|
12 | 12 | # See the License for the specific language governing permissions and
|
13 | 13 | # limitations under the License.
|
14 | 14 |
|
15 |
| -from io import StringIO |
16 |
| -import json |
17 |
| -import os |
18 |
| -import pathlib |
19 |
| -import re |
20 |
| -import sys |
| 15 | +import warnings |
21 | 16 |
|
22 |
| -import em |
23 |
| -from rosidl_parser.definition import IdlLocator |
24 |
| -from rosidl_parser.parser import parse_idl_file |
| 17 | +from rosidl_pycommon import * # noqa: F401, F403 |
25 | 18 |
|
26 |
| - |
27 |
| -def convert_camel_case_to_lower_case_underscore(value): |
28 |
| - # insert an underscore before any upper case letter |
29 |
| - # which is followed by a lower case letter |
30 |
| - value = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', value) |
31 |
| - # insert an underscore before any upper case letter |
32 |
| - # which is preseded by a lower case letter or number |
33 |
| - value = re.sub('([a-z0-9])([A-Z])', r'\1_\2', value) |
34 |
| - return value.lower() |
35 |
| - |
36 |
| - |
37 |
| -def read_generator_arguments(input_file): |
38 |
| - with open(input_file, mode='r', encoding='utf-8') as h: |
39 |
| - return json.load(h) |
40 |
| - |
41 |
| - |
42 |
| -def get_newest_modification_time(target_dependencies): |
43 |
| - newest_timestamp = None |
44 |
| - for dep in target_dependencies: |
45 |
| - ts = os.path.getmtime(dep) |
46 |
| - if newest_timestamp is None or ts > newest_timestamp: |
47 |
| - newest_timestamp = ts |
48 |
| - return newest_timestamp |
49 |
| - |
50 |
| - |
51 |
| -def generate_files( |
52 |
| - generator_arguments_file, mapping, additional_context=None, |
53 |
| - keep_case=False, post_process_callback=None |
54 |
| -): |
55 |
| - args = read_generator_arguments(generator_arguments_file) |
56 |
| - |
57 |
| - template_basepath = pathlib.Path(args['template_dir']) |
58 |
| - for template_filename in mapping.keys(): |
59 |
| - assert (template_basepath / template_filename).exists(), \ |
60 |
| - 'Could not find template: ' + template_filename |
61 |
| - |
62 |
| - latest_target_timestamp = get_newest_modification_time(args['target_dependencies']) |
63 |
| - generated_files = [] |
64 |
| - |
65 |
| - for idl_tuple in args.get('idl_tuples', []): |
66 |
| - idl_parts = idl_tuple.rsplit(':', 1) |
67 |
| - assert len(idl_parts) == 2 |
68 |
| - locator = IdlLocator(*idl_parts) |
69 |
| - idl_rel_path = pathlib.Path(idl_parts[1]) |
70 |
| - idl_stem = idl_rel_path.stem |
71 |
| - if not keep_case: |
72 |
| - idl_stem = convert_camel_case_to_lower_case_underscore(idl_stem) |
73 |
| - try: |
74 |
| - idl_file = parse_idl_file(locator) |
75 |
| - for template_file, generated_filename in mapping.items(): |
76 |
| - generated_file = os.path.join( |
77 |
| - args['output_dir'], str(idl_rel_path.parent), |
78 |
| - generated_filename % idl_stem) |
79 |
| - generated_files.append(generated_file) |
80 |
| - data = { |
81 |
| - 'package_name': args['package_name'], |
82 |
| - 'interface_path': idl_rel_path, |
83 |
| - 'content': idl_file.content, |
84 |
| - } |
85 |
| - if additional_context is not None: |
86 |
| - data.update(additional_context) |
87 |
| - expand_template( |
88 |
| - os.path.basename(template_file), data, |
89 |
| - generated_file, minimum_timestamp=latest_target_timestamp, |
90 |
| - template_basepath=template_basepath, |
91 |
| - post_process_callback=post_process_callback) |
92 |
| - except Exception as e: |
93 |
| - print( |
94 |
| - 'Error processing idl file: ' + |
95 |
| - str(locator.get_absolute_path()), file=sys.stderr) |
96 |
| - raise(e) |
97 |
| - |
98 |
| - return generated_files |
99 |
| - |
100 |
| - |
101 |
| -template_prefix_path = [] |
102 |
| - |
103 |
| - |
104 |
| -def get_template_path(template_name): |
105 |
| - global template_prefix_path |
106 |
| - for basepath in template_prefix_path: |
107 |
| - template_path = basepath / template_name |
108 |
| - if template_path.exists(): |
109 |
| - return template_path |
110 |
| - raise RuntimeError(f"Failed to find template '{template_name}'") |
111 |
| - |
112 |
| - |
113 |
| -interpreter = None |
114 |
| - |
115 |
| - |
116 |
| -def expand_template( |
117 |
| - template_name, data, output_file, minimum_timestamp=None, |
118 |
| - template_basepath=None, post_process_callback=None |
119 |
| -): |
120 |
| - # in the legacy API the first argument was the path to the template |
121 |
| - if template_basepath is None: |
122 |
| - template_name = pathlib.Path(template_name) |
123 |
| - template_basepath = template_name.parent |
124 |
| - template_name = template_name.name |
125 |
| - |
126 |
| - global interpreter |
127 |
| - output = StringIO() |
128 |
| - interpreter = em.Interpreter( |
129 |
| - output=output, |
130 |
| - options={ |
131 |
| - em.BUFFERED_OPT: True, |
132 |
| - em.RAW_OPT: True, |
133 |
| - }, |
134 |
| - ) |
135 |
| - |
136 |
| - global template_prefix_path |
137 |
| - template_prefix_path.append(template_basepath) |
138 |
| - template_path = get_template_path(template_name) |
139 |
| - |
140 |
| - # create copy before manipulating |
141 |
| - data = dict(data) |
142 |
| - _add_helper_functions(data) |
143 |
| - |
144 |
| - try: |
145 |
| - with template_path.open('r') as h: |
146 |
| - template_content = h.read() |
147 |
| - interpreter.invoke( |
148 |
| - 'beforeFile', name=template_name, file=h, locals=data) |
149 |
| - interpreter.string(template_content, template_path, locals=data) |
150 |
| - interpreter.invoke('afterFile') |
151 |
| - except Exception as e: # noqa: F841 |
152 |
| - if os.path.exists(output_file): |
153 |
| - os.remove(output_file) |
154 |
| - print(f"{e.__class__.__name__} when expanding '{template_name}' into " |
155 |
| - f"'{output_file}': {e}", file=sys.stderr) |
156 |
| - raise |
157 |
| - finally: |
158 |
| - template_prefix_path.pop() |
159 |
| - |
160 |
| - content = output.getvalue() |
161 |
| - interpreter.shutdown() |
162 |
| - |
163 |
| - if post_process_callback: |
164 |
| - content = post_process_callback(content) |
165 |
| - |
166 |
| - # only overwrite file if necessary |
167 |
| - # which is either when the timestamp is too old or when the content is different |
168 |
| - if os.path.exists(output_file): |
169 |
| - timestamp = os.path.getmtime(output_file) |
170 |
| - if minimum_timestamp is None or timestamp > minimum_timestamp: |
171 |
| - with open(output_file, 'r', encoding='utf-8') as h: |
172 |
| - if h.read() == content: |
173 |
| - return |
174 |
| - else: |
175 |
| - # create folder if necessary |
176 |
| - try: |
177 |
| - os.makedirs(os.path.dirname(output_file)) |
178 |
| - except FileExistsError: |
179 |
| - pass |
180 |
| - |
181 |
| - with open(output_file, 'w', encoding='utf-8') as h: |
182 |
| - h.write(content) |
183 |
| - |
184 |
| - |
185 |
| -def _add_helper_functions(data): |
186 |
| - data['TEMPLATE'] = _expand_template |
187 |
| - |
188 |
| - |
189 |
| -def _expand_template(template_name, **kwargs): |
190 |
| - global interpreter |
191 |
| - template_path = get_template_path(template_name) |
192 |
| - _add_helper_functions(kwargs) |
193 |
| - with template_path.open('r') as h: |
194 |
| - interpreter.invoke( |
195 |
| - 'beforeInclude', name=str(template_path), file=h, locals=kwargs) |
196 |
| - content = h.read() |
197 |
| - try: |
198 |
| - interpreter.string(content, str(template_path), kwargs) |
199 |
| - except Exception as e: # noqa: F841 |
200 |
| - print(f"{e.__class__.__name__} in template '{template_path}': {e}", |
201 |
| - file=sys.stderr) |
202 |
| - raise |
203 |
| - interpreter.invoke('afterInclude') |
| 19 | +warnings.warn( |
| 20 | + "The 'rosidl_cmake' Python module is deprecated. Use 'rosidl_pycommon' instead.", |
| 21 | + UserWarning |
| 22 | +) |
0 commit comments