Merge topic 'only-git-fetch-when-necessary'
a41d3a4
ExternalProjectUpdateTest: Only support Git 1.6.5 and greater.de760c1
ExternalProject: Verify when a fetch occurs during update test.0a34433
ExternalProject: Make sure the ExternalProjectUpdate setup is available.9b66c8f
ExternalProject: Always do a git fetch for a remote ref.2619f4d
ExternalProject: Add tests for UPDATE_COMMAND.378aa12
ExternalProject: Do smoke tests for Git Tutorial builds.d075829
ExternalProject: Only run 'git fetch' when required.
This commit is contained in:
commit
bd52ff3ac9
|
@ -402,6 +402,79 @@ 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()
|
||||
|
||||
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(
|
||||
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 is_remote_ref 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 +1427,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 +1479,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)
|
||||
|
|
|
@ -983,6 +983,36 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
|
|||
set_tests_properties(ExternalProject PROPERTIES
|
||||
TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT})
|
||||
|
||||
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}
|
||||
-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
|
||||
DEPENDS ExternalProjectUpdateSetup )
|
||||
|
||||
# do each of the tutorial steps
|
||||
foreach(STP RANGE 1 7)
|
||||
add_test(TutorialStep${STP} ${CMAKE_CTEST_COMMAND}
|
||||
|
|
|
@ -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:
|
||||
#
|
||||
|
|
|
@ -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)
|
||||
set(TEST_GIT_TAG origin/master)
|
||||
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_DIR>
|
||||
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}'")
|
|
@ -0,0 +1,94 @@
|
|||
# Set the ExternalProject GIT_TAG to desired_tag, and make sure the
|
||||
# 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}
|
||||
-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
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(error_code)
|
||||
message(FATAL_ERROR "Could not check the sha.")
|
||||
endif()
|
||||
|
||||
if(NOT (${tag_sha} STREQUAL ${resulting_sha}))
|
||||
message(FATAL_ERROR "UPDATE_COMMAND produced
|
||||
${tag_sha}
|
||||
when
|
||||
${resulting_sha}
|
||||
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)
|
||||
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
|
||||
# 'git fetch'
|
||||
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 1)
|
||||
endif()
|
Binary file not shown.
Loading…
Reference in New Issue