diff --git a/cmake/GitCheckout.cmake b/cmake/GitCheckout.cmake index 9201c33..4969aa3 100644 --- a/cmake/GitCheckout.cmake +++ b/cmake/GitCheckout.cmake @@ -24,16 +24,38 @@ endmacro() # # Arguments: # - URL: The URL of the remote Git repository. +# +# Optional arguments: +# - REF: The reference (branch, tag, or commit) to check out the Git repository. function(git_checkout URL) - cmake_parse_arguments(ARG "" "ERROR_VARIABLE" "" ${ARGN}) + cmake_parse_arguments(ARG "" "REF;ERROR_VARIABLE" "" ${ARGN}) + + # Clones the Git repository. execute_process( COMMAND git clone ${URL} RESULT_VARIABLE RES ) if(NOT RES EQUAL 0) _set_error( - "Failed to clone ${URL} (${RES})" + "Failed to clone '${URL}' (${RES})" ERROR_VARIABLE ${ARG_ERROR_VARIABLE} ) endif() + + # Determines the directory of the cloned Git repository. + string(REGEX REPLACE ".*/" "" GIT_DIR ${URL}) + + if(ARG_REF) + # Checks out the Git repository to a specific reference. + execute_process( + COMMAND git -C ${GIT_DIR} checkout ${ARG_REF} + RESULT_VARIABLE RES + ) + if(NOT RES EQUAL 0) + _set_error( + "Failed to check out '${GIT_DIR}' to '${ARG_REF}' (${RES})" + ERROR_VARIABLE ${ARG_ERROR_VARIABLE} + ) + endif() + endif() endfunction() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e8cc45d..e19905a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -14,6 +14,8 @@ add_cmake_test( GitCheckoutTest.cmake "Check out a Git repository" "Check out an invalid Git repository" + "Check out a Git repository on a specific ref" + "Check out a Git repository on a specific invalid ref" ) add_cmake_test( diff --git a/test/GitCheckoutTest.cmake b/test/GitCheckoutTest.cmake index c278982..b46218d 100644 --- a/test/GitCheckoutTest.cmake +++ b/test/GitCheckoutTest.cmake @@ -29,7 +29,51 @@ if("Check out an invalid Git repository" MATCHES ${TEST_MATCHES}) ERROR_VARIABLE ERR ) - set(EXPECTED_ERR "Failed to clone https://github.com/threeal/invalid-project (128)") + set(EXPECTED_ERR "Failed to clone 'https://github.com/threeal/invalid-project' (128)") + if(NOT ${ERR} STREQUAL EXPECTED_ERR) + message(FATAL_ERROR "It should fail to check out because of '${EXPECTED_ERR}' but instead got '${ERR}'") + endif() +endif() + +if("Check out a Git repository on a specific ref" MATCHES ${TEST_MATCHES}) + math(EXPR TEST_COUNT "${TEST_COUNT} + 1") + + if(EXISTS project-starter) + file(REMOVE_RECURSE project-starter) + endif() + + include(GitCheckout) + git_checkout(https://github.com/threeal/project-starter REF 5a80d20) + + if(NOT EXISTS project-starter) + message(FATAL_ERROR "The 'project-starter' directory should exist") + endif() + + execute_process( + COMMAND git -C project-starter rev-parse --short HEAD + OUTPUT_VARIABLE COMMIT_SHA + ) + string(STRIP ${COMMIT_SHA} COMMIT_SHA) + if(NOT COMMIT_SHA STREQUAL 5a80d20) + message(FATAL_ERROR "The commit SHA should be '5a80d20' but instead got '${COMMIT_SHA}'") + endif() +endif() + +if("Check out a Git repository on a specific invalid ref" MATCHES ${TEST_MATCHES}) + math(EXPR TEST_COUNT "${TEST_COUNT} + 1") + + if(EXISTS project-starter) + file(REMOVE_RECURSE project-starter) + endif() + + include(GitCheckout) + git_checkout( + https://github.com/threeal/project-starter + REF invalid-ref + ERROR_VARIABLE ERR + ) + + set(EXPECTED_ERR "Failed to check out 'project-starter' to 'invalid-ref' (1)") if(NOT ${ERR} STREQUAL EXPECTED_ERR) message(FATAL_ERROR "It should fail to check out because of '${EXPECTED_ERR}' but instead got '${ERR}'") endif()