ExternalProject: Add Mercurial (hg) repository support
Add options HG_REPOSITORY and HG_TAG to specify an external project hosted in a Mercurial repository. Teach ExternalProject to clone the repository and update from it. Extend the ExternalProject test to try a Mercurial repository when hg is available.
This commit is contained in:
parent
ea5bfb1d25
commit
91053cdf7b
|
@ -21,6 +21,8 @@
|
||||||
# [SVN_TRUST_CERT 1 ] # Trust the Subversion server site certificate
|
# [SVN_TRUST_CERT 1 ] # Trust the Subversion server site certificate
|
||||||
# [GIT_REPOSITORY url] # URL of git repo
|
# [GIT_REPOSITORY url] # URL of git repo
|
||||||
# [GIT_TAG tag] # Git branch name, commit id or tag
|
# [GIT_TAG tag] # Git branch name, commit id or tag
|
||||||
|
# [HG_REPOSITORY url] # URL of mercurial repo
|
||||||
|
# [HG_TAG tag] # Mercurial branch name, commit id or tag
|
||||||
# [URL /.../src.tgz] # Full path or URL of source
|
# [URL /.../src.tgz] # Full path or URL of source
|
||||||
# [URL_MD5 md5] # MD5 checksum of file at URL
|
# [URL_MD5 md5] # MD5 checksum of file at URL
|
||||||
# [TIMEOUT seconds] # Time allowed for file download operations
|
# [TIMEOUT seconds] # Time allowed for file download operations
|
||||||
|
@ -331,6 +333,67 @@ endif()
|
||||||
|
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
function(_ep_write_hgclone_script script_filename source_dir hg_EXECUTABLE hg_repository hg_tag src_name work_dir hgclone_infofile hgclone_stampfile)
|
||||||
|
file(WRITE ${script_filename}
|
||||||
|
"if(\"${hg_tag}\" STREQUAL \"\")
|
||||||
|
message(FATAL_ERROR \"Tag for hg checkout should not be empty.\")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(run 0)
|
||||||
|
|
||||||
|
if(\"${hgclone_infofile}\" IS_NEWER_THAN \"${hgclone_stampfile}\")
|
||||||
|
set(run 1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT run)
|
||||||
|
message(STATUS \"Avoiding repeated hg clone, stamp file is up to date: '${hgclone_stampfile}'\")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND \${CMAKE_COMMAND} -E remove_directory \"${source_dir}\"
|
||||||
|
RESULT_VARIABLE error_code
|
||||||
|
)
|
||||||
|
if(error_code)
|
||||||
|
message(FATAL_ERROR \"Failed to remove directory: '${source_dir}'\")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND \"${hg_EXECUTABLE}\" clone \"${hg_repository}\" \"${src_name}\"
|
||||||
|
WORKING_DIRECTORY \"${work_dir}\"
|
||||||
|
RESULT_VARIABLE error_code
|
||||||
|
)
|
||||||
|
if(error_code)
|
||||||
|
message(FATAL_ERROR \"Failed to clone repository: '${hg_repository}'\")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND \"${hg_EXECUTABLE}\" update ${hg_tag}
|
||||||
|
WORKING_DIRECTORY \"${work_dir}/${src_name}\"
|
||||||
|
RESULT_VARIABLE error_code
|
||||||
|
)
|
||||||
|
if(error_code)
|
||||||
|
message(FATAL_ERROR \"Failed to checkout tag: '${hg_tag}'\")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Complete success, update the script-last-run stamp file:
|
||||||
|
#
|
||||||
|
execute_process(
|
||||||
|
COMMAND \${CMAKE_COMMAND} -E copy
|
||||||
|
\"${hgclone_infofile}\"
|
||||||
|
\"${hgclone_stampfile}\"
|
||||||
|
WORKING_DIRECTORY \"${work_dir}/${src_name}\"
|
||||||
|
RESULT_VARIABLE error_code
|
||||||
|
)
|
||||||
|
if(error_code)
|
||||||
|
message(FATAL_ERROR \"Failed to copy script-last-run stamp file: '${hgclone_stampfile}'\")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
"
|
||||||
|
)
|
||||||
|
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
function(_ep_write_downloadfile_script script_filename remote local timeout md5)
|
function(_ep_write_downloadfile_script script_filename remote local timeout md5)
|
||||||
if(timeout)
|
if(timeout)
|
||||||
|
@ -1027,6 +1090,7 @@ function(_ep_add_download_command name)
|
||||||
get_property(cvs_repository TARGET ${name} PROPERTY _EP_CVS_REPOSITORY)
|
get_property(cvs_repository TARGET ${name} PROPERTY _EP_CVS_REPOSITORY)
|
||||||
get_property(svn_repository TARGET ${name} PROPERTY _EP_SVN_REPOSITORY)
|
get_property(svn_repository TARGET ${name} PROPERTY _EP_SVN_REPOSITORY)
|
||||||
get_property(git_repository TARGET ${name} PROPERTY _EP_GIT_REPOSITORY)
|
get_property(git_repository TARGET ${name} PROPERTY _EP_GIT_REPOSITORY)
|
||||||
|
get_property(hg_repository TARGET ${name} PROPERTY _EP_HG_REPOSITORY )
|
||||||
get_property(url TARGET ${name} PROPERTY _EP_URL)
|
get_property(url TARGET ${name} PROPERTY _EP_URL)
|
||||||
|
|
||||||
# TODO: Perhaps file:// should be copied to download dir before extraction.
|
# TODO: Perhaps file:// should be copied to download dir before extraction.
|
||||||
|
@ -1148,6 +1212,46 @@ function(_ep_add_download_command name)
|
||||||
set(comment "Performing download step (git clone) for '${name}'")
|
set(comment "Performing download step (git clone) for '${name}'")
|
||||||
set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitclone.cmake)
|
set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitclone.cmake)
|
||||||
list(APPEND depends ${stamp_dir}/${name}-gitinfo.txt)
|
list(APPEND depends ${stamp_dir}/${name}-gitinfo.txt)
|
||||||
|
elseif(hg_repository)
|
||||||
|
find_package(Hg)
|
||||||
|
if(NOT HG_EXECUTABLE)
|
||||||
|
message(FATAL_ERROR "error: could not find hg for clone of ${name}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
get_property(hg_tag TARGET ${name} PROPERTY _EP_HG_TAG)
|
||||||
|
if(NOT hg_tag)
|
||||||
|
set(hg_tag "tip")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# For the download step, and the hg clone operation, only the repository
|
||||||
|
# should be recorded in a configured RepositoryInfo file. If the repo
|
||||||
|
# changes, the clone script should be run again. But if only the tag
|
||||||
|
# changes, avoid running the clone script again. Let the 'always' running
|
||||||
|
# update step checkout the new tag.
|
||||||
|
#
|
||||||
|
set(repository ${hg_repository})
|
||||||
|
set(module)
|
||||||
|
set(tag)
|
||||||
|
configure_file(
|
||||||
|
"${CMAKE_ROOT}/Modules/RepositoryInfo.txt.in"
|
||||||
|
"${stamp_dir}/${name}-hginfo.txt"
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
|
||||||
|
get_filename_component(src_name "${source_dir}" NAME)
|
||||||
|
get_filename_component(work_dir "${source_dir}" PATH)
|
||||||
|
|
||||||
|
# Since hg clone doesn't succeed if the non-empty source_dir exists,
|
||||||
|
# create a cmake script to invoke as download command.
|
||||||
|
# The script will delete the source directory and then call hg clone.
|
||||||
|
#
|
||||||
|
_ep_write_hgclone_script(${tmp_dir}/${name}-hgclone.cmake ${source_dir}
|
||||||
|
${HG_EXECUTABLE} ${hg_repository} ${hg_tag} ${src_name} ${work_dir}
|
||||||
|
${stamp_dir}/${name}-hginfo.txt ${stamp_dir}/${name}-hgclone-lastrun.txt
|
||||||
|
)
|
||||||
|
set(comment "Performing download step (hg clone) for '${name}'")
|
||||||
|
set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-hgclone.cmake)
|
||||||
|
list(APPEND depends ${stamp_dir}/${name}-hginfo.txt)
|
||||||
elseif(url)
|
elseif(url)
|
||||||
get_filename_component(work_dir "${source_dir}" PATH)
|
get_filename_component(work_dir "${source_dir}" PATH)
|
||||||
get_property(md5 TARGET ${name} PROPERTY _EP_URL_MD5)
|
get_property(md5 TARGET ${name} PROPERTY _EP_URL_MD5)
|
||||||
|
@ -1196,7 +1300,7 @@ function(_ep_add_download_command name)
|
||||||
else()
|
else()
|
||||||
_ep_is_dir_empty("${source_dir}" empty)
|
_ep_is_dir_empty("${source_dir}" empty)
|
||||||
if(${empty})
|
if(${empty})
|
||||||
message(SEND_ERROR "error: no download info for '${name}' -- please specify existing/non-empty SOURCE_DIR or one of URL, CVS_REPOSITORY and CVS_MODULE, SVN_REPOSITORY, GIT_REPOSITORY or DOWNLOAD_COMMAND")
|
message(SEND_ERROR "error: no download info for '${name}' -- please specify existing/non-empty SOURCE_DIR or one of URL, CVS_REPOSITORY and CVS_MODULE, SVN_REPOSITORY, GIT_REPOSITORY, HG_REPOSITORY or DOWNLOAD_COMMAND")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -1226,6 +1330,7 @@ function(_ep_add_update_command name)
|
||||||
get_property(cvs_repository TARGET ${name} PROPERTY _EP_CVS_REPOSITORY)
|
get_property(cvs_repository TARGET ${name} PROPERTY _EP_CVS_REPOSITORY)
|
||||||
get_property(svn_repository TARGET ${name} PROPERTY _EP_SVN_REPOSITORY)
|
get_property(svn_repository TARGET ${name} PROPERTY _EP_SVN_REPOSITORY)
|
||||||
get_property(git_repository TARGET ${name} PROPERTY _EP_GIT_REPOSITORY)
|
get_property(git_repository TARGET ${name} PROPERTY _EP_GIT_REPOSITORY)
|
||||||
|
get_property(hg_repository TARGET ${name} PROPERTY _EP_HG_REPOSITORY )
|
||||||
|
|
||||||
set(work_dir)
|
set(work_dir)
|
||||||
set(comment)
|
set(comment)
|
||||||
|
@ -1280,6 +1385,27 @@ function(_ep_add_update_command name)
|
||||||
COMMAND ${GIT_EXECUTABLE} submodule update --recursive
|
COMMAND ${GIT_EXECUTABLE} submodule update --recursive
|
||||||
)
|
)
|
||||||
set(always 1)
|
set(always 1)
|
||||||
|
elseif(hg_repository)
|
||||||
|
if(NOT HG_EXECUTABLE)
|
||||||
|
message(FATAL_ERROR "error: could not find hg for pull of ${name}")
|
||||||
|
endif()
|
||||||
|
set(work_dir ${source_dir})
|
||||||
|
set(comment "Performing update step (hg pull) for '${name}'")
|
||||||
|
get_property(hg_tag TARGET ${name} PROPERTY _EP_HG_TAG)
|
||||||
|
if(NOT hg_tag)
|
||||||
|
set(hg_tag "tip")
|
||||||
|
endif()
|
||||||
|
if("${HG_VERSION_STRING}" STREQUAL "2.1")
|
||||||
|
message(WARNING "Mercurial 2.1 does not distinguish an empty pull from a failed pull:
|
||||||
|
http://mercurial.selenic.com/wiki/UpgradeNotes#A2.1.1:_revert_pull_return_code_change.2C_compile_issue_on_OS_X
|
||||||
|
http://thread.gmane.org/gmane.comp.version-control.mercurial.devel/47656
|
||||||
|
Update to Mercurial >= 2.1.1.
|
||||||
|
")
|
||||||
|
endif()
|
||||||
|
set(cmd ${HG_EXECUTABLE} pull
|
||||||
|
COMMAND ${HG_EXECUTABLE} update ${hg_tag}
|
||||||
|
)
|
||||||
|
set(always 1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
get_property(log TARGET ${name} PROPERTY _EP_LOG_UPDATE)
|
get_property(log TARGET ${name} PROPERTY _EP_LOG_UPDATE)
|
||||||
|
|
|
@ -6,6 +6,7 @@ include(ExternalProject)
|
||||||
find_package(CVS)
|
find_package(CVS)
|
||||||
find_package(Subversion)
|
find_package(Subversion)
|
||||||
find_package(Git)
|
find_package(Git)
|
||||||
|
find_package(Hg)
|
||||||
|
|
||||||
option(ExternalProjectTest_USE_FOLDERS "Enable folder grouping in IDEs." ON)
|
option(ExternalProjectTest_USE_FOLDERS "Enable folder grouping in IDEs." ON)
|
||||||
if(ExternalProjectTest_USE_FOLDERS)
|
if(ExternalProjectTest_USE_FOLDERS)
|
||||||
|
@ -511,6 +512,76 @@ if(do_git_tests)
|
||||||
set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
|
set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(do_hg_tests 0)
|
||||||
|
|
||||||
|
if(HG_EXECUTABLE)
|
||||||
|
set(do_hg_tests 1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(do_hg_tests)
|
||||||
|
set(local_hg_repo "../../LocalRepositories/HG")
|
||||||
|
|
||||||
|
# Unzip/untar the hg repository in our source folder so that other
|
||||||
|
# projects below may use it to test hg args of ExternalProject_Add
|
||||||
|
#
|
||||||
|
set(proj SetupLocalHGRepository)
|
||||||
|
ExternalProject_Add(${proj}
|
||||||
|
SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/LocalRepositories/HG
|
||||||
|
URL ${CMAKE_CURRENT_SOURCE_DIR}/hgrepo.tgz
|
||||||
|
BUILD_COMMAND ""
|
||||||
|
CONFIGURE_COMMAND "${HG_EXECUTABLE}" --version
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
)
|
||||||
|
set_property(TARGET ${proj}
|
||||||
|
PROPERTY FOLDER "SetupRepos/Local/Deeply/Nested/For/Testing")
|
||||||
|
|
||||||
|
|
||||||
|
# hg by commit id:
|
||||||
|
#
|
||||||
|
set(proj TutorialStep1-HG-byhash)
|
||||||
|
ExternalProject_Add(${proj}
|
||||||
|
HG_REPOSITORY "${local_hg_repo}"
|
||||||
|
HG_TAG dd2ce38a6b8a
|
||||||
|
UPDATE_COMMAND ""
|
||||||
|
CMAKE_GENERATOR "${CMAKE_GENERATOR}"
|
||||||
|
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
DEPENDS "SetupLocalHGRepository"
|
||||||
|
)
|
||||||
|
set_property(TARGET ${proj} PROPERTY FOLDER "HG")
|
||||||
|
|
||||||
|
# hg by explicit branch/tag name:
|
||||||
|
#
|
||||||
|
set(proj TutorialStep1-HG-bytag)
|
||||||
|
ExternalProject_Add(${proj}
|
||||||
|
HG_REPOSITORY "${local_hg_repo}"
|
||||||
|
HG_TAG "default"
|
||||||
|
UPDATE_COMMAND ""
|
||||||
|
CMAKE_GENERATOR "${CMAKE_GENERATOR}"
|
||||||
|
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
DEPENDS "SetupLocalHGRepository"
|
||||||
|
)
|
||||||
|
set_property(TARGET ${proj} PROPERTY FOLDER "HG")
|
||||||
|
|
||||||
|
# Live hg / tip (no HG_TAG):
|
||||||
|
#
|
||||||
|
# Mercurial 2.1 does not distinguish an empty pull from a failed pull,
|
||||||
|
# so do not run the test with that version.
|
||||||
|
if(NOT "${HG_VERSION_STRING}" STREQUAL "2.1")
|
||||||
|
set(proj TutorialStep1-HG-tip)
|
||||||
|
ExternalProject_Add(${proj}
|
||||||
|
HG_REPOSITORY "${local_hg_repo}"
|
||||||
|
CMAKE_GENERATOR "${CMAKE_GENERATOR}"
|
||||||
|
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
DEPENDS "SetupLocalHGRepository"
|
||||||
|
LOG_UPDATE 1
|
||||||
|
)
|
||||||
|
set_property(TARGET ${proj} PROPERTY FOLDER "HG")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# Test the testable built/installed products:
|
# Test the testable built/installed products:
|
||||||
#
|
#
|
||||||
|
@ -581,5 +652,5 @@ endif()
|
||||||
message(STATUS "can_build_tutorial_step5='${can_build_tutorial_step5}'")
|
message(STATUS "can_build_tutorial_step5='${can_build_tutorial_step5}'")
|
||||||
message(STATUS "do_cvs_tests='${do_cvs_tests}'")
|
message(STATUS "do_cvs_tests='${do_cvs_tests}'")
|
||||||
message(STATUS "do_svn_tests='${do_svn_tests}'")
|
message(STATUS "do_svn_tests='${do_svn_tests}'")
|
||||||
message(STATUS "do_git_tests='${do_git_tests}'")
|
message(STATUS "do_git_tests='${do_git_tests}' GIT_EXECUTABLE='${GIT_EXECUTABLE}'")
|
||||||
message(STATUS "GIT_EXECUTABLE='${GIT_EXECUTABLE}'")
|
message(STATUS "do_hg_tests='${do_hg_tests}' HG_EXECUTABLE='${HG_EXECUTABLE}'")
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue