Răsfoiți Sursa

CPack RPM and DEB: improved package version handling

Adds support for epoch version to CPackRPM and
CPackDeb packagers.
Also adds better version checking to CPackDeb
that complies with Debian rules.

Fixes: #17057
Domen Vrankar 8 ani în urmă
părinte
comite
74b7457f12

+ 14 - 0
Help/release/dev/cpack-rpm-deb-version.rst

@@ -0,0 +1,14 @@
+cpack-rpm-deb-version
+---------------------
+
+* Modules :module:`CPackRPM` and :module:`CPackDeb` learned to set package epoch
+  version.
+  See :variable:`CPACK_RPM_PACKAGE_EPOCH` and
+  :variable:`CPACK_DEBIAN_PACKAGE_EPOCH` variables.
+
+* The :module:`CPackDeb` module learned to set package release version in
+  `Version` info property.
+  See :variable:`CPACK_DEBIAN_PACKAGE_RELEASE` variable.
+
+* The :module:`CPackDeb` module learned more strict package version checking
+  that complies with Debian rules.

+ 44 - 8
Modules/CPackDeb.cmake

@@ -88,6 +88,16 @@
 #    get overwritten and it is up to the packager to set the variables in a
 #    manner that will prevent such errors.
 #
+# .. variable:: CPACK_DEBIAN_PACKAGE_EPOCH
+#
+#  The Debian package epoch
+#
+#  * Mandatory : No
+#  * Default   : -
+#
+#  Optional number that should be incremented when changing versioning schemas
+#  or fixing mistakes in the version numbers of older packages.
+#
 # .. variable:: CPACK_DEBIAN_PACKAGE_VERSION
 #
 #  The Debian package version
@@ -95,12 +105,17 @@
 #  * Mandatory : YES
 #  * Default   : :variable:`CPACK_PACKAGE_VERSION`
 #
+#  This variable may contain only alphanumerics (A-Za-z0-9) and the characters
+#  . + - ~ (full stop, plus, hyphen, tilde) and should start with a digit. If
+#  :variable:`CPACK_DEBIAN_PACKAGE_RELEASE` is not set then hyphens are not
+#  allowed.
+#
 # .. variable:: CPACK_DEBIAN_PACKAGE_RELEASE
 #
 #  The Debian package release - Debian revision number.
 #
-#  * Mandatory : YES
-#  * Default   : 1
+#  * Mandatory : No
+#  * Default   : -
 #
 #  This is the numbering of the DEB package itself, i.e. the version of the
 #  packaging and not the version of the content (see
@@ -738,6 +753,32 @@ function(cpack_deb_prepare_package_vars)
     set(CPACK_DEBIAN_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION})
   endif()
 
+  if(NOT CPACK_DEBIAN_PACKAGE_VERSION MATCHES "^[0-9][A-Za-z0-9.+-~]*$")
+    message(FATAL_ERROR
+      "CPackDeb: Debian package version must confirm to \"^[0-9][A-Za-z0-9.+-~]*$\" regex!")
+  endif()
+
+  if(CPACK_DEBIAN_PACKAGE_RELEASE)
+    if(NOT CPACK_DEBIAN_PACKAGE_RELEASE MATCHES "^[A-Za-z0-9.+~]+$")
+      message(FATAL_ERROR
+        "CPackDeb: Debian package release must confirm to \"^[A-Za-z0-9.+~]+$\" regex!")
+    endif()
+    string(APPEND CPACK_DEBIAN_PACKAGE_VERSION
+      "-${CPACK_DEBIAN_PACKAGE_RELEASE}")
+  elseif(CPACK_DEBIAN_PACKAGE_VERSION MATCHES ".*-.*")
+    message(FATAL_ERROR
+      "CPackDeb: Debian package version must not contain hyphens when CPACK_DEBIAN_PACKAGE_RELEASE is not provided!")
+  endif()
+
+  if(CPACK_DEBIAN_PACKAGE_EPOCH)
+    if(NOT CPACK_DEBIAN_PACKAGE_EPOCH MATCHES "^[0-9]+$")
+      message(FATAL_ERROR
+        "CPackDeb: Debian package epoch must confirm to \"^[0-9]+$\" regex!")
+    endif()
+    set(CPACK_DEBIAN_PACKAGE_VERSION
+      "${CPACK_DEBIAN_PACKAGE_EPOCH}:${CPACK_DEBIAN_PACKAGE_VERSION}")
+  endif()
+
   # Architecture: (mandatory)
   if(CPACK_DEB_PACKAGE_COMPONENT AND CPACK_DEBIAN_${_local_component_name}_PACKAGE_ARCHITECTURE)
     set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${CPACK_DEBIAN_${_local_component_name}_PACKAGE_ARCHITECTURE}")
