mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 10:18:41 +02:00 
			
		
		
		
	Generated by `./mach lint -l black --fix taskcluster/android_taskgraph/ taskcluster/scripts/lint/ taskcluster/scripts/write-dummy-secret.py mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/conftest.py mobile/android/fenix/automation/taskcluster/androidTest/parse-ui-test-fromfile.py mobile/android/focus-android/automation/taskcluster/androidTest/parse-ui-test*` Differential Revision: https://phabricator.services.mozilla.com/D201457
		
			
				
	
	
		
			165 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			165 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
#!/usr/bin/env python3
 | 
						|
 | 
						|
# This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
# License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
						|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
						|
 | 
						|
 | 
						|
import argparse
 | 
						|
import json
 | 
						|
import logging
 | 
						|
import os
 | 
						|
import re
 | 
						|
import subprocess
 | 
						|
import sys
 | 
						|
from collections import defaultdict
 | 
						|
 | 
						|
import yaml
 | 
						|
from mergedeep import merge
 | 
						|
 | 
						|
logger = logging.getLogger(__name__)
 | 
						|
 | 
						|
_DEFAULT_GRADLE_COMMAND = ("./gradlew", "--console=plain", "--no-parallel")
 | 
						|
_LOCAL_DEPENDENCY_PATTERN = re.compile(
 | 
						|
    r"(\+|\\)--- project :(?P<local_dependency_name>\S+)\s?.*"
 | 
						|
)
 | 
						|
 | 
						|
 | 
						|
