diff --git a/test/core/CMakeLists.txt b/test/core/CMakeLists.txt index 87446c066..1e040b7c2 100644 --- a/test/core/CMakeLists.txt +++ b/test/core/CMakeLists.txt @@ -49,7 +49,7 @@ tribits_add_advanced_test( TestingFunctionMacro_UnitTests -D${PROJECT_NAME}_TRIBITS_DIR=${${PROJECT_NAME}_TRIBITS_DIR} -P "${CMAKE_CURRENT_SOURCE_DIR}/TestingFunctionMacro_UnitTests.cmake" PASS_REGULAR_EXPRESSION_ALL - "Final UnitTests Result: num_run = 695" + "Final UnitTests Result: num_run = 702" "Final UnitTests Result: PASSED" ) diff --git a/test/core/TestingFunctionMacro_UnitTests.cmake b/test/core/TestingFunctionMacro_UnitTests.cmake index 45f7bb6a7..7eff5ed75 100644 --- a/test/core/TestingFunctionMacro_UnitTests.cmake +++ b/test/core/TestingFunctionMacro_UnitTests.cmake @@ -60,6 +60,7 @@ include(TribitsFilepathHelpers) include(TribitsGetVersionDate) include(TribitsTplFindIncludeDirsAndLibraries) include(TribitsReportInvalidTribitsUsage) +include(TribitsGitRepoVersionInfo) include(UnitTestHelpers) include(GlobalSet) include(GlobalNullSet) @@ -487,6 +488,55 @@ function(unittest_tribits_get_version_date_from_raw_git_commit_utc_time) endfunction() +function(unittest_tribits_git_repo_sha1) + + message("\n***") + message("*** Testing tribits_git_repo_sha1()") + message("***\n") + + find_program(GIT_EXECUTABLE ${GIT_NAME}) + + set(tribitsProjDir "${${PROJECT_NAME}_TRIBITS_DIR}/..") + + # Matches any 40-char SHA1 + set(anySha1Regex "") + foreach(i RANGE 0 39) + string(APPEND anySha1Regex "[a-z0-9]") + endforeach() + + if (IS_DIRECTORY "${tribitsProjDir}/.git") + + message("Testing tribits_git_repo_sha1() with the base TriBITS project (without FAILURE_MESSAGE_OUT)\n") + tribits_git_repo_sha1("${tribitsProjDir}" gitRepoSha1) + unittest_string_var_regex(gitRepoSha1 REGEX_STRINGS "${anySha1Regex}") + + message("Testing tribits_git_repo_sha1() with the base TriBITS project (with FAILURE_MESSAGE_OUT)\n") + tribits_git_repo_sha1("${tribitsProjDir}" gitRepoSha1 + FAILURE_MESSAGE_OUT failureMsg) + unittest_string_var_regex(gitRepoSha1 REGEX_STRINGS "${anySha1Regex}") + unittest_compare_const(failureMsg "") + + endif() + + message("Testing tribits_git_repo_sha1(): No GIT_EXECUTABLE (with FAILURE_MESSAGE_OUT)\n") + set(GIT_EXECUTABLE_SAVED "${GIT_EXECUTABLE}") + set(GIT_EXECUTABLE "") + tribits_git_repo_sha1("${tribitsProjDir}" gitRepoSha1 + FAILURE_MESSAGE_OUT failureMsg) + unittest_compare_const(gitRepoSha1 "") + unittest_compare_const(failureMsg "ERROR: The program 'git' could not be found!") + set(GIT_EXECUTABLE "${GIT_EXECUTABLE_SAVED}") + unset(GIT_EXECUTABLE_SAVED) + + message("Testing tribits_git_repo_sha1(): Invalid repo dir (with FAILURE_MESSAGE_OUT)\n") + tribits_git_repo_sha1("/repo/does/not/exist" gitRepoSha1 + FAILURE_MESSAGE_OUT failureMsg) + unittest_compare_const(gitRepoSha1 "") + unittest_compare_const(failureMsg "ERROR: The directory /repo/does/not/exist/.git does not exist!") + +endfunction() + + function(unittest_tribits_tpl_allow_pre_find_package) message("\n***") @@ -4520,6 +4570,7 @@ unittest_tribits_misc() unittest_tribits_strip_quotes_from_str() unittest_tribits_get_version_date_from_raw_git_commit_utc_time() unittest_tribits_get_raw_git_commit_utc_time() +unittest_tribits_git_repo_sha1() unittest_tribits_tpl_allow_pre_find_package() unittest_tribits_report_invalid_tribits_usage() @@ -4576,4 +4627,4 @@ message("*** Determine final result of all unit tests") message("***\n") # Pass in the number of expected tests that must pass! -unittest_final_result(695) +unittest_final_result(702) diff --git a/tribits/core/package_arch/TribitsGitRepoVersionInfo.cmake b/tribits/core/package_arch/TribitsGitRepoVersionInfo.cmake index e2eedaab0..9d4943dc8 100644 --- a/tribits/core/package_arch/TribitsGitRepoVersionInfo.cmake +++ b/tribits/core/package_arch/TribitsGitRepoVersionInfo.cmake @@ -44,6 +44,74 @@ ################################################################################ +# @FUNCTION: tribits_git_repo_sha1() +# +# Get the Git repo version SHA1. +# +# Usage:: +# +# tribits_git_repo_sha1( +# FAILURE_MESSAGE_OUT ) +# +# If ```` is non-empty on input, then the variable +# ```` will be set to a non-empty value on output with the +# error message if an error occurs and the SHA1 for ```` can not +# be computed. If ```` is empty in input, and there is an +# error, a ``FATAL_ERROR`` will be raised. +# +# NOTE: To get the SHA1 for the Git repo ````, it must contain the +# ``.git/`` directory and the ``git`` executable var ``GIT_EXECUTABLE`` must +# be set. Otherwise, it is an error. +# +function(tribits_git_repo_sha1 gitRepoDir gitRepoSha1Out) + + cmake_parse_arguments( PARSE_ARGV 2 + PARSE "" "" # prefix, options, one_value_keywords + "FAILURE_MESSAGE_OUT" # multi_value_keywords + ) + tribits_check_for_unparsed_arguments() + tribits_assert_parse_arg_zero_or_one_value(PARSE FAILURE_MESSAGE_OUT) + + set(failureMsg "") + + if (NOT GIT_EXECUTABLE) + set(failureMsg "ERROR: The program '${GIT_NAME}' could not be found!") + elseif (NOT IS_DIRECTORY "${gitRepoDir}/.git") + set(failureMsg "ERROR: The directory ${gitRepoDir}/.git does not exist!") + endif() + + set(gitRepoSha1 "") + if (failureMsg STREQUAL "") + execute_process( + COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:"%H" + WORKING_DIRECTORY ${gitRepoDir} + RESULT_VARIABLE gitCmndRtn OUTPUT_VARIABLE gitCmndOutput + ) + # NOTE: Above we have to add quotes '"' or CMake will not accept the + # command. However, git will put those quotes in the output so we have to + # strip them out below! + + if (NOT gitCmndRtn STREQUAL 0) + set(failureMsg "ERROR: ${GIT_EXECUTABLE} command returned ${gitCmndRtn}!=0 for repo ${gitRepoDir}!") + else() + # Strip the quotes off :-( + string(LENGTH "${gitCmndOutput}" gitCmndOutputLen) + math(EXPR outputNumCharsToKeep "${gitCmndOutputLen}-2") + string(SUBSTRING "${gitCmndOutput}" 1 ${outputNumCharsToKeep} gitRepoSha1) + endif() + endif() + # ToDo: Factor above out into its own function! + + if (NOT failureMsg STREQUAL "" AND PARSE_FAILURE_MESSAGE_OUT STREQUAL "") + message(FATAL_ERROR "${failureMsg}") + elseif (PARSE_FAILURE_MESSAGE_OUT) + set(${PARSE_FAILURE_MESSAGE_OUT} "${failureMsg}" PARENT_SCOPE) + endif() + set(${gitRepoSha1Out} "${gitRepoSha1}" PARENT_SCOPE) + +endfunction() + + # Run the git log command to get the version info for a git repo # function(tribits_generate_single_repo_version_string gitRepoDir