@@ -961,11 +1002,6 @@ function(cpack_deb_prepare_package_vars)
     set(CPACK_DEBIAN_GENERATE_POSTRM 0)
   endif()
 
-  if(NOT CPACK_DEBIAN_PACKAGE_RELEASE)
-    set(CPACK_DEBIAN_PACKAGE_RELEASE 1)
-  endif()
-
-
   cpack_deb_variable_fallback("CPACK_DEBIAN_FILE_NAME"
     "CPACK_DEBIAN_${_local_component_name}_FILE_NAME"
     "CPACK_DEBIAN_FILE_NAME")
@@ -974,7 +1010,7 @@ function(cpack_deb_prepare_package_vars)
       # Patch package file name to be in corrent debian format:
       # <foo>_<VersionNumber>-<DebianRevisionNumber>_<DebianArchitecture>.deb
       set(CPACK_OUTPUT_FILE_NAME
-        "${CPACK_DEBIAN_PACKAGE_NAME}_${CPACK_DEBIAN_PACKAGE_VERSION}-${CPACK_DEBIAN_PACKAGE_RELEASE}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb")
+        "${CPACK_DEBIAN_PACKAGE_NAME}_${CPACK_DEBIAN_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb")
     else()
       cmake_policy(PUSH)
         cmake_policy(SET CMP0010 NEW)

+ 17 - 0
Modules/CPackRPM.cmake

@@ -106,6 +106,16 @@
 #  group rpm package is generated without component suffix in filename and
 #  package name.
 #
+# .. variable:: CPACK_RPM_PACKAGE_EPOCH
+#
+#  The RPM package epoch
+#
+#  * Mandatory : No
+#  * Default   : -
+#
+#  Optional number that should be incremented when changing versioning schemas
+#  or fixing mistakes in the version numbers of older packages.
+#
 # .. variable:: CPACK_RPM_PACKAGE_VERSION
 #
 #  The RPM package version.
@@ -1891,11 +1901,16 @@ function(cpack_rpm_generate_package)
     OUTPUT_STRIP_TRAILING_WHITESPACE)
   string(REPLACE "\n" ";" RPMBUILD_TAG_LIST "${RPMBUILD_TAG_LIST}")
 
+  if(CPACK_RPM_PACKAGE_EPOCH)
+    set(TMP_RPM_EPOCH "Epoch: ${CPACK_RPM_PACKAGE_EPOCH}")
+  endif()
+
   # Check if additional fields for RPM spec header are given
   # There may be some COMPONENT specific variables as well
   # If component specific var is not provided we use the global one
   # for each component
   foreach(_RPM_SPEC_HEADER URL REQUIRES SUGGESTS PROVIDES OBSOLETES PREFIX CONFLICTS AUTOPROV AUTOREQ AUTOREQPROV REQUIRES_PRE REQUIRES_POST REQUIRES_PREUN REQUIRES_POSTUN)
+
     if(CPACK_RPM_PACKAGE_DEBUG)
       message("CPackRPM:Debug: processing ${_RPM_SPEC_HEADER}")
     endif()
@@ -2501,6 +2516,7 @@ Vendor:         \@CPACK_RPM_PACKAGE_VENDOR\@
 \@TMP_RPM_AUTOREQPROV\@
 \@TMP_RPM_BUILDARCH\@
 \@TMP_RPM_PREFIXES\@
+\@TMP_RPM_EPOCH\@
 
 %description -n \@CPACK_RPM_PACKAGE_NAME\@
 \@CPACK_RPM_PACKAGE_DESCRIPTION\@
