From d0758290e78046ac0d8cf91e3456369cc4c43999 Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Fri, 8 Jun 2012 18:29:34 -0400 Subject: [PATCH 1/7] ExternalProject: Only run 'git fetch' when required. In the current default update step for Git under the ExternalProject_Add command, a 'git fetch' is always performed, followed by a 'git checkout' and 'git submodule update --recursive'. However, a 'git fetch' can be time consuming and requires a network connection. To save time, we look at the current checked out hash, and only perform the fetch if required. This is performed in a CMake script so we can handle the conditional logic in a cross platform manner. --- Modules/ExternalProject.cmake | 70 ++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 5 deletions(-) diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 8d578607e..7a8aa5ff9 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -402,6 +402,66 @@ endif() endfunction() +function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_repository work_dir) + file(WRITE ${script_filename} +"if(\"${git_tag}\" STREQUAL \"\") + message(FATAL_ERROR \"Tag for git checkout should not be empty.\") +endif() + +execute_process( + COMMAND \"${git_EXECUTABLE}\" rev-list --max-count=1 HEAD + WORKING_DIRECTORY \"${work_dir}\" + RESULT_VARIABLE error_code + OUTPUT_VARIABLE head_sha + ) +if(error_code) + message(FATAL_ERROR \"Failed to get the hash for HEAD\") +endif() + +# This will fail if the tag does not exist (it probably has not been fetched +# yet). +execute_process( + COMMAND \"${git_EXECUTABLE}\" rev-list --max-count=1 ${git_tag} + WORKING_DIRECTORY \"${work_dir}\" + RESULT_VARIABLE error_code + OUTPUT_VARIABLE tag_sha + ) + +# Is the hash checkout out that we want? +if(error_code OR NOT (\"\${tag_sha}\" STREQUAL \"\${head_sha}\")) + execute_process( + COMMAND \"${git_EXECUTABLE}\" fetch + WORKING_DIRECTORY \"${work_dir}\" + RESULT_VARIABLE error_code + ) + if(error_code) + message(FATAL_ERROR \"Failed to fetch repository '${git_repository}'\") + endif() + + execute_process( + COMMAND \"${git_EXECUTABLE}\" checkout ${git_tag} + WORKING_DIRECTORY \"${work_dir}\" + RESULT_VARIABLE error_code + ) + if(error_code) + message(FATAL_ERROR \"Failed to checkout tag: '${git_tag}'\") + endif() + + execute_process( + COMMAND \"${git_EXECUTABLE}\" submodule update --recursive + WORKING_DIRECTORY \"${work_dir}/${src_name}\" + RESULT_VARIABLE error_code + ) + if(error_code) + message(FATAL_ERROR \"Failed to update submodules in: '${work_dir}/${src_name}'\") + endif() +endif() + +" +) + +endfunction(_ep_write_gitupdate_script) + function(_ep_write_downloadfile_script script_filename remote local timeout hash tls_verify tls_cainfo) if(timeout) set(timeout_args TIMEOUT ${timeout}) @@ -1354,7 +1414,7 @@ endfunction() function(_ep_add_update_command name) - ExternalProject_Get_Property(${name} source_dir) + ExternalProject_Get_Property(${name} source_dir tmp_dir) get_property(cmd_set TARGET ${name} PROPERTY _EP_UPDATE_COMMAND SET) get_property(cmd TARGET ${name} PROPERTY _EP_UPDATE_COMMAND) @@ -1406,15 +1466,15 @@ function(_ep_add_update_command name) message(FATAL_ERROR "error: could not find git for fetch of ${name}") endif() set(work_dir ${source_dir}) - set(comment "Performing update step (git fetch) for '${name}'") + set(comment "Performing update step for '${name}'") get_property(git_tag TARGET ${name} PROPERTY _EP_GIT_TAG) if(NOT git_tag) set(git_tag "master") endif() - set(cmd ${GIT_EXECUTABLE} fetch - COMMAND ${GIT_EXECUTABLE} checkout ${git_tag} - COMMAND ${GIT_EXECUTABLE} submodule update --recursive + _ep_write_gitupdate_script(${tmp_dir}/${name}-gitupdate.cmake + ${GIT_EXECUTABLE} ${git_tag} ${git_repository} ${work_dir} ) + set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitupdate.cmake) set(always 1) elseif(hg_repository) if(NOT HG_EXECUTABLE) From 378aa127b4f335af77ddfe132e03343d8709c148 Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Thu, 26 Jul 2012 18:24:41 +0000 Subject: [PATCH 2/7] ExternalProject: Do smoke tests for Git Tutorial builds. --- Tests/ExternalProject/CMakeLists.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt index 3f8e8273d..e24a979c5 100644 --- a/Tests/ExternalProject/CMakeLists.txt +++ b/Tests/ExternalProject/CMakeLists.txt @@ -638,6 +638,17 @@ if(do_svn_tests) "${binary_base}/TutorialStep1-SVN-trunk/Tutorial" 98) endif() +if(do_git_tests) + add_test(TutorialStep1-GIT-byhash + "${binary_base}/TutorialStep1-GIT-byhash/Tutorial" 100) + + add_test(TutorialStep1-GIT-bytag + "${binary_base}/TutorialStep1-GIT-bytag/Tutorial" 99) + + add_test(TutorialStep1-GIT-master + "${binary_base}/TutorialStep1-GIT-master/Tutorial" 98) +endif() + # InstallTree tests: # From 2619f4d87a0080cbe6e739529913bf28c0d93d12 Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Fri, 27 Jul 2012 16:26:28 +0000 Subject: [PATCH 3/7] ExternalProject: Add tests for UPDATE_COMMAND. Tests are added for UPDATE_COMMAND to ensure it is working properly. Testing infrastructure is added along with tests for Git, but tests for other version control systems could easily be added in the future. --- Tests/CMakeLists.txt | 14 +++ Tests/ExternalProjectUpdate/CMakeLists.txt | 94 ++++++++++++++++++ .../ExternalProjectUpdateTest.cmake | 58 +++++++++++ Tests/ExternalProjectUpdate/gitrepo.tgz | Bin 0 -> 3057 bytes 4 files changed, 166 insertions(+) create mode 100644 Tests/ExternalProjectUpdate/CMakeLists.txt create mode 100644 Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake create mode 100644 Tests/ExternalProjectUpdate/gitrepo.tgz diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index b404333b8..311a6d8c9 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -982,6 +982,20 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ set_tests_properties(ExternalProject PROPERTIES TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT}) + add_test(ExternalProjectUpdate ${CMAKE_CMAKE_COMMAND} + -DExternalProjectUpdate_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate + -DExternalProjectUpdate_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate + -DCMAKE_TEST_GENERATOR=${CMAKE_TEST_GENERATOR} + -DCMAKE_TEST_MAKEPROGRAM=${CMAKE_TEST_MAKEPROGRAM} + -DCMAKE_CTEST_COMMAND=${CMAKE_CTEST_COMMAND} + -P ${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake + ) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate") + set_tests_properties(ExternalProjectUpdate PROPERTIES + TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT} + WORKING_DIRECTORY ${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate + ) + # do each of the tutorial steps foreach(STP RANGE 1 7) add_test(TutorialStep${STP} ${CMAKE_CTEST_COMMAND} diff --git a/Tests/ExternalProjectUpdate/CMakeLists.txt b/Tests/ExternalProjectUpdate/CMakeLists.txt new file mode 100644 index 000000000..cb3a94e54 --- /dev/null +++ b/Tests/ExternalProjectUpdate/CMakeLists.txt @@ -0,0 +1,94 @@ +cmake_minimum_required(VERSION 2.8) +project(ExternalProjectUpdateTest NONE) + +include(ExternalProject) + +find_package(Git) + +option(ExternalProjectUpdateTest_USE_FOLDERS "Enable folder grouping in IDEs." ON) +if(ExternalProjectUpdateTest_USE_FOLDERS) + set_property(GLOBAL PROPERTY USE_FOLDERS ON) +else() + set_property(GLOBAL PROPERTY USE_FOLDERS OFF) +endif() + +set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER + "CMakePredefinedTargets-in-ExternalProjectUpdateTest") + +set(base "${CMAKE_BINARY_DIR}/CMakeExternals") +set(binary_base "${base}/Build") +set_property(DIRECTORY PROPERTY EP_BASE ${base}) +set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test) + +set(do_git_tests 0) + +if(GIT_EXECUTABLE) + set(do_git_tests 1) + + execute_process( + COMMAND "${GIT_EXECUTABLE}" --version + OUTPUT_VARIABLE ov + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + string(REGEX REPLACE "^git version (.+)$" "\\1" git_version "${ov}") + message(STATUS "git_version='${git_version}'") + + if(git_version VERSION_LESS 1.6.5) + message(STATUS "No ExternalProject git tests with git client less than version 1.6.5") + set(do_git_tests 0) + endif() +endif() + +# This should be specified from the command line. +if(NOT TEST_GIT_TAG) + message(FATAL_ERROR "TEST_GIT_TAG must be specified.") +endif() + +if(do_git_tests) + set(local_git_repo "../../LocalRepositories/GIT") + + # Unzip/untar the git repository in our source folder so that other + # projects below may use it to test git args of ExternalProject_Add + # + set(proj SetupLocalGITRepository) + ExternalProject_Add(${proj} + SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/LocalRepositories/GIT + URL ${CMAKE_CURRENT_SOURCE_DIR}/gitrepo.tgz + BUILD_COMMAND "" + CONFIGURE_COMMAND "${GIT_EXECUTABLE}" --version + INSTALL_COMMAND "" + ) + set_property(TARGET ${proj} + PROPERTY FOLDER "SetupRepos/Local/Deeply/Nested/For/Testing") + + set(proj TutorialStep1-GIT) + ExternalProject_Add(${proj} + GIT_REPOSITORY "${local_git_repo}" + GIT_TAG ${TEST_GIT_TAG} + CMAKE_GENERATOR "${CMAKE_GENERATOR}" + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= + INSTALL_COMMAND "" + DEPENDS "SetupLocalGITRepository" + ) + set_property(TARGET ${proj} PROPERTY FOLDER "GIT") +endif() + + +# Test the testable built/installed products: +# +enable_testing() + + +# Do at least a smoke test of a built executable from each +# project's build directory... +# +# BuildTree tests: +# + +if(do_git_tests) + add_test(TutorialStep1-GIT + "${binary_base}/TutorialStep1-GIT/Tutorial" 81) +endif() + +message(STATUS "do_git_tests='${do_git_tests}'") +message(STATUS "GIT_EXECUTABLE='${GIT_EXECUTABLE}'") diff --git a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake new file mode 100644 index 000000000..fed40ef49 --- /dev/null +++ b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake @@ -0,0 +1,58 @@ +# Set the ExternalProject GIT_TAG to desired_tag, and make sure the +# resulting checked out version is resulting_sha and a rebuild. +# This check's the viability of the ExternalProject UPDATE_COMMAND. +macro(check_a_tag desired_tag resulting_sha) + # Configure + execute_process(COMMAND ${CMAKE_COMMAND} + -G ${CMAKE_TEST_GENERATOR} + -DTEST_GIT_TAG:STRING=${desired_tag} + ${ExternalProjectUpdate_SOURCE_DIR} + WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR} + RESULT_VARIABLE error_code + ) + if(error_code) + message(FATAL_ERROR "Could not configure the project.") + endif() + + # Build + execute_process(COMMAND ${CMAKE_COMMAND} + --build ${ExternalProjectUpdate_BINARY_DIR} + RESULT_VARIABLE error_code + ) + if(error_code) + message(FATAL_ERROR "Could not build the project.") + endif() + + # Check the resulting SHA + execute_process(COMMAND ${GIT_EXECUTABLE} + rev-list --max-count=1 HEAD + WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT + RESULT_VARIABLE error_code + OUTPUT_VARIABLE tag_sha + ) + if(error_code) + message(FATAL_ERROR "Could not check the sha.") + endif() + + string(STRIP "${tag_sha}" tag_sha) + if(NOT (${tag_sha} STREQUAL ${resulting_sha})) + message(FATAL_ERROR "UPDATE_COMMAND produced + ${tag_sha} +when + ${resulting_sha} +was expected." + ) + endif() +endmacro() + +find_package(Git) +if(GIT_EXECUTABLE) + check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7) + check_a_tag(tag1 d1970730310fe8bc07e73f15dc570071f9f9654a) + # With the Git UPDATE_COMMAND performance patch, this will not required a + # 'git fetch' + check_a_tag(tag1 d1970730310fe8bc07e73f15dc570071f9f9654a) + check_a_tag(tag2 5842b503ba4113976d9bb28d57b5aee1ad2736b7) + check_a_tag(d19707303 d1970730310fe8bc07e73f15dc570071f9f9654a) + check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7) +endif() diff --git a/Tests/ExternalProjectUpdate/gitrepo.tgz b/Tests/ExternalProjectUpdate/gitrepo.tgz new file mode 100644 index 0000000000000000000000000000000000000000..87090ab0be8d0a68c67896ba362fccc0ee357b36 GIT binary patch literal 3057 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 literal 0 HcmV?d00001 From 9b66c8faf5a2c0d482c5565056ce844b7b4570ad Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Fri, 27 Jul 2012 17:38:01 +0000 Subject: [PATCH 4/7] ExternalProject: Always do a git fetch for a remote ref. Remote git refs always require a git fetch, because the remote may move around where the ref points. --- Modules/ExternalProject.cmake | 15 ++++++++++++++- .../ExternalProjectUpdateTest.cmake | 4 +++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 7a8aa5ff9..2355dac47 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -418,6 +418,19 @@ if(error_code) message(FATAL_ERROR \"Failed to get the hash for HEAD\") endif() +execute_process( + COMMAND \"${git_EXECUTABLE}\" show-ref ${git_tag} + WORKING_DIRECTORY \"${work_dir}\" + OUTPUT_VARIABLE show_ref_output + ) +# If a remote ref is asked for, which can possibly move around, +# we must always do a fetch and checkout. +if(\"\${show_ref_output}\" MATCHES \"remotes\") + set(is_remote_ref 1) +else() + set(is_remote_ref 0) +endif() + # This will fail if the tag does not exist (it probably has not been fetched # yet). execute_process( @@ -428,7 +441,7 @@ execute_process( ) # Is the hash checkout out that we want? -if(error_code OR NOT (\"\${tag_sha}\" STREQUAL \"\${head_sha}\")) +if(error_code OR is_remote_ref OR NOT (\"\${tag_sha}\" STREQUAL \"\${head_sha}\")) execute_process( COMMAND \"${git_EXECUTABLE}\" fetch WORKING_DIRECTORY \"${work_dir}\" diff --git a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake index fed40ef49..0f9a99901 100644 --- a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake +++ b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake @@ -29,12 +29,12 @@ macro(check_a_tag desired_tag resulting_sha) WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT RESULT_VARIABLE error_code OUTPUT_VARIABLE tag_sha + OUTPUT_STRIP_TRAILING_WHITESPACE ) if(error_code) message(FATAL_ERROR "Could not check the sha.") endif() - string(STRIP "${tag_sha}" tag_sha) if(NOT (${tag_sha} STREQUAL ${resulting_sha})) message(FATAL_ERROR "UPDATE_COMMAND produced ${tag_sha} @@ -55,4 +55,6 @@ if(GIT_EXECUTABLE) check_a_tag(tag2 5842b503ba4113976d9bb28d57b5aee1ad2736b7) check_a_tag(d19707303 d1970730310fe8bc07e73f15dc570071f9f9654a) check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7) + # This is a remote symbolic ref, so it will always trigger a 'git fetch' + check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7) endif() From 0a34433dfbd001c5144a2a5889a35a98579f9760 Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Thu, 1 Nov 2012 15:50:58 +0000 Subject: [PATCH 5/7] ExternalProject: Make sure the ExternalProjectUpdate setup is available. This prepares the numberous tests that occur in the ExternalProjectUpdate test. The tests were passing previously because a fresh build was not performed. --- Tests/CMakeLists.txt | 20 ++++++++++++++++++-- Tests/ExternalProjectUpdate/CMakeLists.txt | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 311a6d8c9..c394fc62f 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -982,7 +982,23 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ set_tests_properties(ExternalProject PROPERTIES TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT}) - add_test(ExternalProjectUpdate ${CMAKE_CMAKE_COMMAND} + add_test(ExternalProjectUpdateSetup ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate" + "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate" + --build-generator ${CMAKE_TEST_GENERATOR} + --build-project ExternalProjectUpdateTest + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate" + --force-new-ctest-process + --test-command ${CMAKE_CTEST_COMMAND} -V + ) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate") + set_tests_properties(ExternalProjectUpdateSetup PROPERTIES + TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT}) + + add_test(NAME ExternalProjectUpdate + COMMAND ${CMAKE_CMAKE_COMMAND} -DExternalProjectUpdate_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate -DExternalProjectUpdate_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate -DCMAKE_TEST_GENERATOR=${CMAKE_TEST_GENERATOR} @@ -994,7 +1010,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ set_tests_properties(ExternalProjectUpdate PROPERTIES TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT} WORKING_DIRECTORY ${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate - ) + DEPENDS ExternalProjectUpdateSetup ) # do each of the tutorial steps foreach(STP RANGE 1 7) diff --git a/Tests/ExternalProjectUpdate/CMakeLists.txt b/Tests/ExternalProjectUpdate/CMakeLists.txt index cb3a94e54..c33e90b51 100644 --- a/Tests/ExternalProjectUpdate/CMakeLists.txt +++ b/Tests/ExternalProjectUpdate/CMakeLists.txt @@ -41,7 +41,7 @@ endif() # This should be specified from the command line. if(NOT TEST_GIT_TAG) - message(FATAL_ERROR "TEST_GIT_TAG must be specified.") + set(TEST_GIT_TAG origin/master) endif() if(do_git_tests) From de760c1fa39ba6d052344dc1052b4b47086998ae Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Thu, 1 Nov 2012 20:21:29 +0000 Subject: [PATCH 6/7] ExternalProject: Verify when a fetch occurs during update test. The performance feature of only performing a git fetch when needed during the ExternalProject update step is verified during the test. A fetch is identified by removing the FETCH_HEAD file and checking for its reincarnation. --- .../ExternalProjectUpdateTest.cmake | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake index 0f9a99901..080dd4a05 100644 --- a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake +++ b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake @@ -1,7 +1,15 @@ # Set the ExternalProject GIT_TAG to desired_tag, and make sure the -# resulting checked out version is resulting_sha and a rebuild. -# This check's the viability of the ExternalProject UPDATE_COMMAND. -macro(check_a_tag desired_tag resulting_sha) +# resulting checked out version is resulting_sha and rebuild. +# This check's the correct behavior of the ExternalProject UPDATE_COMMAND. +# Also verify that a fetch only occurs when fetch_expected is 1. +macro(check_a_tag desired_tag resulting_sha fetch_expected) + message( STATUS "Checking ExternalProjectUpdate to tag: ${desired_tag}" ) + + # Remove the FETCH_HEAD file, so we can check if it gets replaced with a 'git + # fetch'. + set( FETCH_HEAD_file ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT/.git/FETCH_HEAD ) + file( REMOVE ${FETCH_HEAD_file} ) + # Configure execute_process(COMMAND ${CMAKE_COMMAND} -G ${CMAKE_TEST_GENERATOR} @@ -43,18 +51,26 @@ when was expected." ) endif() + + if( NOT EXISTS ${FETCH_HEAD_file} AND ${fetch_expected}) + message( FATAL_ERROR "Fetch did NOT occur when it was expected.") + endif() + if( EXISTS ${FETCH_HEAD_file} AND NOT ${fetch_expected}) + message( FATAL_ERROR "Fetch DID occur when it was not expected.") + endif() endmacro() find_package(Git) if(GIT_EXECUTABLE) - check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7) - check_a_tag(tag1 d1970730310fe8bc07e73f15dc570071f9f9654a) + check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1) + check_a_tag(tag1 d1970730310fe8bc07e73f15dc570071f9f9654a 1) # With the Git UPDATE_COMMAND performance patch, this will not required a # 'git fetch' - check_a_tag(tag1 d1970730310fe8bc07e73f15dc570071f9f9654a) - check_a_tag(tag2 5842b503ba4113976d9bb28d57b5aee1ad2736b7) - check_a_tag(d19707303 d1970730310fe8bc07e73f15dc570071f9f9654a) - check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7) + check_a_tag(tag1 d1970730310fe8bc07e73f15dc570071f9f9654a 0) + check_a_tag(tag2 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1) + check_a_tag(d19707303 d1970730310fe8bc07e73f15dc570071f9f9654a 1) + check_a_tag(d19707303 d1970730310fe8bc07e73f15dc570071f9f9654a 0) + check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1) # This is a remote symbolic ref, so it will always trigger a 'git fetch' - check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7) + check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1) endif() From a41d3a40bea01cd4e45579832ac131a0329afc1d Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Fri, 9 Nov 2012 13:45:52 +0000 Subject: [PATCH 7/7] ExternalProjectUpdateTest: Only support Git 1.6.5 and greater. --- .../ExternalProjectUpdateTest.cmake | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake index 080dd4a05..5a6af579e 100644 --- a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake +++ b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake @@ -61,7 +61,25 @@ was expected." endmacro() find_package(Git) +set(do_git_tests 0) if(GIT_EXECUTABLE) + set(do_git_tests 1) + + execute_process( + COMMAND "${GIT_EXECUTABLE}" --version + OUTPUT_VARIABLE ov + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + string(REGEX REPLACE "^git version (.+)$" "\\1" git_version "${ov}") + message(STATUS "git_version='${git_version}'") + + if(git_version VERSION_LESS 1.6.5) + message(STATUS "No ExternalProject git tests with git client less than version 1.6.5") + set(do_git_tests 0) + endif() +endif() + +if(do_git_tests) check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1) check_a_tag(tag1 d1970730310fe8bc07e73f15dc570071f9f9654a 1) # With the Git UPDATE_COMMAND performance patch, this will not required a