|
| 1 | +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 2 | +# See https://llvm.org/LICENSE.txt for license information. |
| 3 | +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 4 | +"""Computes the list of projects that need to be tested from a diff. |
| 5 | +
|
| 6 | +Does some things, spits out a list of projects. |
| 7 | +""" |
| 8 | + |
| 9 | +from collections.abc import Set |
| 10 | +import pathlib |
| 11 | +import platform |
| 12 | +import sys |
| 13 | + |
| 14 | +PROJECT_DEPENDENCIES = { |
| 15 | + "llvm": set(), |
| 16 | + "clang": {"llvm"}, |
| 17 | + "bolt": {"clang", "lld", "llvm"}, |
| 18 | + "clang-tools-extra": {"clang", "llvm"}, |
| 19 | + "compiler-rt": {"clang", "lld"}, |
| 20 | + "libc": {"clang", "lld"}, |
| 21 | + "openmp": {"clang", "lld"}, |
| 22 | + "flang": {"llvm", "clang"}, |
| 23 | + "lldb": {"llvm", "clang"}, |
| 24 | + "libclc": {"llvm", "clang"}, |
| 25 | + "lld": {"llvm"}, |
| 26 | + "mlir": {"llvm"}, |
| 27 | + "polly": {"llvm"}, |
| 28 | +} |
| 29 | + |
| 30 | +DEPENDENTS_TO_TEST = { |
| 31 | + "llvm": {"bolt", "clang", "clang-tools-extra", "lld", "lldb", "mlir", "polly"}, |
| 32 | + "lld": {"bolt", "cross-project-tests"}, |
| 33 | + "clang": {"clang-tools-extra", "compiler-rt", "cross-project-tests"}, |
| 34 | + "clang-tools-extra": {"libc"}, |
| 35 | + "mlir": {"flang"}, |
| 36 | +} |
| 37 | + |
| 38 | +DEPENDENT_RUNTIMES_TO_TEST = {"clang": {"libcxx", "libcxxabi", "libunwind"}} |
| 39 | + |
| 40 | +EXCLUDE_LINUX = { |
| 41 | + "cross-project-tests", # Tests are failing. |
| 42 | + "openmp", # https://github.com/google/llvm-premerge-checks/issues/410 |
| 43 | +} |
| 44 | + |
| 45 | +EXCLUDE_WINDOWS = { |
| 46 | + "cross-project-tests", # Tests are failing. |
| 47 | + "compiler-rt", # Tests are taking too long. |
| 48 | + "openmp", # Does not detect perl installation. |
| 49 | + "libc", # No Windows Support. |
| 50 | + "lldb", # Custom environment requirements. |
| 51 | + "bolt", # No Windows Support. |
| 52 | +} |
| 53 | + |
| 54 | +PROJECT_CHECK_TARGETS = { |
| 55 | + "clang-tools-extra": "check-clang-tools", |
| 56 | + "compiler-rt": "check-compiler-rt", |
| 57 | + "cross-project-tests": "check-cross-project", |
| 58 | + "libcxx": "check-cxx", |
| 59 | + "libcxxabi": "check-cxxabi", |
| 60 | + "libunwind": "check-unwind", |
| 61 | + "lldb": "check-lldb", |
| 62 | + "llvm": "check-llvm", |
| 63 | + "clang": "check-clang", |
| 64 | + "bolt": "check-bolt", |
| 65 | + "lld": "check-lld", |
| 66 | + "flang": "check-flang", |
| 67 | + "libc": "check-libc", |
| 68 | + "lld": "check-lld", |
| 69 | + "lldb": "check-lldb", |
| 70 | + "mlir": "check-mlir", |
| 71 | + "openmp": "check-openmp", |
| 72 | + "polly": "check-polly", |
| 73 | +} |
| 74 | + |
| 75 | + |
| 76 | +def _add_dependencies(projects: Set[str]) -> Set[str]: |
| 77 | + projects_with_dependents = set(projects) |
| 78 | + current_projects_count = 0 |
| 79 | + while current_projects_count != len(projects_with_dependents): |
| 80 | + current_projects_count = len(projects_with_dependents) |
| 81 | + for project in list(projects_with_dependents): |
| 82 | + if project not in PROJECT_DEPENDENCIES: |
| 83 | + continue |
| 84 | + projects_with_dependents.update(PROJECT_DEPENDENCIES[project]) |
| 85 | + return projects_with_dependents |
| 86 | + |
| 87 | + |
| 88 | +def _compute_projects_to_test(modified_projects: Set[str], platform: str) -> Set[str]: |
| 89 | + """Computes the list of projects that should be passed to LLVM_ENABLE_PROJECTS""" |
| 90 | + projects_to_test = set(modified_projects) |
| 91 | + for modified_project in modified_projects: |
| 92 | + if modified_project not in DEPENDENTS_TO_TEST: |
| 93 | + continue |
| 94 | + projects_to_test.update(DEPENDENTS_TO_TEST[modified_project]) |
| 95 | + if platform == "Linux": |
| 96 | + for to_exclude in EXCLUDE_LINUX: |
| 97 | + if to_exclude in projects_to_test: |
| 98 | + projects_to_test.remove(to_exclude) |
| 99 | + elif platform == "Windows": |
| 100 | + for to_exclude in EXCLUDE_WINDOWS: |
| 101 | + if to_exclude in projects_to_test: |
| 102 | + projects_to_test.remove(to_exclude) |
| 103 | + else: |
| 104 | + raise ValueError("Unexpected platform.") |
| 105 | + return projects_to_test |
| 106 | + |
| 107 | + |
| 108 | +def _compute_projects_to_build(projects_to_test: Set[str]) -> Set[str]: |
| 109 | + return _add_dependencies(projects_to_test) |
| 110 | + |
| 111 | + |
| 112 | +def _compute_project_check_targets(projects_to_test: Set[str]) -> Set[str]: |
| 113 | + """blah blah blah""" |
| 114 | + check_targets = set() |
| 115 | + for project_to_test in projects_to_test: |
| 116 | + if project_to_test not in PROJECT_CHECK_TARGETS: |
| 117 | + continue |
| 118 | + check_targets.add(PROJECT_CHECK_TARGETS[project_to_test]) |
| 119 | + return check_targets |
| 120 | + |
| 121 | + |
| 122 | +def _compute_runtimes_to_test(projects_to_test: Set[str]) -> Set[str]: |
| 123 | + """blah blah blah""" |
| 124 | + runtimes_to_test = set() |
| 125 | + for project_to_test in projects_to_test: |
| 126 | + if project_to_test not in DEPENDENT_RUNTIMES_TO_TEST: |
| 127 | + continue |
| 128 | + runtimes_to_test.update(DEPENDENT_RUNTIMES_TO_TEST[project_to_test]) |
| 129 | + return runtimes_to_test |
| 130 | + |
| 131 | + |
| 132 | +def _compute_runtime_check_targets(runtimes_to_test: Set[str]) -> Set[str]: |
| 133 | + """blah blah blah""" |
| 134 | + check_targets = set() |
| 135 | + for runtime_to_test in runtimes_to_test: |
| 136 | + check_targets.add(PROJECT_CHECK_TARGETS[runtime_to_test]) |
| 137 | + return check_targets |
| 138 | + |
| 139 | + |
| 140 | +def _get_modified_projects(modified_files: list[str]) -> Set[str]: |
| 141 | + """blah blah blah""" |
| 142 | + modified_projects = set() |
| 143 | + for modified_file in modified_files: |
| 144 | + modified_projects.add(pathlib.Path(modified_file).parts[0]) |
| 145 | + return modified_projects |
| 146 | + |
| 147 | + |
| 148 | +def get_env_variables(modified_files: list[str], platform: str) -> Set[str]: |
| 149 | + modified_projects = _get_modified_projects(modified_files) |
| 150 | + projects_to_test = _compute_projects_to_test(modified_projects, platform) |
| 151 | + projects_to_build = _compute_projects_to_build(projects_to_test) |
| 152 | + projects_check_targets = _compute_project_check_targets(projects_to_test) |
| 153 | + runtimes_to_test = _compute_runtimes_to_test(projects_to_test) |
| 154 | + runtimes_check_targets = _compute_runtime_check_targets(runtimes_to_test) |
| 155 | + return { |
| 156 | + "projects_to_build": ";".join(sorted(projects_to_build)), |
| 157 | + "project_check_targets": " ".join(sorted(projects_check_targets)), |
| 158 | + "runtimes_to_build": ";".join(sorted(runtimes_to_test)), |
| 159 | + "runtimes_check_targets": " ".join(sorted(runtimes_check_targets)), |
| 160 | + } |
| 161 | + |
| 162 | + |
| 163 | +if __name__ == "__main__": |
| 164 | + env_variables = get_env_variables(sys.stdin.readlines(), platform.system()) |
| 165 | + for env_variable in env_variables: |
| 166 | + print(f"{env_variable}={env_variables[env_variable]}") |
0 commit comments