1#!/usr/bin/env -S python3
2#  Copyright (C) 2024 The Android Open Source Project
3#
4#  Licensed under the Apache License, Version 2.0 (the "License");
5#  you may not use this file except in compliance with the License.
6#  You may obtain a copy of the License at
7#
8#       http://www.apache.org/licenses/LICENSE-2.0
9#
10#  Unless required by applicable law or agreed to in writing, software
11#  distributed under the License is distributed on an "AS IS" BASIS,
12#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13#  See the License for the specific language governing permissions and
14#  limitations under the License.
15import argparse
16import dataclasses
17import subprocess
18import sys
19from pathlib import Path
20
21
22@dataclasses.dataclass(frozen=True)
23class BaselineProject:
24    """A project that has a baseline file to update."""
25    # The name of the project
26    name: str
27
28    # The baseline file path.
29    baseline_file: Path
30
31
32def resource_path(project_dir, resource_path):
33    return project_dir / "src" / "test" / "resources" / resource_path
34
35
36def find_baseline_projects(metalava_dir):
37    projects = []
38    for buildFile in metalava_dir.glob("*/build.gradle.kts"):
39        for line in open(buildFile, 'r'):
40            if """id("metalava-model-provider-plugin")""" in line:
41                project_dir = buildFile.parent
42                baseline = BaselineProject(
43                    name=project_dir.name,
44                    baseline_file=resource_path(project_dir, "model-test-suite-baseline.txt"),
45                )
46                projects.append(baseline)
47    projects.append(BaselineProject(
48        name="metalava",
49        baseline_file=resource_path(metalava_dir / "metalava", "source-model-provider-baseline.txt")
50    ))
51    return projects
52
53
54def main(args):
55    args_parser = argparse.ArgumentParser(description="Refresh the baseline files.")
56    args_parser.add_argument("projects", nargs='*')
57    args = args_parser.parse_args(args)
58
59    # Get various directories.
60    this = Path(__file__)
61    script_dir = this.parent
62    metalava_dir = script_dir.parent
63    out_dir = metalava_dir.parent.parent / "out"
64    metalava_out_dir = out_dir / "metalava"
65
66    # Get the projects which have a baseline file to update.
67    baseline_projects = find_baseline_projects(metalava_dir)
68
69    # Filter the baseline projects by the names specified on the command line.
70    if args.projects:
71        baseline_projects = [p for p in baseline_projects if p.name in args.projects]
72
73    for baseline_project in baseline_projects:
74        project_name = baseline_project.name
75
76        # Delete all the test report files.
77        print(f"Deleting test report files for {project_name}")
78        test_reports_dir = metalava_out_dir / project_name / "build" / "test-results" / "test"
79        for f in test_reports_dir.glob("**/TEST-*.xml"):
80            f.unlink()
81
82        # Delete the baseline file.
83        baseline_file = baseline_project.baseline_file
84        print(f"Deleting baseline file - {baseline_file}")
85        baseline_file.unlink(missing_ok=True)
86
87        # Run the tests.
88        print(f"Running all tests in {project_name}")
89        subprocess.run(["./gradlew", f":{project_name}:test", "--continue"], cwd=metalava_dir)
90
91        print(f"Updating baseline file - {baseline_file}")
92        test_report_files = " ".join([f"'{str(f)}'" for f in test_reports_dir.glob("**/TEST-*.xml")])
93        project_dir = metalava_dir / project_name
94        subprocess.run(["./gradlew", f":metalava-model-testsuite-cli:run",
95                        f"""--args={test_report_files} --baseline-file '{baseline_file}'"""], cwd=metalava_dir)
96
97
98if __name__ == "__main__":
99    main(sys.argv[1:])
100