From d634ed344fd1431631d7fc5c74287f46734038e6 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Mon, 20 Nov 2017 23:42:52 -0500 Subject: [PATCH] Various CheckSubmodules fixes (#3996) Various CheckSubmodules fixes Closes #3992, #3993, #3994 --- cmake/modules/CheckSubmodules.cmake | 72 +++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 13 deletions(-) diff --git a/cmake/modules/CheckSubmodules.cmake b/cmake/modules/CheckSubmodules.cmake index 6512617af..467d4cf93 100644 --- a/cmake/modules/CheckSubmodules.cmake +++ b/cmake/modules/CheckSubmodules.cmake @@ -18,7 +18,7 @@ # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # Files which confirm a successful clone -SET(VALID_CRUMBS "CMakeLists.txt;Makefile;Makefile.in;Makefile.am;configure.ac;configure.py;autogen.sh") +SET(VALID_CRUMBS "CMakeLists.txt;Makefile;Makefile.in;Makefile.am;configure.ac;configure.py;autogen.sh;.gitignore") # Try and use the specified shallow clone on submodules, if supported SET(DEPTH_VALUE 100) @@ -29,11 +29,23 @@ SET(MAX_ATTEMPTS 2) MESSAGE("\nValidating submodules...") FILE(READ "${CMAKE_SOURCE_DIR}/.gitmodules" SUBMODULE_DATA) +# Force English locale +SET(LC_ALL_BACKUP "$ENV{LC_ALL}") +SET(LANG_BACKUP "$ENV{LANG}") +SET(ENV{LC_ALL} "C") +SET(ENV{LANG} "en_US") + # Assume alpha-numeric paths STRING(REGEX MATCHALL "path = [-0-9A-Za-z/]+" SUBMODULE_LIST ${SUBMODULE_DATA}) +STRING(REGEX MATCHALL "url = [.:%-0-9A-Za-z/]+" SUBMODULE_URL_LIST ${SUBMODULE_DATA}) + FOREACH(_part ${SUBMODULE_LIST}) STRING(REPLACE "path = " "" SUBMODULE_PATH ${_part}) + LIST(FIND SUBMODULE_LIST ${_part} SUBMODULE_INDEX) + LIST(GET SUBMODULE_URL_LIST ${SUBMODULE_INDEX} _url) + STRING(REPLACE "url = " "" SUBMODULE_URL ${_url}) + # Remove submodules from validation as specified in -DSKIP_SUBMODULES=foo;bar SET(SKIP false) IF(SKIP_SUBMODULES) @@ -44,19 +56,33 @@ FOREACH(_part ${SUBMODULE_LIST}) ENDIF() ENDFOREACH() ENDIF() - LIST(REMOVE_ITEM SUBMODULE_LIST ${_part}) IF(NOT SKIP) - LIST(APPEND SUBMODULE_LIST ${SUBMODULE_PATH}) + LIST(INSERT SUBMODULE_LIST ${SUBMODULE_INDEX} ${SUBMODULE_PATH}) + LIST(INSERT SUBMODULE_URL_LIST ${SUBMODULE_INDEX} ${SUBMODULE_URL}) ENDIF() + LIST(REMOVE_ITEM SUBMODULE_LIST ${_part}) + LIST(REMOVE_ITEM SUBMODULE_URL_LIST ${_url}) ENDFOREACH() -LIST(SORT SUBMODULE_LIST) # Once called, status is stored in GIT_RESULT respectively. # Note: Git likes to write to stderr. Don't assume stderr is error; Check GIT_RESULT instead. -MACRO(GIT_SUBMODULE SUBMODULE_PATH FORCE_DEINIT) +MACRO(GIT_SUBMODULE SUBMODULE_PATH FORCE_DEINIT FORCE_REMOTE) FIND_PACKAGE(Git REQUIRED) - IF(${FORCE_DEINIT}) + # Handle missing commits + SET(FORCE_REMOTE_FLAG "${FORCE_REMOTE}") + IF(FORCE_REMOTE_FLAG) + MESSAGE("-- Adding remote submodulefix to ${SUBMODULE_PATH}") + EXECUTE_PROCESS( + COMMAND ${GIT_EXECUTABLE} remote rm submodulefix + COMMAND ${GIT_EXECUTABLE} remote add submodulefix ${FORCE_REMOTE} + COMMAND ${GIT_EXECUTABLE} fetch submodulefix + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/${SUBMODULE_PATH} + OUTPUT_QUIET ERROR_QUIET + ) + # Recurse + GIT_SUBMODULE(${SUBMODULE_PATH} false false) + ELSEIF(${FORCE_DEINIT}) MESSAGE("-- Resetting ${SUBMODULE_PATH}") EXECUTE_PROCESS( COMMAND ${GIT_EXECUTABLE} submodule deinit -f ${CMAKE_SOURCE_DIR}/${SUBMODULE_PATH} @@ -64,7 +90,7 @@ MACRO(GIT_SUBMODULE SUBMODULE_PATH FORCE_DEINIT) OUTPUT_QUIET ) # Recurse - GIT_SUBMODULE(${SUBMODULE_PATH} false) + GIT_SUBMODULE(${SUBMODULE_PATH} false false) ELSE() # Try to use the depth switch SET(DEPTH_CMD "") @@ -87,7 +113,8 @@ MACRO(GIT_SUBMODULE SUBMODULE_PATH FORCE_DEINIT) ENDIF() ENDMACRO() -SET(RETRY_PHRASES "Failed to recurse;unadvertised object;cannot create directory") +SET(MISSING_COMMIT_PHRASES "no such remote ref;reference is not a tree") +SET(RETRY_PHRASES "Failed to recurse;unadvertised object;cannot create directory;already exists;${MISSING_COMMIT_PHRASES}") # Attempt to do lazy clone FOREACH(_submodule ${SUBMODULE_LIST}) @@ -101,10 +128,11 @@ FOREACH(_submodule ${SUBMODULE_LIST}) IF(EXISTS "${CMAKE_SOURCE_DIR}/${_submodule}/${_crumb}") SET(CRUMB_FOUND true) MESSAGE("-- Found ${_submodule}/${_crumb}") + BREAK() ENDIF() ENDFOREACH() IF(NOT CRUMB_FOUND) - GIT_SUBMODULE(${_submodule} false) + GIT_SUBMODULE(${_submodule} false false) SET(COUNTED 0) SET(COUNTING "") @@ -112,11 +140,24 @@ FOREACH(_submodule ${SUBMODULE_LIST}) WHILE(NOT GIT_RESULT EQUAL 0 AND COUNTED LESS MAX_ATTEMPTS) LIST(APPEND COUNTING "x") LIST(LENGTH COUNTING COUNTED) - - FOREACH(_phrase ${RETRY_PHRASES}) + SET(MISSING_COMMIT false) + FOREACH(_phrase ${MISSING_COMMIT_PHRASES}) IF("${GIT_MESSAGE}" MATCHES "${_phrase}") - MESSAGE("-- Retrying ${_submodule} using 'deinit' (attempt ${COUNTED} of ${MAX_ATTEMPTS})...") + SET(MISSING_COMMIT true) + BREAK() + ENDIF() + ENDFOREACH() + FOREACH(_phrase ${RETRY_PHRASES}) + IF(${MISSING_COMMIT}) + LIST(FIND SUBMODULE_LIST ${_submodule} SUBMODULE_INDEX) + LIST(GET SUBMODULE_URL_LIST ${SUBMODULE_INDEX} SUBMODULE_URL) + MESSAGE("-- Retrying ${_submodule} using 'remote add submodulefix' (attempt ${COUNTED} of ${MAX_ATTEMPTS})...") + GIT_SUBMODULE(${_submodule} false "${SUBMODULE_URL}") + BREAK() + ELSEIF("${GIT_MESSAGE}" MATCHES "${_phrase}") + MESSAGE("-- Retrying ${_submodule} using 'deinit' (attempt ${COUNTED} of ${MAX_ATTEMPTS})...") + # Shallow submodules were introduced in 1.8.4 # Shallow commits can fail to clone from non-default branches, only try once IF(GIT_VERSION_STRING VERSION_GREATER "1.8.3" AND COUNTED LESS 2) @@ -125,7 +166,8 @@ FOREACH(_submodule ${SUBMODULE_LIST}) UNSET(DEPTH_VALUE) ENDIF() - GIT_SUBMODULE(${_submodule} true) + GIT_SUBMODULE(${_submodule} true false) + BREAK() ENDIF() ENDFOREACH() ENDWHILE() @@ -136,3 +178,7 @@ FOREACH(_submodule ${SUBMODULE_LIST}) ENDIF() ENDFOREACH() MESSAGE("-- Done validating submodules.\n") + +# Reset locale +SET(ENV{LC_ALL} "${LC_ALL_BACKUP}") +SET(ENV{LANG} "${LANG_BACKUP}")