Skip to content

Commit

Permalink
Add function tribits_git_repo_sha1() (TriBITSPub#483)
Browse files Browse the repository at this point in the history
This will be a robust way to generate the CDash URLs that contain 'Revision'
for when the base git repos can't produce a SHA1.  And this is just a very
generally useful function.
  • Loading branch information
bartlettroscoe committed Jun 7, 2022
1 parent 22d618f commit 608570c
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 2 deletions.
2 changes: 1 addition & 1 deletion test/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down
53 changes: 52 additions & 1 deletion test/core/TestingFunctionMacro_UnitTests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ include(TribitsFilepathHelpers)
include(TribitsGetVersionDate)
include(TribitsTplFindIncludeDirsAndLibraries)
include(TribitsReportInvalidTribitsUsage)
include(TribitsGitRepoVersionInfo)
include(UnitTestHelpers)
include(GlobalSet)
include(GlobalNullSet)
Expand Down Expand Up @@ -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***")
Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -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)
68 changes: 68 additions & 0 deletions tribits/core/package_arch/TribitsGitRepoVersionInfo.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,74 @@
################################################################################


# @FUNCTION: tribits_git_repo_sha1()
#
# Get the Git repo version SHA1.
#
# Usage::
#
# tribits_git_repo_sha1(<gitRepoDir> <gitRepoSha1Out>
# FAILURE_MESSAGE_OUT <failureMsgOut>)
#
# If ``<failureMsgOut>`` is non-empty on input, then the variable
# ``<failureMsgOut>`` will be set to a non-empty value on output with the
# error message if an error occurs and the SHA1 for ``<gitRepoDir>`` can not
# be computed. If ``<failureMsgOut>`` is empty in input, and there is an
# error, a ``FATAL_ERROR`` will be raised.
#
# NOTE: To get the SHA1 for the Git repo ``<gitRepoDir>``, 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
Expand Down

0 comments on commit 608570c

Please sign in to comment.