-
Notifications
You must be signed in to change notification settings - Fork 127
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Michel Hidalgo <[email protected]>
- Loading branch information
Showing
4 changed files
with
198 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
# Copyright 2021 Open Source Robotics Foundation, Inc. | ||
# | ||
# 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. | ||
|
||
import collections | ||
import os | ||
import pathlib | ||
|
||
from rosidl_cli.command import Command | ||
|
||
from .extensions import load_translate_extensions | ||
|
||
|
||
class TranslateCommand(Command): | ||
"""Translate interface definition files from one format to another.""" | ||
|
||
name = 'translate' | ||
|
||
def add_arguments(self, parser, cli_name): | ||
parser.add_argument( | ||
'-o', '--output-path', metavar='PATH', | ||
type=pathlib.Path, default=pathlib.Path.cwd(), | ||
help=('Path to directory to hold translated interface definition' | ||
"files. Defaults to '.'.")) | ||
parser.add_argument( | ||
'--use', '--translator', metavar='TRANSLATOR_SPEC', | ||
dest='translator_specs', action='append', default=[], | ||
help=('Target translators, backed by tool extensions. ' | ||
'Specified by name plus an optional PEP440 version ' | ||
'specifier. If none is given, suitable ones among ' | ||
'all available translators will be chosen.') | ||
) | ||
parser.add_argument( | ||
'--to', '--output-format', metavar='FORMAT', | ||
dest='output_format', required=True, | ||
help=('Output format for translate interface definition files. ' | ||
'Specified by name plus an optional PEP440 version.') | ||
) | ||
parser.add_argument( | ||
'--from', '--input-format', metavar='FORMAT', | ||
dest='input_format', default=None, | ||
help=('Input format for all source interface definition files. ' | ||
'Specified by name plus an optional PEP440 version. ' | ||
'If not given, file extensions will be used to deduce ' | ||
'the format of each interface definition file.') | ||
) | ||
parser.add_argument( | ||
'-I', '--include-path', metavar='PATH', type=pathlib.Path, | ||
dest='include_paths', action='append', default=[], | ||
help='Paths to include dependency interface definition files from.' | ||
) | ||
parser.add_argument( | ||
'package_name', | ||
help='Name of the package all interface files belong to') | ||
parser.add_argument( | ||
'interface_files', metavar='interface_file', nargs='+', | ||
help=('Normalized relative path to an interface definition file. ' | ||
"If prefixed by another path followed by a colon ':', " | ||
'path resolution is performed against such path.') | ||
) | ||
|
||
def main(self, *, parser, args): | ||
extensions = load_translate_extensions( | ||
specs=args.translator_specs, | ||
strict=any(args.translator_specs) | ||
) | ||
if not extensions: | ||
return 'No translate extensions found' | ||
|
||
if not args.input_format: | ||
interface_files_per_format = collections.defaultdict(list) | ||
for interface_file in args.interface_files: | ||
input_format = os.path.splitext(interface_file)[-1][1:] | ||
interface_files_per_format[input_format].append(interface_file) | ||
else: | ||
interface_files_per_format = { | ||
args.input_format: args.interface_files} | ||
|
||
for input_format, interface_files in interface_files_per_format.items(): | ||
extension = next(( | ||
extension for extension in extensions | ||
if extension.input_format == input_format and \ | ||
extension.output_format == args.output_format | ||
), None) | ||
|
||
if not extension: | ||
return (f"Translation from '{input_format}' to " | ||
f"'{args.output_format}' is not supported") | ||
|
||
extension.translate( | ||
args.package_name, interface_files, | ||
args.include_paths, args.output_path) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Copyright 2021 Open Source Robotics Foundation, Inc. | ||
# | ||
# 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 rosidl_cli.extensions import Extension | ||
from rosidl_cli.extensions import load_extensions | ||
|
||
|
||
class TranslateCommandExtension(Extension): | ||
""" | ||
The extension point for interface definition translation. | ||
The following attributes must be defined | ||
* `input_format` | ||
* `output_format` | ||
The following methods must be defined: | ||
* `translate` | ||
""" | ||
|
||
def translate( | ||
self, | ||
package_name, | ||
interface_file, | ||
include_paths, | ||
output_path | ||
): | ||
""" | ||
Translate interface definition file. | ||
The path to an interface definition file is a relative path optionally | ||
prefixed by an absolute path followed by a colon ':', in which case | ||
path resolution is to be performed against that absolute path. | ||
On output, the directory structure specified by this relative path | ||
will be replicated e.g. an ``msg/Empty.foo`` file will result in a | ||
``msg/Empty.bar`` file under `output_path`. | ||
:param package_name: name of the package `interface_file` belongs to | ||
:param interface_file: path to the interface definition file | ||
:param include_paths: list of paths to include dependency interface | ||
definition files from | ||
:param output_path: path to directory to hold the translated interface | ||
definition file | ||
""" | ||
raise NotImplementedError() | ||
|
||
|
||
def load_translate_extensions(**kwargs): | ||
"""Load extensions for interface definition translation.""" | ||
return load_extensions( | ||
'rosidl_cli.command.translate.extensions', **kwargs | ||
) |