Files
android_development/tools/repo_diff/repo_diff_android.py
Po-Chien Hsueh fb4ba49c20 Rename exclusions.txt in the script
The file name has been changed in a previous CL

Test: run the script
Change-Id: I7cc1b183989ae674e14e65321e09c51d5c689ad0
2017-09-28 16:55:31 +08:00

173 lines
5.3 KiB
Python

#!/usr/bin/python
"""Diff a repo (downstream) and its upstream.
This script:
1. Downloads a repo source tree with specified manifest URL, branch
and release tag.
2. Retrieves the BUILD_ID from $downstream/build/core/build_id.mk.
3. Downloads the upstream using the BUILD_ID.
4. Diffs each project in these two repos.
"""
import argparse
import os
import subprocess
import repo_diff_trees
HELP_MSG = "Diff a repo (downstream) and its upstream"
DOWNSTREAM_WORKSPACE = "downstream"
UPSTREAM_WORKSPACE = "upstream"
DEFAULT_MANIFEST_URL = "https://android.googlesource.com/platform/manifest"
DEFAULT_MANIFEST_BRANCH = "android-8.0.0_r10"
DEFAULT_UPSTREAM_MANIFEST_URL = "https://android.googlesource.com/platform/manifest"
DEFAULT_UPSTREAM_MANIFEST_BRANCH = "android-8.0.0_r1"
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
DEFAULT_EXCLUSIONS_FILE = os.path.join(SCRIPT_DIR, "android_exclusions.txt")
def parse_args():
"""Parse args."""
parser = argparse.ArgumentParser(description=HELP_MSG)
parser.add_argument("-u", "--manifest-url",
help="manifest url",
default=DEFAULT_MANIFEST_URL)
parser.add_argument("-b", "--manifest-branch",
help="manifest branch",
default=DEFAULT_MANIFEST_BRANCH)
parser.add_argument("-r", "--upstream-manifest-url",
help="upstream manifest url",
default=DEFAULT_UPSTREAM_MANIFEST_URL)
parser.add_argument("-a", "--upstream-manifest-branch",
help="upstream manifest branch",
default=DEFAULT_UPSTREAM_MANIFEST_BRANCH)
parser.add_argument("-e", "--exclusions-file",
help="exclusions file",
default=DEFAULT_EXCLUSIONS_FILE)
parser.add_argument("-t", "--tag",
help="release tag (optional). If not set then will"
"sync the latest in the branch.")
return parser.parse_args()
def repo_init(url, rev, workspace):
"""Repo init with specific url and rev.
Args:
url: manifest url
rev: manifest branch, or rev
workspace: the folder to init and sync code
"""
print("repo init:\n url: %s\n rev: %s\n workspace: %s" %
(url, rev, workspace))
subprocess.check_output("repo init --manifest-url=%s --manifest-branch=%s" %
(url, rev), cwd=workspace, shell=True)
def repo_sync(workspace, retry=5):
"""Repo sync."""
count = 0
while count < retry:
count += 1
print("repo sync (retry=%d/%d):\n workspace: %s" %
(count, retry, workspace))
try:
subprocess.check_output(("repo sync --jobs=24 --current-branch --quiet "
"--no-tags --no-clone-bundle"),
cwd=workspace, shell=True)
except subprocess.CalledProcessError as e:
print "Error: %s" % e.output
# Stop retrying if the repo sync was successful
else:
break
def get_commit_with_keyword(project_path, keyword):
"""Get the latest commit in $project_path with the specific keyword."""
return subprocess.check_output(("git -C %s "
"rev-list --max-count=1 --grep=\"%s\" "
"HEAD") %
(project_path, keyword), shell=True).rstrip()
def get_build_id(workspace):
"""Get BUILD_ID defined in $workspace/build/core/build_id.mk."""
path = os.path.join(workspace, "build", "core", "build_id.mk")
return subprocess.check_output("source %s && echo $BUILD_ID" % path,
shell=True).rstrip()
def repo_sync_specific_release(url, branch, tag, workspace):
"""Repo sync source with the specific release tag."""
if not os.path.exists(workspace):
os.makedirs(workspace)
manifest_path = os.path.join(workspace, ".repo", "manifests")
repo_init(url, branch, workspace)
if tag:
rev = get_commit_with_keyword(manifest_path, tag)
if not rev:
raise(ValueError("could not find a manifest revision for tag " + tag))
repo_init(url, rev, workspace)
repo_sync(workspace)
def diff(manifest_url, manifest_branch, tag, upstream_manifest_url,
upstream_manifest_branch, exclusions_file):
"""Syncs and diffs an Android workspace against an upstream workspace."""
workspace = os.path.abspath(DOWNSTREAM_WORKSPACE)
upstream_workspace = os.path.abspath(UPSTREAM_WORKSPACE)
# repo sync downstream source tree
repo_sync_specific_release(
manifest_url,
manifest_branch,
tag,
workspace)
build_id = None
if tag:
# get the build_id so that we know which rev of upstream we need
build_id = get_build_id(workspace)
if not build_id:
raise(ValueError("Error: could not find the Build ID of " + workspace))
# repo sync upstream source tree
repo_sync_specific_release(
upstream_manifest_url,
upstream_manifest_branch,
build_id,
upstream_workspace)
# do the comparison
repo_diff_trees.diff(
upstream_workspace,
workspace,
os.path.abspath("project.csv"),
os.path.abspath("commit.csv"),
os.path.abspath(exclusions_file),
)
def main():
args = parse_args()
diff(args.manifest_url, args.manifest_branch, args.tag,
args.upstream_manifest_url, args.upstream_manifest_branch,
args.exclusions_file)
if __name__ == "__main__":
main()