@@ -2560,6 +2576,7 @@ Vendor:         \@CPACK_RPM_PACKAGE_VENDOR\@
 \@TMP_RPM_AUTOREQPROV\@
 \@TMP_RPM_BUILDARCH\@
 \@TMP_RPM_PREFIXES\@
+\@TMP_RPM_EPOCH\@
 
 \@TMP_RPM_DEBUGINFO\@
 

+ 1 - 1
Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend1.cmake

@@ -6,7 +6,7 @@ include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
 
 
 # expected results
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2_*.deb")
 set(expected_count 3)
 
 

+ 1 - 1
Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend2.cmake

@@ -6,7 +6,7 @@ include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
 
 
 # expected results
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2_*.deb")
 set(expected_count 3)
 
 set(config_verbose -V)

+ 1 - 1
Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description1.cmake

@@ -6,7 +6,7 @@ include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
 
 
 # expected results
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2_*.deb")
 set(expected_count 3)
 
 

+ 1 - 1
Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description2.cmake

@@ -7,7 +7,7 @@ include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
 
 
 # expected results
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2_*.deb")
 set(expected_count 3)
 
 

+ 1 - 1
Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake

@@ -5,7 +5,7 @@ endif()
 include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
 
 # TODO: currently debian doens't produce lower cased names
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2_*.deb")
 set(expected_count 3)
 
 

+ 1 - 1
Tests/CPackComponentsDEB/RunCPackVerifyResult-components-shlibdeps1.cmake

@@ -9,7 +9,7 @@ include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
 # requirements
 
 # debian now produces lower case names
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2_*.deb")
 set(expected_count 3)
 
 

+ 1 - 1
Tests/CPackComponentsDEB/RunCPackVerifyResult-components-source.cmake

@@ -6,7 +6,7 @@ include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
 
 
 # expected results
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2_*.deb")
 set(expected_count 3)
 
 set(config_verbose -V)

+ 1 - 1
Tests/CPackComponentsDEB/RunCPackVerifyResult-compression.cmake

@@ -5,7 +5,7 @@ endif()
 include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
 
 # TODO: currently debian doens't produce lower cased names
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib_1.0.2_*.deb")
 set(expected_count 1)
 
 set(actual_output)

+ 1 - 1
Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake

@@ -60,7 +60,7 @@ elseif (CPackGen MATCHES "RPM")
         set(expected_count 1)
     endif ()
 elseif (CPackGen MATCHES "DEB")
-    set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/mylib*_1.0.2-1_*.deb")
+    set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/mylib*_1.0.2_*.deb")
     if (${CPackComponentWay} STREQUAL "default")
         set(expected_count 1)
     elseif (${CPackComponentWay} STREQUAL "OnePackPerGroup")

+ 1 - 1
Tests/RunCMake/CPack/DEB/Helpers.cmake

