From 26be1b4d89c1697f6fb17e52f0e8158472d739cc Mon Sep 17 00:00:00 2001 From: d-e-e-p Date: Sat, 15 Apr 2023 00:10:26 -0700 Subject: [PATCH] If version is specified as latest, look for last version tagged in repository, eg: CPMAddPackage( NAME fibonacci GIT_REPOSITORY https://github.com/cpm-cmake/testpack-fibonacci.git VERSION latest ) --- cmake/CPM.cmake | 38 +++++++++++++++++++--- test/unit/tag_when_version_is_latest.cmake | 38 ++++++++++++++++++++++ test/unit/version_latest/.gitignore | 1 + test/unit/version_latest/CMakeLists.txt.in | 33 +++++++++++++++++++ test/unit/version_latest/main.cpp | 10 ++++++ 5 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 test/unit/tag_when_version_is_latest.cmake create mode 100644 test/unit/version_latest/.gitignore create mode 100644 test/unit/version_latest/CMakeLists.txt.in create mode 100644 test/unit/version_latest/main.cpp diff --git a/cmake/CPM.cmake b/cmake/CPM.cmake index 92953b8c..2e8fafd3 100644 --- a/cmake/CPM.cmake +++ b/cmake/CPM.cmake @@ -178,6 +178,26 @@ if(NOT CPM_DONT_CREATE_PACKAGE_LOCK) ) endif() +# look for string in TAG like "latest" or "master" +function(cpm_fetch_git_tag_from_version_description URI RESULT) + find_package(Git REQUIRED) + if(NOT GIT_EXECUTABLE) + return() + endif() + + # TODO: if not tag exists in rep, revert to last checkin + # TODO: make it work for case of multuple URI + # TODO: replace tail and sed with string functions so we don't have to call bash + set(CMD "${GIT_EXECUTABLE} ls-remote --refs --heads --tags --sort=v:refname ${URI} | tail -1 | sed 's:.*refs/tags/::' " ) + execute_process( + COMMAND bash "-c" ${CMD} + OUTPUT_VARIABLE OUT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + message("found latest tag: ${OUT} from ${URI}") + set(${RESULT} ${OUT} PARENT_SCOPE) +endfunction() + include(FetchContent) # Try to infer package name from git repository uri (path or url) @@ -543,11 +563,6 @@ function(CPMAddPackage) # Set default values for arguments - if(NOT DEFINED CPM_ARGS_VERSION) - if(DEFINED CPM_ARGS_GIT_TAG) - cpm_get_version_from_git_tag("${CPM_ARGS_GIT_TAG}" CPM_ARGS_VERSION) - endif() - endif() if(CPM_ARGS_DOWNLOAD_ONLY) set(DOWNLOAD_ONLY ${CPM_ARGS_DOWNLOAD_ONLY}) @@ -577,6 +592,19 @@ function(CPMAddPackage) set(CPM_SKIP_FETCH FALSE) + # if "latest" version is specified, look at repository for last tagged version + if(DEFINED CPM_ARGS_GIT_REPOSITORY AND DEFINED CPM_ARGS_VERSION) + if(${CPM_ARGS_VERSION} MATCHES "^latest$") + cpm_fetch_git_tag_from_version_description(${CPM_ARGS_GIT_REPOSITORY} CPM_ARGS_GIT_TAG) + endif() + endif() + + if(NOT DEFINED CPM_ARGS_VERSION) + if(DEFINED CPM_ARGS_GIT_TAG) + cpm_get_version_from_git_tag("${CPM_ARGS_GIT_TAG}" CPM_ARGS_VERSION) + endif() + endif() + if(DEFINED CPM_ARGS_GIT_TAG) list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS GIT_TAG ${CPM_ARGS_GIT_TAG}) # If GIT_SHALLOW is explicitly specified, honor the value. diff --git a/test/unit/tag_when_version_is_latest.cmake b/test/unit/tag_when_version_is_latest.cmake new file mode 100644 index 00000000..01baf932 --- /dev/null +++ b/test/unit/tag_when_version_is_latest.cmake @@ -0,0 +1,38 @@ +cmake_minimum_required(VERSION 3.14 FATAL_ERROR) + +include(${CPM_PATH}/testing.cmake) +include(CMakePackageConfigHelpers) + +set(CPM_SOURCE_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/CPM") +set(TEST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/version_latest) + +function(clear_cache) + message(STATUS "clearing CPM cache") + file(REMOVE_RECURSE ${CPM_SOURCE_CACHE_DIR}) + assert_not_exists("${CPM_SOURCE_CACHE_DIR}") +endfunction() + +function(update_cmake_lists) + configure_package_config_file( + "${CMAKE_CURRENT_LIST_DIR}/version_latest/CMakeLists.txt.in" + "${CMAKE_CURRENT_LIST_DIR}/version_latest/CMakeLists.txt" + INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/junk + ) +endfunction() + +function(reset_test) + clear_cache() + file(REMOVE_RECURSE ${TEST_BUILD_DIR}) + update_cmake_lists() +endfunction() + +# Read CPM_SOURCE_CACHE from arguments + +reset_test() + +execute_process( + COMMAND ${CMAKE_COMMAND} "-S${CMAKE_CURRENT_LIST_DIR}/version_latest" + "-B${TEST_BUILD_DIR}" "-DCPM_SOURCE_CACHE=${CPM_SOURCE_CACHE_DIR}" RESULT_VARIABLE ret +) + +assert_equal(${ret} "0") diff --git a/test/unit/version_latest/.gitignore b/test/unit/version_latest/.gitignore new file mode 100644 index 00000000..96730bdd --- /dev/null +++ b/test/unit/version_latest/.gitignore @@ -0,0 +1 @@ +/CMakeLists.txt \ No newline at end of file diff --git a/test/unit/version_latest/CMakeLists.txt.in b/test/unit/version_latest/CMakeLists.txt.in new file mode 100644 index 00000000..05f4b1a5 --- /dev/null +++ b/test/unit/version_latest/CMakeLists.txt.in @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.14 FATAL_ERROR) + +project(CPMExampleCatch2) + +# ---- Options ---- + +option(ENABLE_TEST_COVERAGE "Enable test coverage" OFF) + +# ---- Dependencies ---- + +include(@CPM_PATH@/CPM.cmake) + +CPMAddPackage( + NAME fibonacci + GIT_REPOSITORY https://github.com/cpm-cmake/testpack-fibonacci.git + VERSION latest +) + + +# ---- Create binary ---- + +add_executable(CPMExampleCatch2 main.cpp) +target_link_libraries(CPMExampleCatch2 fibonacci) +set_target_properties(CPMExampleCatch2 PROPERTIES CXX_STANDARD 17 COMPILE_FLAGS "-Wall -pedantic -Wextra -Werror") + +# ---- Check parameters ---- + +include(@CPM_PATH@/testing.cmake) + +ASSERT_TRUTHY(fibonacci_ADDED) +ASSERT_DEFINED(fibonacci_SOURCE_DIR) +ASSERT_DEFINED(fibonacci_BINARY_DIR) +ASSERT_EQUAL("${CPM_LAST_PACKAGE_NAME}" "fibonacci") diff --git a/test/unit/version_latest/main.cpp b/test/unit/version_latest/main.cpp new file mode 100644 index 00000000..0299b57a --- /dev/null +++ b/test/unit/version_latest/main.cpp @@ -0,0 +1,10 @@ +#define CATCH_CONFIG_MAIN + +#include + +#include + +int main() { + std::cout << "fib(10) = " << fastFibonacci(10) << std::endl; + return 0; +}