summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2025-01-22 13:15:47 +0100
committerPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2025-02-20 15:33:53 +0100
commit95f8cc7ed662f6d79f889a0a03b82d832748024d (patch)
tree79650004b9c91887e88e6c50175f020d650b49fe
parentd42e1f7f8b9c60a0d1fe3df98802060eb5b0ef64 (diff)
downloadjustbuild-95f8cc7ed662f6d79f889a0a03b82d832748024d.tar.gz
just-lock: Add support for cloning 'git tree' repositories
-rwxr-xr-xbin/just-lock.py81
1 files changed, 76 insertions, 5 deletions
diff --git a/bin/just-lock.py b/bin/just-lock.py
index 30cfb978..30c048ea 100755
--- a/bin/just-lock.py
+++ b/bin/just-lock.py
@@ -2259,6 +2259,78 @@ def clone_repo(repos: Json, known_repo: str, deps_chain: List[str],
separators=(',', ':')).encode('utf-8'))
return distdir_tree_id
+ def process_git_tree(repository: Json, *, clone_to: str,
+ fail_context: str) -> str:
+ """Process a git tree repository and return the tree id."""
+ # Parse tree id
+ tree_id: str = repository.get("id", None)
+ if not isinstance(tree_id, str):
+ fail(fail_context +
+ "Expected field \"id\" to be a string, but found:\n%r" %
+ (json.dumps(tree_id, indent=2), ))
+ # If tree is in Git cache, stage it from there
+ if (try_read_object_from_repo(tree_id, "tree", upstream=None)
+ is not None):
+ os.makedirs(clone_to, exist_ok=True)
+ stage_git_entry(fpath=clone_to,
+ obj_id=tree_id,
+ obj_type=ObjectType.DIR,
+ upstream=None,
+ fail_context=fail_context)
+ return tree_id
+ # Parse the other needed fields
+ command: List[str] = repository.get("cmd", None)
+ if not isinstance(command, list):
+ fail(fail_context +
+ "Expected field \"cmd\" to be a list, but found:\n%r" %
+ (json.dumps(command, indent=2), ))
+ command_env: Optional[Json] = repository.get("env", {})
+ if command_env is not None and not isinstance(command_env, dict):
+ fail(fail_context +
+ "Expected field \"env\" to be a map, but found:\n%r" %
+ (json.dumps(command_env, indent=2), ))
+ inherit_env: Optional[List[str]] = repository.get("inherit env", [])
+ if inherit_env is not None and not isinstance(inherit_env, list):
+ fail(fail_context +
+ "Expected field \"inherit env\" to be a list, but found:\n%r" %
+ (json.dumps(inherit_env, indent=2), ))
+ # Get the actual command environment
+ curr_env = os.environ
+ new_envs = {}
+ for envar in inherit_env:
+ if envar in curr_env:
+ new_envs[envar] = curr_env[envar]
+ command_env = dict(command_env, **new_envs)
+ # Generate the content
+ os.makedirs(clone_to, exist_ok=True)
+ run_cmd(g_LAUNCHER + command,
+ cwd=clone_to,
+ env=command_env,
+ fail_context=fail_context)
+ # Cache the content; to not pollute the clone folder, do it via a
+ # temporary location
+ workdir: str = create_tmp_dir(type="git-tree-checkout")
+ try:
+ shutil.copytree(clone_to,
+ workdir,
+ symlinks=True,
+ dirs_exist_ok=True)
+ except Exception as ex:
+ report("Copying file path %s failed with:\n%r" % (clone_to, ex))
+ imported_tree_id = import_to_git(workdir,
+ repo_type="git-tree",
+ content_id=tree_id,
+ fail_context=fail_context)
+ if imported_tree_id != tree_id:
+ # Allow, but give warning
+ warn(
+ fail_context +
+ "Tree mismatch in \"git tree\" repository: expected %s, got %s\n"
+ % (tree_id, imported_tree_id))
+ try_rmtree(workdir)
+ # Always report the id of the actual content
+ return imported_tree_id
+
def follow_binding(repos: Json, *, repo_name: str, dep_name: str,
fail_context: str) -> str:
"""Follow a named binding."""
@@ -2341,11 +2413,10 @@ def clone_repo(repos: Json, known_repo: str, deps_chain: List[str],
report("\tCloned distdir %s to %s" % (content_id, clone_to))
elif repo_type == "git tree":
- #TODO(psarbu): Implement git tree cloning
- warn(fail_context +
- "Cloning from \"%s\" repositories not yet implemented!" %
- (repo_type, ))
- result = None
+ tree_id = process_git_tree(repository,
+ clone_to=clone_to,
+ fail_context=fail_context)
+ report("\tCloned git tree %s to %s" % (tree_id, clone_to))
elif repo_type in ["computed", "tree structure"]:
warn(fail_context + "Cloning not supported for type %r. Skipping" %