repopick: Clean up subprocess calls

* Use the builtin approach to decode text output
 * Drop unnecessary system shell usage
 * Use subprocess.run when we don't need its stdout

Change-Id: Ibb2aeae442b5e97828fe4e0eb783e6512288d245
This commit is contained in:
dianlujitao
2024-01-14 14:57:41 +08:00
committed by Bruno Martins
parent c0fb88f19e
commit 6f048e37fd

View File

@@ -60,7 +60,7 @@ def fetch_query_via_ssh(remote_url, query):
elif remote_url.count(":") == 1: elif remote_url.count(":") == 1:
(uri, userhost) = remote_url.split(":") (uri, userhost) = remote_url.split(":")
userhost = userhost[2:] userhost = userhost[2:]
port = 29418 port = "29418"
else: else:
raise Exception("Malformed URI: Expecting ssh://[user@]host[:port]") raise Exception("Malformed URI: Expecting ssh://[user@]host[:port]")
@@ -68,16 +68,19 @@ def fetch_query_via_ssh(remote_url, query):
[ [
"ssh", "ssh",
"-x", "-x",
"-p{0}".format(port), "-p",
port,
userhost, userhost,
"gerrit", "gerrit",
"query", "query",
"--format=JSON --patch-sets --current-patch-set", "--format",
"JSON",
"--patch-sets",
"--current-patch-set",
query, query,
] ],
text=True,
) )
if not hasattr(out, "encode"):
out = out.decode()
reviews = [] reviews = []
for line in out.split("\n"): for line in out.split("\n"):
try: try:
@@ -317,9 +320,7 @@ if __name__ == "__main__":
# If --abandon-first is given, abandon the branch before starting # If --abandon-first is given, abandon the branch before starting
if args.abandon_first: if args.abandon_first:
# Determine if the branch already exists; skip the abandon if it does not # Determine if the branch already exists; skip the abandon if it does not
plist = subprocess.check_output(["repo", "info"]) plist = subprocess.check_output(["repo", "info"], text=True)
if not hasattr(plist, "encode"):
plist = plist.decode()
needs_abandon = False needs_abandon = False
for pline in plist.splitlines(): for pline in plist.splitlines():
matchObj = re.match(r"Local Branches.*\[(.*)\]", pline) matchObj = re.match(r"Local Branches.*\[(.*)\]", pline)
@@ -332,14 +333,14 @@ if __name__ == "__main__":
# Perform the abandon only if the branch already exists # Perform the abandon only if the branch already exists
if not args.quiet: if not args.quiet:
print("Abandoning branch: %s" % args.start_branch[0]) print("Abandoning branch: %s" % args.start_branch[0])
subprocess.check_output(["repo", "abandon", args.start_branch[0]]) subprocess.run(["repo", "abandon", args.start_branch[0]])
if not args.quiet: if not args.quiet:
print("") print("")
# Get the main manifest from repo # Get the main manifest from repo
# - convert project name and revision to a path # - convert project name and revision to a path
project_name_to_data = {} project_name_to_data = {}
manifest = subprocess.check_output(["repo", "manifest"]) manifest = subprocess.check_output(["repo", "manifest"], text=True)
xml_root = ElementTree.fromstring(manifest) xml_root = ElementTree.fromstring(manifest)
projects = xml_root.findall("project") projects = xml_root.findall("project")
remotes = xml_root.findall("remote") remotes = xml_root.findall("remote")
@@ -528,16 +529,22 @@ if __name__ == "__main__":
# If --start-branch is given, create the branch (more than once per path is okay; repo ignores gracefully) # If --start-branch is given, create the branch (more than once per path is okay; repo ignores gracefully)
if args.start_branch: if args.start_branch:
subprocess.check_output( subprocess.run(["repo", "start", args.start_branch[0], project_path])
["repo", "start", args.start_branch[0], project_path]
)
# Determine the maximum commits to check already picked changes # Determine the maximum commits to check already picked changes
check_picked_count = args.check_picked check_picked_count = args.check_picked
max_count = "--max-count={0}".format(check_picked_count + 1)
branch_commits_count = int( branch_commits_count = int(
subprocess.check_output( subprocess.check_output(
["git", "rev-list", "--count", max_count, "HEAD"], cwd=project_path [
"git",
"rev-list",
"--count",
"--max-count",
str(check_picked_count + 1),
"HEAD",
],
cwd=project_path,
text=True,
) )
) )
if branch_commits_count <= check_picked_count: if branch_commits_count <= check_picked_count:
@@ -553,11 +560,8 @@ if __name__ == "__main__":
): ):
continue continue
output = subprocess.check_output( output = subprocess.check_output(
["git", "show", "-q", "HEAD~{0}".format(i)], cwd=project_path ["git", "show", "-q", f"HEAD~{i}"], cwd=project_path, text=True
) )
# make sure we have a string on Python 3
if isinstance(output, bytes):
output = output.decode("utf-8")
output = output.split() output = output.split()
if "Change-Id:" in output: if "Change-Id:" in output:
head_change_id = "" head_change_id = ""
@@ -591,20 +595,23 @@ if __name__ == "__main__":
else: else:
method = "ssh" method = "ssh"
if args.pull:
cmd = ["git", "pull", "--no-edit"]
else:
cmd = ["git", "fetch"]
if args.quiet:
cmd.append("--quiet")
cmd.extend(["", item["fetch"][method]["ref"]])
# Try fetching from GitHub first if using default gerrit # Try fetching from GitHub first if using default gerrit
if args.gerrit == default_gerrit: if args.gerrit == default_gerrit:
if args.verbose: if args.verbose:
print("Trying to fetch the change from GitHub") print("Trying to fetch the change from GitHub")
if args.pull: cmd[-2] = "github"
cmd = ["git pull --no-edit github", item["fetch"][method]["ref"]] if not args.quiet:
else:
cmd = ["git fetch github", item["fetch"][method]["ref"]]
if args.quiet:
cmd.append("--quiet")
else:
print(cmd) print(cmd)
result = subprocess.call([" ".join(cmd)], cwd=project_path, shell=True) result = subprocess.call(cmd, cwd=project_path)
FETCH_HEAD = "{0}/.git/FETCH_HEAD".format(project_path) FETCH_HEAD = "{0}/.git/FETCH_HEAD".format(project_path)
if result != 0 and os.stat(FETCH_HEAD).st_size != 0: if result != 0 and os.stat(FETCH_HEAD).st_size != 0:
print("ERROR: git command failed") print("ERROR: git command failed")
@@ -620,60 +627,47 @@ if __name__ == "__main__":
else: else:
print("Fetching from {0}".format(args.gerrit)) print("Fetching from {0}".format(args.gerrit))
if args.pull: cmd[-2] = item["fetch"][method]["url"]
cmd = [ if not args.quiet:
"git pull --no-edit",
item["fetch"][method]["url"],
item["fetch"][method]["ref"],
]
else:
cmd = [
"git fetch",
item["fetch"][method]["url"],
item["fetch"][method]["ref"],
]
if args.quiet:
cmd.append("--quiet")
else:
print(cmd) print(cmd)
result = subprocess.call([" ".join(cmd)], cwd=project_path, shell=True) result = subprocess.call(cmd, cwd=project_path)
if result != 0: if result != 0:
print("ERROR: git command failed") print("ERROR: git command failed")
sys.exit(result) sys.exit(result)
# Perform the cherry-pick # Perform the cherry-pick
if not args.pull: if not args.pull:
cmd = ["git cherry-pick --ff FETCH_HEAD"]
if args.quiet: if args.quiet:
cmd_out = open(os.devnull, "wb") cmd_out = subprocess.DEVNULL
else: else:
cmd_out = None cmd_out = None
result = subprocess.call( result = subprocess.call(
cmd, cwd=project_path, shell=True, stdout=cmd_out, stderr=cmd_out ["git", "cherry-pick", "--ff", item["revision"]],
cwd=project_path,
stdout=cmd_out,
stderr=cmd_out,
) )
if result != 0: if result != 0:
cmd = ["git diff-index --quiet HEAD --"]
result = subprocess.call( result = subprocess.call(
cmd, cwd=project_path, shell=True, stdout=cmd_out, stderr=cmd_out ["git", "diff-index", "--quiet", "HEAD", "--"],
cwd=project_path,
stdout=cmd_out,
stderr=cmd_out,
) )
if result == 0: if result == 0:
print( print(
"WARNING: git command resulted with an empty commit, aborting cherry-pick" "WARNING: git command resulted with an empty commit, aborting cherry-pick"
) )
cmd = ["git cherry-pick --abort"]
subprocess.call( subprocess.call(
cmd, ["git", "cherry-pick", "--abort"],
cwd=project_path, cwd=project_path,
shell=True,
stdout=cmd_out, stdout=cmd_out,
stderr=cmd_out, stderr=cmd_out,
) )
elif args.reset: elif args.reset:
print("ERROR: git command failed, aborting cherry-pick") print("ERROR: git command failed, aborting cherry-pick")
cmd = ["git cherry-pick --abort"]
subprocess.call( subprocess.call(
cmd, ["git", "cherry-pick", "--abort"],
cwd=project_path, cwd=project_path,
shell=True,
stdout=cmd_out, stdout=cmd_out,
stderr=cmd_out, stderr=cmd_out,
) )