From 75c9a20e5156bfa3711801070bbf5cc71c752d72 Mon Sep 17 00:00:00 2001 From: Steve Peters Date: Wed, 23 Oct 2024 06:03:36 +0200 Subject: [PATCH 1/8] Helper to get version number from package.xml This adds a python script and a cmake helper function for getting the version number from a package.xml file. Signed-off-by: Steve Peters --- cmake/GzGetPackageXmlVersion.cmake | 54 +++++++++++++++++++ examples/CMakeLists.txt | 3 ++ .../version_from_package_xml/CMakeLists.txt | 14 +++++ examples/version_from_package_xml/README.md | 32 +++++++++++ .../include/CMakeLists.txt | 0 examples/version_from_package_xml/package.xml | 19 +++++++ .../src/CMakeLists.txt | 3 ++ .../test/CMakeLists.txt | 0 tools/print_package_xml_version.py | 37 +++++++++++++ 9 files changed, 162 insertions(+) create mode 100644 cmake/GzGetPackageXmlVersion.cmake create mode 100644 examples/version_from_package_xml/CMakeLists.txt create mode 100644 examples/version_from_package_xml/README.md create mode 100644 examples/version_from_package_xml/include/CMakeLists.txt create mode 100644 examples/version_from_package_xml/package.xml create mode 100644 examples/version_from_package_xml/src/CMakeLists.txt create mode 100644 examples/version_from_package_xml/test/CMakeLists.txt create mode 100644 tools/print_package_xml_version.py diff --git a/cmake/GzGetPackageXmlVersion.cmake b/cmake/GzGetPackageXmlVersion.cmake new file mode 100644 index 00000000..2f8e9d7e --- /dev/null +++ b/cmake/GzGetPackageXmlVersion.cmake @@ -0,0 +1,54 @@ +# Copyright (C) 2023 Open Source Robotics Foundation +# 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. + +################################################# +# gz_get_package_xml_version( ) +# +# Given the path to a package.xml file in , +# extract the version number and return the following variables +# prefixed by : +# - _VERSION: the full version number (Major.Minor.Patch) +# - _VERSION_MAJOR: the major version number +# - _VERSION_MINOR: the minor version number +# - _VERSION_PATCH: the patch version number +function(gz_get_package_xml_version package_xml_path version_var_prefix) + + if(NOT Python3_Interpreter_FOUND) + find_package(Python3 COMPONENTS Interpreter REQUIRED) + endif() + execute_process( + COMMAND "${Python3_EXECUTABLE}" + "${GZ_CMAKE_TOOLS_DIR}/print_package_xml_version.py" + "${package_xml_path}" + OUTPUT_VARIABLE PACKAGE_XML_version + ERROR_VARIABLE PACKAGE_XML_error + RESULT_VARIABLE PACKAGE_XML_result) + if(NOT ${PACKAGE_XML_result} EQUAL 0) + message("") + message(FATAL_ERROR "Failed to parse version number from package.xml: ${PACKAGE_XML_error}") + endif() + # split version number into list of three numbers + string(REPLACE "." ";" PACKAGE_XML_version_list ${PACKAGE_XML_version}) + + # Return version variables + list(GET PACKAGE_XML_version_list 0 PACKAGE_XML_version_major) + list(GET PACKAGE_XML_version_list 1 PACKAGE_XML_version_minor) + list(GET PACKAGE_XML_version_list 2 PACKAGE_XML_version_patch) + + # Return the list that has been created + set(${version_var_prefix}_VERSION ${PACKAGE_XML_version} PARENT_SCOPE) + set(${version_var_prefix}_VERSION_MAJOR ${PACKAGE_XML_version_major} PARENT_SCOPE) + set(${version_var_prefix}_VERSION_MINOR ${PACKAGE_XML_version_minor} PARENT_SCOPE) + set(${version_var_prefix}_VERSION_PATCH ${PACKAGE_XML_version_patch} PARENT_SCOPE) + +endfunction() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index c6bc5880..6ec79e18 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -19,6 +19,7 @@ set(example_directories core_static_child comp_deps use_config_ifp + version_from_package_xml ) if (NOT CMAKE_GENERATOR MATCHES "Visual Studio") list(APPEND example_directories @@ -61,6 +62,8 @@ foreach(example ${example_directories}) set(example_tarball_name gz-use_component_depsc-0.1.0.tar.bz2) elseif (${example} STREQUAL "use_config_ifp") set(example_tarball_name gz-find_config-0.1.0.tar.bz2) + elseif (${example} STREQUAL "version_from_package_xml") + set(example_tarball_name gz-version_from_package_xml-8.21.65.tar.bz2) else() set(example_tarball_name) diff --git a/examples/version_from_package_xml/CMakeLists.txt b/examples/version_from_package_xml/CMakeLists.txt new file mode 100644 index 00000000..db69de4d --- /dev/null +++ b/examples/version_from_package_xml/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR) + +find_package(gz-cmake4 REQUIRED) +include(GzGetPackageXmlVersion) +gz_get_package_xml_version(${CMAKE_SOURCE_DIR}/package.xml PACKAGE_XML) + +message(STATUS "PACKAGE_XML_VERSION ${PACKAGE_XML_VERSION}") +message(STATUS "PACKAGE_XML_VERSION_MAJOR ${PACKAGE_XML_VERSION_MAJOR}") +message(STATUS "PACKAGE_XML_VERSION_MINOR ${PACKAGE_XML_VERSION_MINOR}") +message(STATUS "PACKAGE_XML_VERSION_PATCH ${PACKAGE_XML_VERSION_PATCH}") + +project(gz-version_from_package_xml VERSION ${PACKAGE_XML_VERSION}) +gz_configure_project() +gz_configure_build(QUIT_IF_BUILD_ERRORS) diff --git a/examples/version_from_package_xml/README.md b/examples/version_from_package_xml/README.md new file mode 100644 index 00000000..a012d157 --- /dev/null +++ b/examples/version_from_package_xml/README.md @@ -0,0 +1,32 @@ +# version\_from\_package\_xml example + +## Getting a version number from package.xml file + +The package.xml file format (defined in +[ROS REP 127](https://ros.org/reps/rep-0127.html), +[ROS REP 140](https://ros.org/reps/rep-0140.html), and +[ROS REP 149](https://ros.org/reps/rep-0149.html)) +can be used to encode metadata about a package, including its version number. +This example shows how to use the `gz_get_package_xml_version` helper function +to get the version number from a package.xml file and use that to set the +cmake project version. + +The package.xml file in this folder encodes a version number `8.21.65`. +Configuring this example with cmake will parse the package.xml file and +print the cmake variables provided by the helper function. + +~~~ +mkdir build +cd build +cmake .. +~~~ + +You should see the following console output. + +~~~ +-- PACKAGE_XML_VERSION 8.21.65 +-- PACKAGE_XML_VERSION_MAJOR 8 +-- PACKAGE_XML_VERSION_MINOR 21 +-- PACKAGE_XML_VERSION_PATCH 65 +-- gz-version_from_package_xml version 8.21.65 +~~~ diff --git a/examples/version_from_package_xml/include/CMakeLists.txt b/examples/version_from_package_xml/include/CMakeLists.txt new file mode 100644 index 00000000..e69de29b diff --git a/examples/version_from_package_xml/package.xml b/examples/version_from_package_xml/package.xml new file mode 100644 index 00000000..81e69383 --- /dev/null +++ b/examples/version_from_package_xml/package.xml @@ -0,0 +1,19 @@ + + + + version_from_package_xml + 8.21.65 + Test package for gz-cmake + + Steve Peters + + Apache License 2.0 + + https://github.com/gazebosim/gz-cmake + + cmake + + + cmake + + diff --git a/examples/version_from_package_xml/src/CMakeLists.txt b/examples/version_from_package_xml/src/CMakeLists.txt new file mode 100644 index 00000000..abbf74b3 --- /dev/null +++ b/examples/version_from_package_xml/src/CMakeLists.txt @@ -0,0 +1,3 @@ + +gz_create_core_library(INTERFACE) + diff --git a/examples/version_from_package_xml/test/CMakeLists.txt b/examples/version_from_package_xml/test/CMakeLists.txt new file mode 100644 index 00000000..e69de29b diff --git a/tools/print_package_xml_version.py b/tools/print_package_xml_version.py new file mode 100644 index 00000000..cf57210f --- /dev/null +++ b/tools/print_package_xml_version.py @@ -0,0 +1,37 @@ +# Copyright (C) 2024 Open Source Robotics Foundation +# +# 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 re +import sys +from xml.etree import ElementTree as ET + +if len(sys.argv) != 2: + raise RuntimeError('Expected one argument with the path to a package.xml file') + +file_name = sys.argv[1] + +doc = ET.parse(file_name) +root = doc.getroot() +if root.tag != 'package': + raise RuntimeError('Invalid package.xml file, root tag <%s> should be ' % root.tag) + +version_str = root.find('version').text + +# validate version string using regex from catkin_pkg +# https://github.com/ros-infrastructure/catkin_pkg/blob/1.0.0/src/catkin_pkg/package_version.py#L55-L58 +match = re.match(r'^(\d+)\.(\d+)\.(\d+)$', version_str) +if match is None: + raise ValueError('Invalid version string, must be int.int.int: "%s"' % version) + +print(version_str, end='') From 837c21a0ad736f03c745516fefb07a738aa3b929 Mon Sep 17 00:00:00 2001 From: Steve Peters Date: Wed, 23 Oct 2024 06:30:50 +0200 Subject: [PATCH 2/8] Add GzGetPackageXmlVersion to GzCMake module This makes the gz_get_package_xml_version function available automatically after finding gz-cmake. Signed-off-by: Steve Peters --- cmake/GzCMake.cmake | 1 + examples/version_from_package_xml/CMakeLists.txt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/GzCMake.cmake b/cmake/GzCMake.cmake index 1ad8506e..da2b6c27 100644 --- a/cmake/GzCMake.cmake +++ b/cmake/GzCMake.cmake @@ -28,6 +28,7 @@ include(GzPackaging) include(GzCreateDocs) include(GzSetCompilerFlags) include(GzConfigureBuild) +include(GzGetPackageXmlVersion) include(GzImportTarget) include(GzPkgConfig) include(GzSanitizers) diff --git a/examples/version_from_package_xml/CMakeLists.txt b/examples/version_from_package_xml/CMakeLists.txt index db69de4d..7900dc1e 100644 --- a/examples/version_from_package_xml/CMakeLists.txt +++ b/examples/version_from_package_xml/CMakeLists.txt @@ -1,7 +1,6 @@ cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR) find_package(gz-cmake4 REQUIRED) -include(GzGetPackageXmlVersion) gz_get_package_xml_version(${CMAKE_SOURCE_DIR}/package.xml PACKAGE_XML) message(STATUS "PACKAGE_XML_VERSION ${PACKAGE_XML_VERSION}") From 06a7c29b3d1110be335addb12de470b4d490580a Mon Sep 17 00:00:00 2001 From: Steve Peters Date: Mon, 28 Oct 2024 13:44:34 -0700 Subject: [PATCH 3/8] update cmake comments Signed-off-by: Steve Peters --- cmake/GzGetPackageXmlVersion.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/GzGetPackageXmlVersion.cmake b/cmake/GzGetPackageXmlVersion.cmake index 2f8e9d7e..e8364fa5 100644 --- a/cmake/GzGetPackageXmlVersion.cmake +++ b/cmake/GzGetPackageXmlVersion.cmake @@ -40,12 +40,12 @@ function(gz_get_package_xml_version package_xml_path version_var_prefix) # split version number into list of three numbers string(REPLACE "." ";" PACKAGE_XML_version_list ${PACKAGE_XML_version}) - # Return version variables + # Create variables for major, minor, and patch version numbers list(GET PACKAGE_XML_version_list 0 PACKAGE_XML_version_major) list(GET PACKAGE_XML_version_list 1 PACKAGE_XML_version_minor) list(GET PACKAGE_XML_version_list 2 PACKAGE_XML_version_patch) - # Return the list that has been created + # Return variables for the full version number as well as major, minor, and patch version numbers set(${version_var_prefix}_VERSION ${PACKAGE_XML_version} PARENT_SCOPE) set(${version_var_prefix}_VERSION_MAJOR ${PACKAGE_XML_version_major} PARENT_SCOPE) set(${version_var_prefix}_VERSION_MINOR ${PACKAGE_XML_version_minor} PARENT_SCOPE) From 3fd24ed9cd83f99bfb7164205d11bbcafe060c12 Mon Sep 17 00:00:00 2001 From: Jose Luis Rivero Date: Tue, 29 Oct 2024 13:15:08 +0100 Subject: [PATCH 4/8] Update GzGetPackageXmlVersion.cmake Signed-off-by: Jose Luis Rivero --- cmake/GzGetPackageXmlVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/GzGetPackageXmlVersion.cmake b/cmake/GzGetPackageXmlVersion.cmake index e8364fa5..b6be331e 100644 --- a/cmake/GzGetPackageXmlVersion.cmake +++ b/cmake/GzGetPackageXmlVersion.cmake @@ -1,4 +1,4 @@ -# Copyright (C) 2023 Open Source Robotics Foundation +# Copyright (C) 2024 Open Source Robotics Foundation # 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 From 622d9110fed83a47a3465f4073ae1059a597eab1 Mon Sep 17 00:00:00 2001 From: Jose Luis Rivero Date: Tue, 29 Oct 2024 13:40:03 +0100 Subject: [PATCH 5/8] Add +x to the script Signed-off-by: Jose Luis Rivero --- tools/print_package_xml_version.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tools/print_package_xml_version.py diff --git a/tools/print_package_xml_version.py b/tools/print_package_xml_version.py old mode 100644 new mode 100755 From c8775be40a1966767df5eef87b1efe3de4513929 Mon Sep 17 00:00:00 2001 From: Steve Peters Date: Tue, 29 Oct 2024 10:04:48 -0700 Subject: [PATCH 6/8] Add shebang to script Signed-off-by: Steve Peters --- tools/print_package_xml_version.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/print_package_xml_version.py b/tools/print_package_xml_version.py index cf57210f..518f05d7 100755 --- a/tools/print_package_xml_version.py +++ b/tools/print_package_xml_version.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # Copyright (C) 2024 Open Source Robotics Foundation # # Licensed under the Apache License, Version 2.0 (the "License") From 1630a52ccf234930bcfd122a2d6aa363972911a8 Mon Sep 17 00:00:00 2001 From: Steve Peters Date: Tue, 29 Oct 2024 10:05:01 -0700 Subject: [PATCH 7/8] fix variable name in exception string Signed-off-by: Steve Peters --- tools/print_package_xml_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/print_package_xml_version.py b/tools/print_package_xml_version.py index 518f05d7..bf50e920 100755 --- a/tools/print_package_xml_version.py +++ b/tools/print_package_xml_version.py @@ -33,6 +33,6 @@ # https://github.com/ros-infrastructure/catkin_pkg/blob/1.0.0/src/catkin_pkg/package_version.py#L55-L58 match = re.match(r'^(\d+)\.(\d+)\.(\d+)$', version_str) if match is None: - raise ValueError('Invalid version string, must be int.int.int: "%s"' % version) + raise ValueError('Invalid version string, must be int.int.int: "%s"' % version_str) print(version_str, end='') From e14fd4590af66ee68a50278059fd7f09abab1eb1 Mon Sep 17 00:00:00 2001 From: Steve Peters Date: Tue, 29 Oct 2024 10:07:02 -0700 Subject: [PATCH 8/8] raise if no version tag is found Co-authored-by: Jose Luis Rivero Signed-off-by: Steve Peters --- tools/print_package_xml_version.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/print_package_xml_version.py b/tools/print_package_xml_version.py index bf50e920..c7eabf60 100755 --- a/tools/print_package_xml_version.py +++ b/tools/print_package_xml_version.py @@ -27,6 +27,9 @@ if root.tag != 'package': raise RuntimeError('Invalid package.xml file, root tag <%s> should be ' % root.tag) +if root.find('version') is None: + raise RuntimeError('Invalid package.xml file, no tag found.') + version_str = root.find('version').text # validate version string using regex from catkin_pkg