init-repository: Normalize git urls with more than one '../' segment
The qttools qlitehtml submodule url was recently updated to use a relative url like '../../playground/qlitehtml.git' instead of an absolute path to code.qt.io repo. Same for the nested litehtml submodule. This broke initialization of the qttools repository, because the init-repository script only normalized one '../' segment in the submodule url, instead of all of them, which ended up trying to clone a non-existent git://code.qt.io/qt/../playground/qlitehtml.git repo. Apply the url normalization in all the code paths where there might still be '../' segments in the url. Pick-to: 6.8 6.9 Change-Id: Iaa8e58104c92858318ad66aefa5a38d63ad7a155 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
parent
444167f5fb
commit
ff25d705a3
@ -93,9 +93,15 @@ function(qt_ir_run_git_submodule_init submodules working_directory)
|
||||
qt_ir_setup_commit_template("${working_directory}" "${working_directory}")
|
||||
endfunction()
|
||||
|
||||
# Add gerrit remotes to the repository.
|
||||
function(qt_ir_add_git_remotes repo_name working_directory)
|
||||
set(gerrit_ssh_base "ssh://@USER@codereview.qt-project.org@PORT@/qt/")
|
||||
# Add gerrit remotes to the repository located in the working_directory.
|
||||
# repo_relative_url is the relative URL of the repository.
|
||||
# Examples:
|
||||
# - qt5
|
||||
# - qttools.git
|
||||
# - ../playground/qlitehtml.git
|
||||
# - ../qt/qttools-litehtml.git
|
||||
function(qt_ir_add_git_remotes repo_relative_url working_directory)
|
||||
set(gerrit_ssh_base "ssh://@USER@codereview.qt-project.org@PORT@/")
|
||||
set(gerrit_repo_url "${gerrit_ssh_base}")
|
||||
|
||||
qt_ir_get_option_value(codereview-username username)
|
||||
@ -110,7 +116,10 @@ function(qt_ir_add_git_remotes repo_name working_directory)
|
||||
string(REPLACE "@PORT@" "" gerrit_repo_url "${gerrit_repo_url}")
|
||||
endif()
|
||||
|
||||
string(APPEND gerrit_repo_url "${repo_name}")
|
||||
set(namespace "qt")
|
||||
set(repo_relative_url_with_namespace "${namespace}/${repo_relative_url}")
|
||||
qt_ir_normalize_git_url("${repo_relative_url_with_namespace}" normalized_url)
|
||||
string(APPEND gerrit_repo_url "${normalized_url}")
|
||||
|
||||
qt_ir_execute_process_and_log_and_handle_error(
|
||||
COMMAND_ARGS git config remote.gerrit.url "${gerrit_repo_url}"
|
||||
@ -193,15 +202,21 @@ function(qt_ir_clone_one_submodule submodule_name)
|
||||
set(submodule_base_git_path "${${prefix}_${submodule_name}_base_git_path}")
|
||||
|
||||
set(submodule_url "${submodule_base_git_path}")
|
||||
qt_ir_has_url_scheme("${submodule_url}" has_url_scheme)
|
||||
qt_ir_parse_git_url(
|
||||
URL "${submodule_url}"
|
||||
OUT_VAR_HAS_URL_SCHEME has_url_scheme
|
||||
)
|
||||
|
||||
if(NOT has_url_scheme AND arg_BASE_URL)
|
||||
set(submodule_url "${arg_BASE_URL}${submodule_url}")
|
||||
qt_ir_normalize_git_url("${submodule_url}" submodule_url)
|
||||
endif()
|
||||
|
||||
qt_ir_get_mirror(mirror_url)
|
||||
set(mirror "")
|
||||
if(NOT has_url_scheme AND mirror_url AND (should_clone OR arg_FETCH))
|
||||
set(mirror "${mirror_url}${submodule_base_git_path}")
|
||||
qt_ir_normalize_git_url("${mirror}" mirror)
|
||||
endif()
|
||||
|
||||
set(mirror_or_original_url "${submodule_url}")
|
||||
|
@ -40,16 +40,77 @@ function(qt_ir_get_git_config_contents out_var)
|
||||
set(${out_var} "${git_output}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Checks whether the given url has a scheme like https:// or is just a
|
||||
# relative path.
|
||||
function(qt_ir_has_url_scheme url out_var)
|
||||
string(REGEX MATCH "^[a-z][a-z0-9+\-.]*://" has_url_scheme "${url}")
|
||||
# Parses a git repo url to:
|
||||
# - check if the given url has a scheme like https:// or git:// or is just a
|
||||
# relative path with no scheme (possibly containing '../' segments)
|
||||
# - extracts the scheme if it exists
|
||||
# - extracts the url without the scheme
|
||||
function(qt_ir_parse_git_url)
|
||||
set(options "")
|
||||
set(oneValueArgs
|
||||
URL
|
||||
OUT_VAR_HAS_URL_SCHEME
|
||||
OUT_VAR_SCHEME
|
||||
OUT_VAR_URL_WITHOUT_SCHEME
|
||||
)
|
||||
set(multiValueArgs "")
|
||||
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
string(REGEX MATCH "^([a-z][a-z0-9+\-.]*://)(.+)" url_scheme_match "${arg_URL}")
|
||||
|
||||
if(url_scheme_match)
|
||||
set(has_url_scheme TRUE)
|
||||
set(scheme "${CMAKE_MATCH_1}")
|
||||
set(url_without_scheme "${CMAKE_MATCH_2}")
|
||||
else()
|
||||
set(has_url_scheme FALSE)
|
||||
set(scheme "")
|
||||
set(url_without_scheme "${url}")
|
||||
endif()
|
||||
|
||||
if(arg_OUT_VAR_HAS_URL_SCHEME)
|
||||
set(${arg_OUT_VAR_HAS_URL_SCHEME} "${has_url_scheme}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if(arg_OUT_VAR_SCHEME)
|
||||
set(${arg_OUT_VAR_SCHEME} "${scheme}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if(arg_OUT_VAR_URL_WITHOUT_SCHEME)
|
||||
set(${arg_OUT_VAR_URL_WITHOUT_SCHEME} "${url_without_scheme}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Normalizes a url that contains '../' path segments.
|
||||
# Removes the '../' segments and the directories that they precede.
|
||||
# Example:
|
||||
# git://code.qt.io/qt/../playground/qlitehtml.git
|
||||
# will be normalized to:
|
||||
# git://code.qt.io/playground/qlitehtml.git
|
||||
function(qt_ir_normalize_git_url url out_var)
|
||||
# The exact perl code was while ($base =~ s,(?!\.\./)[^/]+/\.\./,,g) {}
|
||||
# That got rid of ../ and ../../ in the path, but it broke down
|
||||
# when more than two '../' segments were present.
|
||||
#
|
||||
# In CMake, we instead parse the url to get the non-scheme suffix,
|
||||
# use get_filename_component(ABSOLUTE) to resolve the url as if it was a relative path
|
||||
# and then re-add the scheme if it was present.
|
||||
qt_ir_parse_git_url(
|
||||
URL "${url}"
|
||||
OUT_VAR_HAS_URL_SCHEME has_url_scheme
|
||||
OUT_VAR_SCHEME url_scheme
|
||||
OUT_VAR_URL_WITHOUT_SCHEME url_without_scheme
|
||||
)
|
||||
|
||||
# Note the empty BASE_DIR is important, otherwise the path is relative to
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}.
|
||||
get_filename_component(normalized_url "${url_without_scheme}" ABSOLUTE BASE_DIR "")
|
||||
|
||||
if(has_url_scheme)
|
||||
set(${out_var} TRUE PARENT_SCOPE)
|
||||
else()
|
||||
set(${out_var} FALSE PARENT_SCOPE)
|
||||
string(PREPEND normalized_url "${url_scheme}")
|
||||
endif()
|
||||
|
||||
set(${out_var} "${normalized_url}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Parses a key-value line from a .git/config or .gitmodules file
|
||||
@ -79,14 +140,22 @@ endmacro()
|
||||
# url_value
|
||||
# the url where to clone a repo from
|
||||
# in perl script it was called $base
|
||||
# e.g. '../qtbase.git', 'https://code.qt.io/playground/qlitehtml.git'
|
||||
# Examples:
|
||||
# - '../qtbase.git'
|
||||
# - 'https://code.qt.io/playground/qlitehtml.git'
|
||||
# - '../../playground/qlitehtml.git'
|
||||
# parent_repo_base_git_path
|
||||
# the base git path of the parent of the submodule
|
||||
# it is either a relative dir or a full url
|
||||
# in the perl script it was called $my_repo_base,
|
||||
# it was passed as first arg to git_clone_all_submodules,
|
||||
# it was passed the value of $subbases{$module} when doing recursive submodule cloning
|
||||
# e.g. 'qt5', 'tqtc-qt5', 'qtdeclarative.git', 'https://code.qt.io/playground/qlitehtml.git'
|
||||
# Examples:
|
||||
# - 'qt5'
|
||||
# - 'tqtc-qt5'
|
||||
# - 'qtdeclarative.git'
|
||||
# - 'qttools.git'
|
||||
# - 'https://code.qt.io/playground/qlitehtml.git'
|
||||
#
|
||||
# Outputs
|
||||
#
|
||||
@ -94,21 +163,21 @@ endmacro()
|
||||
# just the value of ${url_value}
|
||||
# ${out_var_prefix}_${submodule_name}_base_git_path
|
||||
# the whole url if it has a scheme, otherwise it's the value of
|
||||
# ${url_value} relative to ${parent_repo_base_git_path}, so all the ../ are collapsed
|
||||
# e.g. 'qtdeclarative.git'
|
||||
# 'https://code.qt.io/playground/qlitehtml.git',
|
||||
# ${url_value} relative to ${parent_repo_base_git_path}, so some of the '../' segments
|
||||
# are collapsed depending on how many path segments are available in
|
||||
# ${parent_repo_base_git_path}.
|
||||
# Examples:
|
||||
# - 'qtdeclarative.git'
|
||||
# - 'https://code.qt.io/playground/qlitehtml.git'
|
||||
# - '../playground/qlitehtml.git'
|
||||
macro(qt_ir_parse_git_url_key out_var_prefix submodule_name url_value parent_repo_base_git_path)
|
||||
qt_ir_has_url_scheme("${url_value}" has_url_scheme)
|
||||
qt_ir_parse_git_url(
|
||||
URL "${url_value}"
|
||||
OUT_VAR_HAS_URL_SCHEME has_url_scheme
|
||||
)
|
||||
if(NOT has_url_scheme)
|
||||
set(base_git_path "${parent_repo_base_git_path}/${url_value}")
|
||||
|
||||
# The exact code perl code was while ($base =~ s,(?!\.\./)[^/]+/\.\./,,g) {}
|
||||
# That got rid of ../ and ../../ in the path, but it broke down
|
||||
# when more than two ../ were present.
|
||||
# We just use ABSOLUTE to resolve the path and get rid of all ../
|
||||
# Note the empty BASE_DIR is important, otherwise the path is relative to
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}.
|
||||
get_filename_component(base_git_path "${base_git_path}" ABSOLUTE BASE_DIR "")
|
||||
qt_ir_normalize_git_url("${base_git_path}" base_git_path)
|
||||
else()
|
||||
set(base_git_path "${url_value}")
|
||||
endif()
|
||||
|
Loading…
x
Reference in New Issue
Block a user