|
@@ -13,9 +13,11 @@ import base64
|
|
|
import os
|
|
|
import platform
|
|
|
import sys
|
|
|
+import concurrent.futures
|
|
|
|
|
|
import gclient_utils
|
|
|
-from gerrit_util import CreateHttpConn, ReadHttpResponse
|
|
|
+from gerrit_util import (CreateHttpConn, ReadHttpResponse,
|
|
|
+ MAX_CONCURRENT_CONNECTION)
|
|
|
import subprocess2
|
|
|
|
|
|
DEV_NULL = "/dev/null"
|
|
@@ -89,6 +91,28 @@ def _process_diff(diff: str, src_root: str, dst_root: str) -> str:
|
|
|
return header + HEADER_DELIMITER + body
|
|
|
|
|
|
|
|
|
+def _create_diff(host: str, repo: str, ref: str, root: str, file: str) -> str:
|
|
|
+ new_file = os.path.join(root, file)
|
|
|
+ if not os.path.exists(new_file):
|
|
|
+ new_file = None
|
|
|
+
|
|
|
+ with gclient_utils.temporary_directory() as tmp_root:
|
|
|
+ old_file = None
|
|
|
+ old_content = fetch_content(host, repo, ref, file)
|
|
|
+ if old_content:
|
|
|
+ old_file = os.path.join(tmp_root, file)
|
|
|
+ os.makedirs(os.path.dirname(old_file), exist_ok=True)
|
|
|
+ with open(old_file, "w") as f:
|
|
|
+ f.write(old_content)
|
|
|
+
|
|
|
+ if not old_file and not new_file:
|
|
|
+ raise RuntimeError(f"Could not access file {file} from {root} "
|
|
|
+ f"or from {host}/{repo}:{ref}.")
|
|
|
+
|
|
|
+ diff = git_diff(old_file, new_file)
|
|
|
+ return _process_diff(diff, tmp_root, root)
|
|
|
+
|
|
|
+
|
|
|
def create_diffs(host: str, repo: str, ref: str, root: str,
|
|
|
files: list[str]) -> dict[str, str]:
|
|
|
"""Calculates diffs of files in a directory against a commit.
|
|
@@ -107,28 +131,15 @@ def create_diffs(host: str, repo: str, ref: str, root: str,
|
|
|
RuntimeError: If a file is missing in both the root and the repo.
|
|
|
"""
|
|
|
diffs = {}
|
|
|
- with gclient_utils.temporary_directory() as tmp_root:
|
|
|
- # TODO(gavinmak): Parallelize fetching content.
|
|
|
- for file in files:
|
|
|
- new_file = os.path.join(root, file)
|
|
|
- if not os.path.exists(new_file):
|
|
|
- new_file = None
|
|
|
-
|
|
|
- old_file = None
|
|
|
- old_content = fetch_content(host, repo, ref, file)
|
|
|
- if old_content:
|
|
|
- old_file = os.path.join(tmp_root, file)
|
|
|
- os.makedirs(os.path.dirname(old_file), exist_ok=True)
|
|
|
- with open(old_file, "w") as f:
|
|
|
- f.write(old_content)
|
|
|
-
|
|
|
- if not old_file and not new_file:
|
|
|
- raise RuntimeError(f"Could not access file {file} from {root} "
|
|
|
- f"or from {host}/{repo}:{ref}.")
|
|
|
-
|
|
|
- diff = git_diff(old_file, new_file)
|
|
|
- diffs[file] = _process_diff(diff, tmp_root, root)
|
|
|
-
|
|
|
+ with concurrent.futures.ThreadPoolExecutor(
|
|
|
+ max_workers=MAX_CONCURRENT_CONNECTION) as executor:
|
|
|
+ futures_to_file = {
|
|
|
+ executor.submit(_create_diff, host, repo, ref, root, file): file
|
|
|
+ for file in files
|
|
|
+ }
|
|
|
+ for future in concurrent.futures.as_completed(futures_to_file):
|
|
|
+ file = futures_to_file[future]
|
|
|
+ diffs[file] = future.result()
|
|
|
return diffs
|
|
|
|
|
|
|