-
Notifications
You must be signed in to change notification settings - Fork 0
Rewrite of Exporter, Minor Changes in Importer #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
93a8768
2bba1cb
cdf4d37
a74346f
5f89261
8975701
27f7b1b
07770e2
37ae444
c7cd358
b4b38be
33ef4ca
a927b0b
7083d53
f98e3e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -82,6 +82,11 @@ def cli() -> None: | |||||||||||||||||||||||||||||||||
| type=str, | ||||||||||||||||||||||||||||||||||
| help="Regular expression to extract description from the file .", | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
| @click.option( | ||||||||||||||||||||||||||||||||||
| "--dependency-json", | ||||||||||||||||||||||||||||||||||
| type=click.Path(path_type=pathlib.Path, dir_okay=False), | ||||||||||||||||||||||||||||||||||
| help="A path to a JSON containing dependencies which should be imported.", | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
| def import_msgs( | ||||||||||||||||||||||||||||||||||
| *, | ||||||||||||||||||||||||||||||||||
| input: str, | ||||||||||||||||||||||||||||||||||
|
|
@@ -93,6 +98,7 @@ def import_msgs( | |||||||||||||||||||||||||||||||||
| output: pathlib.Path, | ||||||||||||||||||||||||||||||||||
| license_header: pathlib.Path | None, | ||||||||||||||||||||||||||||||||||
| description_regex: str | None, | ||||||||||||||||||||||||||||||||||
| dependency_json: pathlib.Path | None, | ||||||||||||||||||||||||||||||||||
| ) -> None: | ||||||||||||||||||||||||||||||||||
| """Import ROS messages into a Capella data package.""" | ||||||||||||||||||||||||||||||||||
| if root: | ||||||||||||||||||||||||||||||||||
|
|
@@ -108,7 +114,7 @@ def import_msgs( | |||||||||||||||||||||||||||||||||
| params = {"types_parent_uuid": model.sa.data_package.uuid} | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| parsed = importer.Importer( | ||||||||||||||||||||||||||||||||||
| input, no_deps, license_header, description_regex | ||||||||||||||||||||||||||||||||||
| input, no_deps, license_header, description_regex, dependency_json | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
| logger.info("Loaded %d packages", len(parsed.messages.packages)) | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
@@ -129,18 +135,30 @@ def import_msgs( | |||||||||||||||||||||||||||||||||
| type=cli_helpers.ModelCLI(), | ||||||||||||||||||||||||||||||||||
| required=True, | ||||||||||||||||||||||||||||||||||
| help="Path to the Capella model.", | ||||||||||||||||||||||||||||||||||
| envvar="CAPELLA_ROS_TOOLS_MODEL", | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
| @click.option( | ||||||||||||||||||||||||||||||||||
| "-l", | ||||||||||||||||||||||||||||||||||
| "--layer", | ||||||||||||||||||||||||||||||||||
| type=click.Choice(["oa", "la", "sa", "pa"], case_sensitive=False), | ||||||||||||||||||||||||||||||||||
| help="The layer to export the model objects from.", | ||||||||||||||||||||||||||||||||||
| envvar="CAPELLA_ROS_TOOLS_LAYER", | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
| @click.option( | ||||||||||||||||||||||||||||||||||
| "-r", | ||||||||||||||||||||||||||||||||||
| "--root", | ||||||||||||||||||||||||||||||||||
| type=click.UUID, | ||||||||||||||||||||||||||||||||||
| help="The UUID of the root package to import the messages from.", | ||||||||||||||||||||||||||||||||||
| envvar="CAPELLA_ROS_TOOLS_ROOT_PACKAGE", | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
| @click.option( | ||||||||||||||||||||||||||||||||||
| "-c", | ||||||||||||||||||||||||||||||||||
| "--config", | ||||||||||||||||||||||||||||||||||
| type=click.Path( | ||||||||||||||||||||||||||||||||||
| path_type=pathlib.Path, file_okay=True, dir_okay=False, readable=True | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| help="Path to the configuration file.", | ||||||||||||||||||||||||||||||||||
| envvar="CAPELLA_ROS_TOOLS_EXPORT_CONFIG", | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
| @click.option( | ||||||||||||||||||||||||||||||||||
| "-o", | ||||||||||||||||||||||||||||||||||
|
|
@@ -149,21 +167,67 @@ def import_msgs( | |||||||||||||||||||||||||||||||||
| default=pathlib.Path.cwd() / "data-package", | ||||||||||||||||||||||||||||||||||
| help="Output directory for the .msg files.", | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
| def export_capella( | ||||||||||||||||||||||||||||||||||
| @click.option( | ||||||||||||||||||||||||||||||||||
| "--generate-cmake", | ||||||||||||||||||||||||||||||||||
| type=bool, | ||||||||||||||||||||||||||||||||||
| default=False, | ||||||||||||||||||||||||||||||||||
| is_flag=True, | ||||||||||||||||||||||||||||||||||
| help="Decide whether experimental cmake files should be generated.", | ||||||||||||||||||||||||||||||||||
| envvar="CAPELLA_ROS_TOOLS_GENERATE_CMAKE", | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+170
to
+177
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a fan of short flag names. And short help texts. :)
Suggested change
|
||||||||||||||||||||||||||||||||||
| def export( | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that the function is called -@cli.command("export")
+@cli.command() |
||||||||||||||||||||||||||||||||||
| *, | ||||||||||||||||||||||||||||||||||
| model: capellambse.MelodyModel, | ||||||||||||||||||||||||||||||||||
| layer: str, | ||||||||||||||||||||||||||||||||||
| root: uuid.UUID, | ||||||||||||||||||||||||||||||||||
| config: pathlib.Path | None, | ||||||||||||||||||||||||||||||||||
| layer: str | None, | ||||||||||||||||||||||||||||||||||
| root: str | None, | ||||||||||||||||||||||||||||||||||
| output: pathlib.Path, | ||||||||||||||||||||||||||||||||||
| generate_cmake: bool, | ||||||||||||||||||||||||||||||||||
| ) -> None: | ||||||||||||||||||||||||||||||||||
| """Export Capella data package to ROS messages.""" | ||||||||||||||||||||||||||||||||||
| if root: | ||||||||||||||||||||||||||||||||||
| current_pkg = model.search("DataPkg").by_uuid(str(root)) | ||||||||||||||||||||||||||||||||||
| elif layer: | ||||||||||||||||||||||||||||||||||
| current_pkg = getattr(model, layer).data_package | ||||||||||||||||||||||||||||||||||
| if config: | ||||||||||||||||||||||||||||||||||
| conf = exporter.load_config(config, model) | ||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||
| raise click.UsageError("Either --root or --layer must be provided") | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| exporter.export(current_pkg, output) # type: ignore | ||||||||||||||||||||||||||||||||||
| if root: | ||||||||||||||||||||||||||||||||||
| root_package = model.search("DataPkg").by_uuid(str(root)) | ||||||||||||||||||||||||||||||||||
| elif layer: | ||||||||||||||||||||||||||||||||||
| root_package = getattr(model, layer).data_package | ||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||
| raise RuntimeError( | ||||||||||||||||||||||||||||||||||
| "Neither config nor root package nor layer specified." | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+196
to
+198
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be a RuntimeErrorINFO:capellambse.cli_helpers:Loading model from [$WORKSPACE]/models/ife-demo
Traceback (most recent call last):
File "", line 198, in _run_module_as_main
File "", line 88, in _run_code
File "[$WORKSPACE]/rostools/capella_ros_tools/__main__.py", line 234, in
cli()
~~~^^
File "[$WORKSPACE]/rostools/.venv/lib/python3.13/site-packages/click/core.py", line 1462, in __call__
return self.main(*args, **kwargs)
~~~~~~~~~^^^^^^^^^^^^^^^^^
File "[$WORKSPACE]/rostools/.venv/lib/python3.13/site-packages/click/core.py", line 1383, in main
rv = self.invoke(ctx)
File "[$WORKSPACE]/rostools/.venv/lib/python3.13/site-packages/click/core.py", line 1850, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
File "[$WORKSPACE]/rostools/.venv/lib/python3.13/site-packages/click/core.py", line 1246, in invoke
return ctx.invoke(self.callback, **ctx.params)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[$WORKSPACE]/rostools/.venv/lib/python3.13/site-packages/click/core.py", line 814, in invoke
return callback(*args, **kwargs)
File "[$WORKSPACE]/rostools/capella_ros_tools/__main__.py", line 196, in export
raise RuntimeError(
"Neither config nor root package nor layer specified."
)
RuntimeError: Neither config nor root package nor layer specified.
UsageErrorINFO:capellambse.cli_helpers:Loading model from [$WORKSPACE]/models/ife-demo Usage: python -m capella_ros_tools export [OPTIONS] Try 'python -m capella_ros_tools export --help' for help. IMO we should also use the parameter names in the error message:
Suggested change
|
||||||||||||||||||||||||||||||||||
| if not isinstance(root_package, capellambse.model.ModelElement): | ||||||||||||||||||||||||||||||||||
| raise RuntimeError("Failed to find root package.") | ||||||||||||||||||||||||||||||||||
| conf = exporter.ExporterConfig( | ||||||||||||||||||||||||||||||||||
| packages={ | ||||||||||||||||||||||||||||||||||
| exporter.RosExportHelper.make_snake_case( | ||||||||||||||||||||||||||||||||||
| root_package.name | ||||||||||||||||||||||||||||||||||
| ): root_package.uuid | ||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||
| built_ins={}, | ||||||||||||||||||||||||||||||||||
| custom_packages={}, | ||||||||||||||||||||||||||||||||||
| custom_types={}, | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
| if conf.packages and (root or layer): | ||||||||||||||||||||||||||||||||||
| logger.warning( | ||||||||||||||||||||||||||||||||||
| "Your config has packages defined, will ignore root/layer for that reason." | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| _exporter = exporter.Exporter( | ||||||||||||||||||||||||||||||||||
| conf.packages, | ||||||||||||||||||||||||||||||||||
| conf.built_ins, | ||||||||||||||||||||||||||||||||||
| conf.custom_packages, | ||||||||||||||||||||||||||||||||||
| conf.custom_types, | ||||||||||||||||||||||||||||||||||
| model, | ||||||||||||||||||||||||||||||||||
| generate_cmake, | ||||||||||||||||||||||||||||||||||
| conf.pkg_postfix, | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
| _exporter.export_ros_pkgs( | ||||||||||||||||||||||||||||||||||
| output, | ||||||||||||||||||||||||||||||||||
| conf.project_name, | ||||||||||||||||||||||||||||||||||
| conf.contact_email, | ||||||||||||||||||||||||||||||||||
| conf.maintainer, | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if __name__ == "__main__": | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| {# | ||
| Copyright DB InfraGO AG and contributors | ||
| SPDX-License-Identifier: Apache-2.0 | ||
| #} | ||
| # ############################################################################## | ||
| # Preamble | ||
| # ############################################################################## | ||
| cmake_minimum_required(VERSION 3.22) | ||
|
|
||
| # set cmake policy to use OLD behavior for FindPythonLibs / FindPythonInterp | ||
| # modules are deprecated since cmake 3.12, but rosidl_generator_py***() is still | ||
| # using them | ||
| # cmake_policy(SET CMP0148 OLD) | ||
|
|
||
| project({{pkg_name}} VERSION 1.0.0) | ||
|
|
||
| # ############################################################################## | ||
| # Project Wide Setup | ||
| # ############################################################################## | ||
| list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") | ||
|
|
||
| set(CMAKE_CXX_STANDARD 17) | ||
| set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||
| set(CMAKE_CXX_EXTENSIONS OFF) | ||
|
|
||
| # ############################################################################## | ||
| # Dependencies | ||
| # ############################################################################## | ||
| find_package(ament_cmake REQUIRED) | ||
|
|
||
| {% for dependency in dependencies -%} | ||
| find_package({{dependency}} REQUIRED) | ||
| {% endfor %} | ||
|
|
||
| # ############################################################################## | ||
| # Main targets | ||
| # ############################################################################## | ||
| # Targets | ||
| file( | ||
| GLOB_RECURSE MSG_FILES | ||
| LIST_DIRECTORIES false | ||
| RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" | ||
| "msg/*.msg" | ||
| ) | ||
|
|
||
| # Note: It seems required that the rosidl interface name is the same as | ||
| # the project name | ||
| rosidl_generate_interfaces( | ||
| ${PROJECT_NAME} ${MSG_FILES} | ||
| DEPENDENCIES | ||
| {% for dependency in dependencies -%} | ||
| {{ dependency }} | ||
| {% endfor %} | ||
| ) | ||
| rosidl_get_typesupport_target(${PROJECT_NAME}_target_name ${PROJECT_NAME} | ||
| "rosidl_typesupport_cpp") | ||
|
|
||
| # Create wrapper target, which has the desired name and not generated ros name | ||
| # We use the suffix wrapper_target, because the project name is already taken | ||
| # (see above). For ease of use the suffix is removed in the alias target and the | ||
| # exported target | ||
| add_library(${PROJECT_NAME}_wrapper_target INTERFACE) | ||
| set_target_properties(${PROJECT_NAME}_wrapper_target | ||
| PROPERTIES EXPORT_NAME ${PROJECT_NAME}) | ||
| add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS | ||
| ${PROJECT_NAME}_wrapper_target) | ||
| target_link_libraries(${PROJECT_NAME}_wrapper_target | ||
| INTERFACE ${${PROJECT_NAME}_target_name}) | ||
|
|
||
| # Installation | ||
| install( | ||
| TARGETS ${PROJECT_NAME}_wrapper_target | ||
| EXPORT ${PROJECT_NAME}_wrapper_targetTargets | ||
| INCLUDES | ||
| DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) | ||
|
|
||
| ament_export_dependencies(rosidl_default_runtime) | ||
| ament_export_targets(${PROJECT_NAME}_wrapper_targetTargets | ||
| HAS_LIBRARY_TARGET) | ||
|
|
||
| # ############################################################################## | ||
| # Tests | ||
| # ############################################################################## | ||
| if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) | ||
| find_package(ament_lint_auto REQUIRED) | ||
| # find_package(ament_cmake_gtest REQUIRED) | ||
| # ament_lint_auto_find_test_dependencies() | ||
| endif() | ||
|
|
||
| ament_package() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The world needs more TOML.
Advantages over YAML:
tomllibis in stdlib since Python 3.11 (previouslytomlion PyPI)Disadvantages:
load()instead ofsafe_load()