Revision control

Copy as Markdown

#!/usr/bin/env python3
# Purpose: Run android-components tests against this application-services working tree.
# Dependencies: PyYAML
# Usage: ./automation/
import argparse
import re
import subprocess
import tempfile
from pathlib import Path
import yaml
from shared import step_msg, fatal_err, run_cmd_checked, find_app_services_root, set_gradle_substitution_path
parser = argparse.ArgumentParser(description="Run android-components tests against this application-services working tree.")
group = parser.add_mutually_exclusive_group()
help="Use a local copy of a-c instead of cloning it.")
help="Clone a different a-c repository.")
help="Branch of a-c to use.")
# XXX TODO: it would be very nice to have a "launch sample app" helper here as well.
choices=["run-tests", "do-nothing"],
help="Run the following action once a-c is set up.")
args = parser.parse_args()
local_repo_path = args.use_local_repo
remote_repo_url = args.remote_repo_url
branch = args.branch
action = args.action
repo_path = local_repo_path
if repo_path is None:
repo_path = tempfile.mkdtemp(suffix="-a-c")
if remote_repo_url is None:
remote_repo_url = DEFAULT_REMOTE_REPO_URL
step_msg(f"Cloning {remote_repo_url}")
run_cmd_checked(["git", "clone", remote_repo_url, repo_path])
if branch is not None:
run_cmd_checked(["git", "checkout", branch], cwd=repo_path)
elif branch is not None:
fatal_err("Cannot specify fenix branch when using a local repo; check it out locally and try again.")
step_msg(f"Configuring {repo_path} to autopublish appservices")
set_gradle_substitution_path(repo_path, "autoPublish.application-services.dir", find_app_services_root())
if action == "do-nothing":
elif action == "run-tests" or action is None:
# There are a lot of non-app-services-related components and we don't want to run all their tests.
# Read the build config to find which projects actually depend on appservices.
# It's a bit gross but it makes the tests run faster!
# First, find out what names a-c uses to refer to apservices projects in dependency declarations.
dep_names = set()
dep_pattern = re.compile("\s*const val ([A-Za-z0-9_]+) = .*Versions.mozilla_appservices")
with Path(repo_path, "buildSrc", "src", "main", "java", "Dependencies.kt").open() as f:
for ln in f:
m = dep_pattern.match(ln)
if m is not None:
step_msg(f"Found the following appservices dependency names: {dep_names}")
# Now find all projects that depend on one of those names.
projects = set()
with Path(repo_path, ".buildconfig.yml").open() as f:
buildconfig = yaml.safe_load(
for (project, details) in buildconfig["projects"].items():
build_dot_gradle = Path(repo_path, details["path"], "build.gradle")
if not build_dot_gradle.exists():
build_dot_gradle = Path(repo_path, details["path"], "build.gradle.kts")
if not build_dot_gradle.exists():
with as f:
for ln in f:
for dep_name in dep_names:
if dep_name in ln:
step_msg(f"Running android-components tests for {len(projects)} projects: {projects}")
run_cmd_checked(["./gradlew"] + [f"{project}:test" for project in projects], cwd=repo_path)
print("Sorry I did not understand what you wanted. Good luck!")