From 211b278ad0dc6620ea797796a53ed223fc26a800 Mon Sep 17 00:00:00 2001 From: Paul Cristian Sarbu Date: Tue, 17 Dec 2024 12:22:17 +0100 Subject: just-lock: Try also mirrors when importing known commit from Git repos When commit to fetch is known, check mirrors before going to the main URL. While there, ensure the context for logging in the checkout method is not replaced, but appended to. --- bin/just-lock.py | 81 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 16 deletions(-) (limited to 'bin/just-lock.py') diff --git a/bin/just-lock.py b/bin/just-lock.py index 3e22be0a..5156c8f2 100755 --- a/bin/just-lock.py +++ b/bin/just-lock.py @@ -425,40 +425,88 @@ def handle_import(remote_type: str, remote_stub: Dict[str, Any], return core_repos +### +# Git utils +## + + +def git_url_is_path(url: str) -> Optional[str]: + """Get the path a URL refers to if it is in a supported path format, + and None otherwise.""" + if url.startswith('/'): + return url + if url.startswith('./'): + return url[len('./'):] + if url.startswith('file://'): + return url[len('file://'):] + return None + + ### # Import from Git ## def git_checkout(url: str, branch: str, *, commit: Optional[str], - mirrors: List[str], - inherit_env: List[str]) -> Tuple[str, Dict[str, Any], str]: + mirrors: List[str], inherit_env: List[str], + fail_context: str) -> Tuple[str, Dict[str, Any], str]: """Clone a given remote Git repository and checkout a specified branch. Return the checkout location, the repository description stub to use for rewriting 'file'-type dependencies, and the temp dir to later clean up.""" workdir: str = tempfile.mkdtemp() srcdir: str = os.path.join(workdir, "src") + fetch_url = git_url_is_path(url) + if fetch_url is None: + fetch_url = url + else: + fetch_url = os.path.abspath(fetch_url) - fail_context: str = "While checking out branch %r of %r:" % (branch, url) + fail_context += "While checking out branch %r of %r:\n" % (branch, url) if commit is None: - # If no commit given, do shallow clone and get HEAD commit - run_cmd(g_LAUNCHER + - [g_GIT, "clone", "-b", branch, "--depth", "1", url, "src"], - cwd=workdir, - fail_context=fail_context) + # If no commit given, do shallow clone and get HEAD commit from + # definitive source location + run_cmd( + g_LAUNCHER + + [g_GIT, "clone", "-b", branch, "--depth", "1", fetch_url, "src"], + cwd=workdir, + fail_context=fail_context) commit = run_cmd(g_LAUNCHER + [g_GIT, "log", "-n", "1", "--pretty=%H"], cwd=srcdir, stdout=subprocess.PIPE, fail_context=fail_context)[0].decode('utf-8').strip() report("Importing remote Git commit %s" % (commit, )) else: - # To get a specified commit, clone the specified branch fully and reset - run_cmd(g_LAUNCHER + [g_GIT, "clone", "-b", branch, url, "src"], - cwd=workdir, - fail_context=fail_context) - run_cmd(g_LAUNCHER + [g_GIT, "reset", "--hard", commit], - cwd=srcdir, - fail_context=fail_context) + # To get a specified commit, clone the specified branch fully and reset; + # Try mirrors first, as they are closer + cloned: bool = False + for source in mirrors: + fetch_source = git_url_is_path(source) + if fetch_source is None: + fetch_source = source + else: + fetch_source = os.path.abspath(fetch_source) + if (run_cmd(g_LAUNCHER + + [g_GIT, "clone", "-b", branch, fetch_source, "src"], + cwd=workdir, + fail_context=None)[1] == 0 + and run_cmd(g_LAUNCHER + [g_GIT, "reset", "--hard", commit], + cwd=srcdir, + fail_context=None)[1] == 0): + cloned = True + break + if not cloned: + # Try definitive source location + if (run_cmd(g_LAUNCHER + + [g_GIT, "clone", "-b", branch, fetch_url, "src"], + cwd=workdir, + fail_context=None)[1] == 0 + and run_cmd(g_LAUNCHER + [g_GIT, "reset", "--hard", commit], + cwd=srcdir, + fail_context=None)[1] != 0): + fail(fail_context + + "Failed to clone Git repository.\nTried locations:\n%s" % + ("\n".join(["\t%s" % (x, ) for x in mirrors + [url]]), )) + # Prepare the description stub used to rewrite "file"-type dependencies repo_stub: Dict[str, Any] = { "type": "git", @@ -538,7 +586,8 @@ def import_from_git(core_repos: Json, imports_entry: Json) -> Json: branch, commit=commit, mirrors=mirrors, - inherit_env=inherit_env) + inherit_env=inherit_env, + fail_context=fail_context) # Read in the foreign config file if foreign_config_file: -- cgit v1.2.3