@@ -23,7 +23,7 @@ function(getPackageNameGlobexpr NAME COMPONENT VERSION REVISION FILE_NO RESULT_V
   endif()
 
   if(GENERATOR_SPECIFIC_FORMAT)
-    set(${RESULT_VAR} "${NAME}${COMPONENT}_${VERSION}-${REVISION}_*.deb" PARENT_SCOPE)
+    set(${RESULT_VAR} "${NAME}${COMPONENT}_${VERSION}_*.deb" PARENT_SCOPE)
   else()
     set(${RESULT_VAR} "${NAME}-${VERSION}-*${COMPONENT}.deb" PARENT_SCOPE)
   endif()

+ 3 - 0
Tests/RunCMake/CPack/RPM/Helpers.cmake

@@ -23,6 +23,9 @@ function(getPackageNameGlobexpr NAME COMPONENT VERSION REVISION FILE_NO RESULT_V
   endif()
 
   if(GENERATOR_SPECIFIC_FORMAT)
+    if(NOT REVISION)
+      set(REVISION "1")
+    endif()
     set(${RESULT_VAR} "${NAME}${COMPONENT}-${VERSION}-${REVISION}.*.rpm" PARENT_SCOPE)
   else()
     set(${RESULT_VAR} "${NAME}-${VERSION}-*${COMPONENT}.rpm" PARENT_SCOPE)

+ 1 - 0
Tests/RunCMake/CPack/RunCMakeTest.cmake

@@ -10,6 +10,7 @@ run_cpack_test(DEBUGINFO "RPM" true "COMPONENT")
 run_cpack_test(DEPENDENCIES "RPM;DEB" true "COMPONENT")
 run_cpack_test(DIST "RPM" false "MONOLITHIC")
 run_cpack_test(EMPTY_DIR "RPM;DEB;TGZ" true "MONOLITHIC;COMPONENT")
+run_cpack_test(VERSION "RPM;DEB" false "MONOLITHIC;COMPONENT")
 run_cpack_test(EXTRA "DEB" false "COMPONENT")
 run_cpack_test(GENERATE_SHLIBS "DEB" true "COMPONENT")
 run_cpack_test(GENERATE_SHLIBS_LDCONFIG "DEB" true "COMPONENT")

+ 1 - 3
Tests/RunCMake/CPack/VerifyResult.cmake

@@ -8,9 +8,7 @@ function(findExpectedFile FILE_NO RESULT_VAR GLOBING_EXPR_VAR)
     endif()
     if(NOT DEFINED EXPECTED_FILE_${FILE_NO}_VERSION)
       set(EXPECTED_FILE_${FILE_NO}_VERSION "0.1.1")
-    endif()
-    if(NOT DEFINED EXPECTED_FILE_${FILE_NO}_REVISION)
-      set(EXPECTED_FILE_${FILE_NO}_REVISION "1")
+      set(EXPECTED_FILE_${FILE_NO}_VERSION "0.1.1" PARENT_SCOPE)
     endif()
 
     getPackageNameGlobexpr("${EXPECTED_FILE_${FILE_NO}_NAME}"

+ 3 - 0
Tests/RunCMake/CPack/tests/VERSION/ExpectedFiles.cmake

@@ -0,0 +1,3 @@
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_CONTENT_1_LIST "/usr;/usr/foo;/usr/foo/CMakeLists.txt")
+set(EXPECTED_FILE_1_REVISION "1")

+ 17 - 0
Tests/RunCMake/CPack/tests/VERSION/VerifyResult.cmake

@@ -0,0 +1,17 @@
+function(checkPackageInfo_ TYPE FILE REGEX)
+  getPackageInfo("${FILE}" "FILE_INFO_")
+  if(NOT FILE_INFO_ MATCHES "${REGEX}")
+    message(FATAL_ERROR "Unexpected ${TYPE} in '${FILE}' ${EXPECTED_FILE_1_VERSION} ${EXPECTED_FILE_1_REVISION}; file info: '${FILE_INFO_}'")
+  endif()
+endfunction()
+
+set(whitespaces_ "[\t\n\r ]*")
+
+if(GENERATOR_TYPE STREQUAL "RPM")
+  checkPackageInfo_("package version" "${FOUND_FILE_1}" "Version${whitespaces_}:${whitespaces_}${EXPECTED_FILE_1_VERSION}")
+  checkPackageInfo_("package revision" "${FOUND_FILE_1}" "Release${whitespaces_}:${whitespaces_}${EXPECTED_FILE_1_REVISION}")
+  checkPackageInfo_("epoch version" "${FOUND_FILE_1}" "Epoch${whitespaces_}:${whitespaces_}3")
+else() # DEB
+  checkPackageInfo_("version" "${FOUND_FILE_1}"
+    ".*Version${whitespaces_}:${whitespaces_}3:${EXPECTED_FILE_1_VERSION}-${EXPECTED_FILE_1_REVISION}")
+endif()

+ 14 - 0
Tests/RunCMake/CPack/tests/VERSION/test.cmake

@@ -0,0 +1,14 @@
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT test)
+
+if(GENERATOR_TYPE STREQUAL "DEB")
+  set(package_type_ "DEBIAN")
+  set(CPACK_DEBIAN_PACKAGE_RELEASE "1")
+else()
+  set(package_type_ "${GENERATOR_TYPE}")
+endif()
+
+set(CPACK_${package_type_}_PACKAGE_EPOCH "3")
+
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+  set(CPACK_COMPONENTS_ALL test)
+endif()