blob: 116d6f8882df167f74178d715425953233ef38f7 [file] [log] [blame]
Luca Farsi040fabe2024-05-22 17:21:47 -07001#
2# Copyright 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.
15
16from abc import ABC
Luca Farsi70a53bd2024-08-07 17:29:16 -070017import argparse
18import functools
Luca Farsib130e792024-08-22 12:04:41 -070019from typing import Self
20from build_context import BuildContext
Luca Farsi040fabe2024-05-22 17:21:47 -070021
22
23class OptimizedBuildTarget(ABC):
24 """A representation of an optimized build target.
25
26 This class will determine what targets to build given a given build_cotext and
27 will have a packaging function to generate any necessary output zips for the
28 build.
29 """
30
Luca Farsi70a53bd2024-08-07 17:29:16 -070031 def __init__(
32 self,
33 target: str,
Luca Farsib130e792024-08-22 12:04:41 -070034 build_context: BuildContext,
Luca Farsi70a53bd2024-08-07 17:29:16 -070035 args: argparse.Namespace,
36 ):
37 self.target = target
Luca Farsi040fabe2024-05-22 17:21:47 -070038 self.build_context = build_context
39 self.args = args
40
Luca Farsi70a53bd2024-08-07 17:29:16 -070041 def get_build_targets(self) -> set[str]:
Luca Farsib130e792024-08-22 12:04:41 -070042 features = self.build_context.enabled_build_features
Luca Farsi70a53bd2024-08-07 17:29:16 -070043 if self.get_enabled_flag() in features:
44 return self.get_build_targets_impl()
45 return {self.target}
Luca Farsi040fabe2024-05-22 17:21:47 -070046
47 def package_outputs(self):
Luca Farsib130e792024-08-22 12:04:41 -070048 features = self.build_context.enabled_build_features
Luca Farsi70a53bd2024-08-07 17:29:16 -070049 if self.get_enabled_flag() in features:
50 return self.package_outputs_impl()
51
52 def package_outputs_impl(self):
53 raise NotImplementedError(
54 f'package_outputs_impl not implemented in {type(self).__name__}'
55 )
56
57 def get_enabled_flag(self):
58 raise NotImplementedError(
59 f'get_enabled_flag not implemented in {type(self).__name__}'
60 )
61
62 def get_build_targets_impl(self) -> set[str]:
63 raise NotImplementedError(
64 f'get_build_targets_impl not implemented in {type(self).__name__}'
65 )
Luca Farsi040fabe2024-05-22 17:21:47 -070066
67
68class NullOptimizer(OptimizedBuildTarget):
69 """No-op target optimizer.
70
71 This will simply build the same target it was given and do nothing for the
72 packaging step.
73 """
74
75 def __init__(self, target):
76 self.target = target
77
78 def get_build_targets(self):
79 return {self.target}
80
81 def package_outputs(self):
82 pass
83
84
Luca Farsi70a53bd2024-08-07 17:29:16 -070085class GeneralTestsOptimizer(OptimizedBuildTarget):
86 """general-tests optimizer
Luca Farsi040fabe2024-05-22 17:21:47 -070087
Luca Farsi70a53bd2024-08-07 17:29:16 -070088 TODO(b/358215235): Implement
89
90 This optimizer reads in the list of changed files from the file located in
91 env[CHANGE_INFO] and uses this list alongside the normal TEST MAPPING logic to
92 determine what test mapping modules will run for the given changes. It then
93 builds those modules and packages them in the same way general-tests.zip is
94 normally built.
95 """
96
97 def get_enabled_flag(self):
98 return 'general-tests-optimized'
99
100 @classmethod
101 def get_optimized_targets(cls) -> dict[str, OptimizedBuildTarget]:
102 return {'general-tests': functools.partial(cls)}
Luca Farsi040fabe2024-05-22 17:21:47 -0700103
104
Luca Farsi70a53bd2024-08-07 17:29:16 -0700105OPTIMIZED_BUILD_TARGETS = {}
106OPTIMIZED_BUILD_TARGETS.update(GeneralTestsOptimizer.get_optimized_targets())