aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2020-11-16 18:14:49 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2020-11-17 16:40:41 +0100
commitf8b8a9a59f8f7eced57e9d68e86f11073eba20a8 (patch)
tree1d198cd1163a171fd20910ff5b92f3de5ee8065e
parentc4c11e016ffe9a4285a959b294b6b9dd334b096d (diff)
Add a script to synchronize the repo to a consistent (sub)set
Make a few modifications to the dependency evaluation to include the revision of each dependency, and a method that checks each dependency out to the revision necessary to create a consistent set for the requested module. If the requested module is ".", check all modules out to the given revision. Can be called (ideally from a git-sync-to alias script): cmake -DSYNC_TO_MODULE="$1" -DSYNC_TO_BRANCH="$2" \ -P cmake/QtSynchronizeRepo.cmake Change-Id: I007e9f9023bae949907b64e264ae7869dff1da2e Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
-rw-r--r--cmake/QtSynchronizeRepo.cmake3
-rw-r--r--cmake/QtTopLevelHelpers.cmake142
2 files changed, 133 insertions, 12 deletions
diff --git a/cmake/QtSynchronizeRepo.cmake b/cmake/QtSynchronizeRepo.cmake
new file mode 100644
index 00000000..522ea76e
--- /dev/null
+++ b/cmake/QtSynchronizeRepo.cmake
@@ -0,0 +1,3 @@
+include(cmake/QtTopLevelHelpers.cmake)
+
+qt_internal_sync_to(${SYNC_TO_MODULE} ${SYNC_TO_BRANCH})
diff --git a/cmake/QtTopLevelHelpers.cmake b/cmake/QtTopLevelHelpers.cmake
index 4aa560e3..b5ce1e8a 100644
--- a/cmake/QtTopLevelHelpers.cmake
+++ b/cmake/QtTopLevelHelpers.cmake
@@ -14,20 +14,30 @@ endfunction()
# poor man's yaml parser, populating $out_dependencies with all dependencies
# in the $depends_file
+# Each entry will be in the format dependency/sha1
function(qt_internal_parse_dependencies depends_file out_dependencies)
file(STRINGS "${depends_file}" lines)
set(dependencies "")
+ set(dependency "")
foreach(line IN LISTS lines)
if(line STREQUAL "dependencies:")
set(found_dependencies 1)
- elseif(found_dependencies AND line MATCHES "^ (.*):$")
- set(dependency ${CMAKE_MATCH_1})
- # dependencies are specified with relative path to this module
- string(REPLACE "../" "" dependency ${dependency})
- list(APPEND dependencies ${dependency})
+ elseif(found_dependencies)
+ if(line MATCHES "^ ref: (.*)$")
+ set(revision "${CMAKE_MATCH_1}")
+ list(APPEND dependencies ${dependency}/${revision})
+ set(dependency "")
+ elseif (line MATCHES "^ (.*):$")
+ if(dependency)
+ message(FATAL_ERROR "Format error in ${depends_file} - ${dependency} does not specify revision!")
+ endif()
+ set(dependency "${CMAKE_MATCH_1}")
+ # dependencies are specified with relative path to this module
+ string(REPLACE "../" "" dependency ${dependency})
+ endif()
endif()
endforeach()
- message(DEBUG "qt_internal_parse_dependencies for ${depends_file}: ${module_list}")
+ message(DEBUG "qt_internal_parse_dependencies for ${depends_file}: ${dependencies} ${revisions}")
set(${out_dependencies} "${dependencies}" PARENT_SCOPE)
endfunction()
@@ -38,7 +48,7 @@ endfunction()
# dependencies.
# Function calls itself recursively if a dependency is found that is not yet in $ordered.
function(qt_internal_add_module_dependencies module ordered out_ordered out_has_dependencies
- out_module_dependencies)
+ out_module_dependencies out_revisions)
set(depends_file "${CMAKE_CURRENT_SOURCE_DIR}/${module}/dependencies.yaml")
if(NOT EXISTS "${depends_file}")
set(${out_has_dependencies} "" PARENT_SCOPE)
@@ -46,28 +56,39 @@ function(qt_internal_add_module_dependencies module ordered out_ordered out_has_
endif()
set(${out_has_dependencies} "1" PARENT_SCOPE)
set(dependencies "")
- qt_internal_parse_dependencies(${depends_file} dependencies)
+ qt_internal_parse_dependencies("${depends_file}" dependencies)
# module hasn't been seen yet, append it
list(FIND ordered "${module}" pindex)
if (pindex EQUAL -1)
list(LENGTH ordered pindex)
- list(APPEND ordered ${module})
+ list(APPEND ordered "${module}")
+ list(APPEND revisions "HEAD")
endif()
+ set(modules_dependencies "")
foreach(dependency IN LISTS dependencies)
+ string(FIND "${dependency}" "/" splitindex REVERSE)
+ string(SUBSTRING "${dependency}" ${splitindex} -1 revision)
+ string(SUBSTRING "${revision}" 1 -1 revision)
+ string(SUBSTRING "${dependency}" 0 ${splitindex} dependency)
+ list(APPEND modules_dependencies "${dependency}")
list(FIND ordered "${dependency}" dindex)
if (dindex EQUAL -1)
# dependency hasnt' been seen yet - load it
list(INSERT ordered ${pindex} "${dependency}")
+ list(INSERT revisions ${pindex} "${revision}")
qt_internal_add_module_dependencies(${dependency} "${ordered}" ordered has_dependency
- "${out_module_dependencies}")
+ "${out_module_dependencies}" revisions)
elseif(dindex GREATER pindex)
# otherwise, make sure it is before module
list(REMOVE_AT ordered ${dindex})
+ list(REMOVE_AT revisions ${dindex})
list(INSERT ordered ${pindex} "${dependency}")
+ list(INSERT revisions ${pindex} "${revision}")
endif()
endforeach()
set(${out_ordered} "${ordered}" PARENT_SCOPE)
- set(${out_module_dependencies} ${${out_module_dependencies}} ${dependencies} PARENT_SCOPE)
+ set(${out_module_dependencies} ${${out_module_dependencies}} ${modules_dependencies} PARENT_SCOPE)
+ set(${out_revisions} "${revisions}" PARENT_SCOPE)
endfunction()
# populates $out_all_ordered with the sequence of the modules that need
@@ -82,7 +103,7 @@ function(qt_internal_sort_module_dependencies modules out_all_ordered dependenci
endif()
set(module_dependencies_list_var_name "${dependencies_map_prefix}${module}")
qt_internal_add_module_dependencies(${module} "${ordered}" out_ordered module_depends
- "${module_dependencies_list_var_name}")
+ "${module_dependencies_list_var_name}" revisions)
set(${module_dependencies_list_var_name}
"${${module_dependencies_list_var_name}}" PARENT_SCOPE)
if(NOT module_depends)
@@ -96,3 +117,100 @@ function(qt_internal_sort_module_dependencies modules out_all_ordered dependenci
message(DEBUG "qt_internal_parse_dependencies sorted ${modules}: ${ordered}")
set(${out_all_ordered} "${ordered}" PARENT_SCOPE)
endfunction()
+
+# does what it says, but also updates submodules
+function(qt_internal_checkout module revision)
+ message(NOTICE "Checking '${module}' out to revision '${revision}'")
+ execute_process(
+ COMMAND "git" "checkout" "${revision}"
+ WORKING_DIRECTORY "./${module}"
+ RESULT_VARIABLE git_result
+ OUTPUT_VARIABLE git_stdout
+ ERROR_VARIABLE git_stderr
+ )
+ if (VERBOSE)
+ message(NOTICE ${git_stdout})
+ endif()
+ if (git_result)
+ message(WARNING "${git_stdout}")
+ message(FATAL_ERROR "Failed to check '${module}' out to '${revision}': ${git_stderr}")
+ endif()
+ execute_process(
+ COMMAND "git" "submodule" "update"
+ WORKING_DIRECTORY "./${module}"
+ RESULT_VARIABLE git_result
+ OUTPUT_VARIABLE git_stdout
+ ERROR_VARIABLE git_stderr
+ )
+endfunction()
+
+# evaluates the dependencies for $module, and checks all dependencies
+# out so that it is a consistent set
+function(qt_internal_sync_to module)
+ if(ARGN)
+ set(revision "${ARGV1}")
+ # special casing "." as the target module - checkout all out to $revision
+ if("${module}" STREQUAL ".")
+ qt_internal_find_modules(modules)
+ foreach(module IN LISTS modules)
+ qt_internal_checkout("${module}" "${revision}")
+ endforeach()
+ return()
+ endif()
+ else()
+ set(revision "HEAD")
+ endif()
+ qt_internal_checkout("${module}" "${revision}")
+
+ set(revision "")
+ set(checkedout "1")
+ # Load all dependencies for $module, then iterate over the dependencies in reverse order,
+ # and check out the first that isn't already at the required revision.
+ # Repeat everything (we need to reload dependencies after each checkout) until no more checkouts
+ # are done.
+ while(${checkedout})
+ set(dependencies "")
+ set(revisions "")
+ set(prefix "")
+ qt_internal_add_module_dependencies(${module} "${dependencies}" dependencies has_dependencies prefix revisions)
+ message(DEBUG "${module} dependencies: ${dependencies}")
+ message(DEBUG "${module} revisions : ${revisions}")
+
+ if (NOT has_dependencies)
+ message(NOTICE "Module ${module} has no dependencies")
+ return()
+ endif()
+
+ list(LENGTH dependencies count)
+ math(EXPR count "${count} - 1")
+ set(checkedout 0)
+ foreach(i RANGE ${count} 0 -1 )
+ list(GET dependencies ${i} dependency)
+ list(GET revisions ${i} revision)
+ if ("${revision}" STREQUAL "HEAD")
+ message(DEBUG "Not changing checked out revision of ${dependency}")
+ continue()
+ endif()
+
+ execute_process(
+ COMMAND "git" "rev-parse" "HEAD"
+ WORKING_DIRECTORY "./${dependency}"
+ RESULT_VARIABLE git_result
+ OUTPUT_VARIABLE git_stdout
+ ERROR_VARIABLE git_stderr
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ if (git_result)
+ message(WARNING "${git_stdout}")
+ message(FATAL_ERROR "Failed to get current HEAD of '${dependency}': ${git_stderr}")
+ endif()
+ if ("${git_stdout}" STREQUAL "${revision}")
+ continue()
+ endif()
+
+ qt_internal_checkout("${dependency}" "${revision}")
+ set(checkedout 1)
+ break()
+ endforeach()
+ endwhile()
+endfunction()