blob: ef83ac5def97c0d35b84b58666f178c59b1e5514 [file] [log] [blame]
# Copyright 2022 The IREE Authors
#
# Licensed under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
import os
import re
import shlex
import shutil
import subprocess
from typing import Tuple
_repo_root = None
def get_repo_root() -> str:
global _repo_root
if _repo_root is None:
_repo_root = os.getcwd()
_validate_repo_root()
return _repo_root
def get_submodule_root(submodule) -> str:
path = os.path.join(get_repo_root(), "third_party", submodule)
if not os.path.isdir(path):
raise SystemExit(f"Could not find submodule: {path}")
return path
def _validate_repo_root():
# Look for something we know is there.
known_dir = os.path.join(_repo_root, "compiler")
if not os.path.isdir(known_dir):
raise SystemExit(f"ERROR: Must run from the iree repository root. "
f"Actually in: {_repo_root}")
def git_setup_remote(remote_alias, url, *, repo_dir=None):
needs_create = False
try:
existing_url = git_exec(["remote", "get-url", remote_alias],
capture_output=True,
repo_dir=repo_dir,
quiet=True)
existing_url = existing_url.strip()
if existing_url == url:
return
except subprocess.CalledProcessError:
# Does not exist.
needs_create = True
if needs_create:
git_exec(["remote", "add", "--no-tags", remote_alias, url],
repo_dir=repo_dir)
else:
git_exec(["remote", "set-url", remote_alias, url], repo_dir=repo_dir)
def git_is_porcelain(*, repo_dir=None):
output = git_exec(["status", "--porcelain", "--untracked-files=no"],
capture_output=True,
quiet=True,
repo_dir=repo_dir).strip()
return not bool(output)
def git_check_porcelain(*, repo_dir=None):
output = git_exec(["status", "--porcelain", "--untracked-files=no"],
capture_output=True,
quiet=True,
repo_dir=repo_dir).strip()
if output:
actual_repo_dir = get_repo_root() if repo_dir is None else repo_dir
raise SystemExit(
f"ERROR: git directory {actual_repo_dir} is not clean. "
f"Please stash changes:\n{output}")
def git_fetch(*, repository=None, ref=None, repo_dir=None):
args = ["fetch"]
if repository:
args.append(repository)
if ref is not None:
args.append(ref)
git_exec(args, repo_dir=repo_dir)
def git_checkout(ref, *, repo_dir=None):
git_exec(["checkout", ref], repo_dir=repo_dir)
def git_create_branch(branch_name,
*,
checkout=True,
ref=None,
force=False,
repo_dir=None):
branch_args = ["branch"]
if force:
branch_args.append("-f")
branch_args.append(branch_name)
if ref is not None:
branch_args.append(ref)
git_exec(branch_args, repo_dir=repo_dir)
if checkout:
git_exec(["checkout", branch_name], repo_dir=repo_dir)
def git_push_branch(repository, branch_name, *, force=False, repo_dir=None):
push_args = ["push", "--set-upstream"]
if force:
push_args.append("-f")
push_args.append(repository)
push_args.append(f"{branch_name}:{branch_name}")
git_exec(push_args, repo_dir=repo_dir)
def git_branch_exists(branch_name, *, repo_dir=None):
output = git_exec(["branch", "-l", branch_name],
repo_dir=repo_dir,
quiet=True,
capture_output=True).strip()
return bool(output)
def git_submodule_set_origin(path, *, url=None, branch=None, repo_dir=None):
if url is not None:
git_exec(["submodule", "set-url", "--", path, url], repo_dir=repo_dir)
if branch is not None:
try:
if branch == "--default":
git_exec(["submodule", "set-branch", "--default", "--", path],
repo_dir=repo_dir)
else:
git_exec([
"submodule", "set-branch", "--branch", branch, "--", path
],
repo_dir=repo_dir)
except subprocess.CalledProcessError:
# The set-branch command returns 0 on change and !0 on no change.
# This is a bit unfortunate.
...
def git_reset(ref, *, hard=True, repo_dir=None):
args = ["reset"]
if hard:
args.append("--hard")
args.append(ref)
git_exec(args, repo_dir=repo_dir)
def git_current_commit(*, repo_dir=None) -> Tuple[str, str]:
output = git_exec(["log", "-n", "1", "--pretty=format:%H (%ci): %s"],
capture_output=True,
repo_dir=repo_dir,
quiet=True)
output = output.strip()
parts = output.split(" ")
# Return commit, full_summary
return parts[0], output
def git_create_commit(*, message, add_all=False, repo_dir=None):
if add_all:
git_exec(["add", "-A"], repo_dir=repo_dir)
git_exec(["commit", "-m", message])
def git_ls_remote_branches(repository_url, *, filter=None, repo_dir=None):
args = ["ls-remote", "-h", repository_url]
if filter:
args.extend(filter)
output = git_exec(args, quiet=True, capture_output=True)
lines = output.strip().splitlines(keepends=False)
# Format is <commit> refs/heads/branch_name
def extract_branch(line):
parts = re.split("\\s+", line)
ref = parts[1]
prefix = "refs/heads/"
if ref.startswith(prefix):
ref = ref[len(prefix):]
return ref
return [extract_branch(l) for l in lines]
def git_exec(args, *, repo_dir=None, quiet=False, capture_output=False):
full_args = ["git"] + args
full_args_quoted = [shlex.quote(a) for a in full_args]
if not repo_dir:
repo_dir = get_repo_root()
if not quiet:
print(f" ++ EXEC: (cd {repo_dir} && {' '.join(full_args_quoted)})")
if capture_output:
return subprocess.check_output(full_args, cwd=repo_dir).decode("utf-8")
else:
subprocess.check_call(full_args, cwd=repo_dir)