def _get_upstream_deps_per_gradle_project(gradle_root, existing_build_config):
 | 
						|
    project_dependencies = defaultdict(set)
 | 
						|
    gradle_projects = _get_gradle_projects(gradle_root, existing_build_config)
 | 
						|
 | 
						|
    logger.info(f"Looking for dependencies in {gradle_root}")
 | 
						|
 | 
						|
    # This is eventually going to fail if there's ever enough projects to make the
 | 
						|
    # command line too long. If that happens, we'll need to split this list up and
 | 
						|
    # run gradle more than once.
 | 
						|
    cmd = list(_DEFAULT_GRADLE_COMMAND)
 | 
						|
    cmd.extend(
 | 
						|
        [f"{gradle_project}:dependencies" for gradle_project in sorted(gradle_projects)]
 | 
						|
    )
 | 
						|
 | 
						|
    # Parsing output like this is not ideal but bhearsum couldn't find a way
 | 
						|
    # to get the dependencies printed in a better format. If we could convince
 | 
						|
    # gradle to spit out JSON that would be much better.
 | 
						|
    # This is filed as https://bugzilla.mozilla.org/show_bug.cgi?id=1795152
 | 
						|
    current_project_name = None
 | 
						|
    print(f"Running command: {' '.join(cmd)}")
 | 
						|
    try:
 | 
						|
        output = subprocess.check_output(cmd, universal_newlines=True, cwd=gradle_root)
 | 
						|
    except subprocess.CalledProcessError as cpe:
 | 
						|
        print(cpe.output)
 | 
						|
        raise
 | 
						|
    for line in output.splitlines():
 | 
						|
        # If we find the start of a new component section, update our tracking
 | 
						|
        # variable
 | 
						|
        if line.startswith("Project"):
 | 
						|
            current_project_name = line.split(":")[1].strip("'")
 | 
						|
 | 
						|
        # If we find a new local dependency, add it.
 | 
						|
        local_dep_match = _LOCAL_DEPENDENCY_PATTERN.search(line)
 | 
						|
        if local_dep_match:
 | 
						|
            local_dependency_name = local_dep_match.group("local_dependency_name")
 | 
						|
            if (
 | 
						|
                local_dependency_name != current_project_name
 | 
						|
                # These lint rules are not part of android-components
 | 
						|
                and local_dependency_name != "mozilla-lint-rules"
 | 
						|
            ):
 | 
						|
                project_dependencies[current_project_name].add(local_dependency_name)
 | 
						|
 | 
						|
    return {
 | 
						|
        project_name: sorted(project_dependencies[project_name])
 | 
						|
        for project_name in gradle_projects
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
def _get_gradle_projects(gradle_root, existing_build_config):
 | 
						|
    if gradle_root.endswith("android-components"):
 | 
						|
        return list(existing_build_config["projects"].keys())
 | 
						|
    elif gradle_root.endswith("focus-android"):
 | 
						|
        return ["app"]
 | 
						|
    elif gradle_root.endswith("fenix"):
 | 
						|
        return ["app"]
 | 
						|
 | 
						|
    raise NotImplementedError(f"Cannot find gradle projects for {gradle_root}")
 | 
						|
 | 
						|
 | 
						|
def is_dir(string):
 | 
						|
    if os.path.isdir(string):
 | 
						|
        return string
 | 
						|
    else:
 | 
						|
        raise argparse.ArgumentTypeError(f'"{string}" is not a directory')
 | 
						|
 | 
						|
 | 
						|
def _parse_args(cmdln_args):
 | 
						|
    parser = argparse.ArgumentParser(
 | 
						|
        description="Calls gradle and generate json file with dependencies"
 | 
						|
    )
 | 
						|
    parser.add_argument(
 | 
						|
        "gradle_root",
 | 
						|
        metavar="GRADLE_ROOT",
 | 
						|
        type=is_dir,
 | 
						|
        help="The directory where to call gradle from",
 | 
						|
    )
 | 
						|
    return parser.parse_args(args=cmdln_args)
 | 
						|
 | 
						|
 | 
						|
def _set_logging_config():
 | 
						|
    logging.basicConfig(
 | 
						|
        level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s"
 | 
						|
    )
 | 
						|
 | 
						|
 | 
						|
def _merge_build_config(
 | 
						|
    existing_build_config, upstream_deps_per_project, variants_config
 | 
						|
):
 | 
						|
    updated_build_config = {
 | 
						|
        "projects": {
 | 
						|
            project: {"upstream_dependencies": deps}
 | 
						|
            for project, deps in upstream_deps_per_project.items()
 | 
						|
        }
 | 
						|
    }
 | 
						|
    updated_variant_config = {"variants": variants_config} if variants_config else {}
 | 
						|
    return merge(existing_build_config, updated_build_config, updated_variant_config)
 | 
						|
 | 
						|
 | 
						|
def _get_variants(gradle_root):
 | 
						|
    cmd = list(_DEFAULT_GRADLE_COMMAND) + ["printVariants"]
 | 
						|
    output_lines = subprocess.check_output(
 | 
						|
        cmd, universal_newlines=True, cwd=gradle_root
 | 
						|
    ).splitlines()
 | 
						|
    variants_line = [line for line in output_lines if line.startswith("variants: ")][0]
 | 
						|
    variants_json = variants_line.split(" ", 1)[1]
 | 
						|
    return json.loads(variants_json)
 | 
						|
 | 
						|
 | 
						|
def _should_print_variants(gradle_root):
 | 
						|
    return gradle_root.endswith("fenix") or gradle_root.endswith("focus-android")
 | 
						|
 | 
						|
 | 
						|
def main():
 | 
						|
    args = _parse_args(sys.argv[1:])
 | 
						|
    gradle_root = args.gradle_root
 | 
						|
    build_config_file = os.path.join(gradle_root, ".buildconfig.yml")
 | 
						|
    _set_logging_config()
 | 
						|
 | 
						|
    with open(build_config_file) as f:
 | 
						|
        existing_build_config = yaml.safe_load(f)
 | 
						|
 | 
						|
    upstream_deps_per_project = _get_upstream_deps_per_gradle_project(
 | 
						|
        gradle_root, existing_build_config
 | 
						|
    )
 | 
						|
 | 
						|
    variants_config = (
 | 
						|
        _get_variants(gradle_root) if _should_print_variants(gradle_root) else {}
 | 
						|
    )
 | 
						|
    merged_build_config = _merge_build_config(
 | 
						|
        existing_build_config, upstream_deps_per_project, variants_config
 | 
						|
    )
 | 
						|
 | 
						|
    with open(build_config_file, "w") as f:
 | 
						|
        yaml.safe_dump(merged_build_config, f)
 | 
						|
    logger.info(f"Updated {build_config_file} with latest gradle config!")
 | 
						|
 | 
						|
 | 
						|
__name__ == "__main__" and main()
 |