1# Copyright (C) 2021 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Binary that generates a simulated Bazel environment in the Android source.
15
16The script utilizes an internal repository of templates to determine the targets
17to build, builds them via Soong, then imports them into a Bazel environment
18all relying on templated BUILD files. These files can then be placed
19directly within the Android source tree to simulate what a real Bazel
20environment would look like.
21"""
22import argparse
23import logging
24
25import bazelenv
26
27_LOG_PRINT_FORMAT = ("%(asctime)s %(filename)s:%(lineno)s:%(levelname)s: "
28                     "%(message)s")
29_LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
30
31
32def _configure_logging(verbose: bool) -> None:
33    """Configures logging for the application.
34
35  Args:
36    verbose: if True, all messages are logged, otherwise only INFO and above
37    are logged.
38  """
39    logging.basicConfig(format=_LOG_PRINT_FORMAT, datefmt=_LOG_DATE_FORMAT)
40    level = logging.DEBUG if verbose else logging.INFO
41    logging.root.setLevel(level)
42
43
44def _create_arg_parser():
45    parser = argparse.ArgumentParser(description=(
46        "Prepares a simulated Bazel environment that can be used to "
47        "execute tests in a Bazel environment based on Soong "
48        "produced artifacts."))
49
50    parser.add_argument("-v",
51                        "--verbose",
52                        help="Enables verbose logging.",
53                        action="store_true")
54
55    subparsers = parser.add_subparsers(dest="action", required=True)
56
57    # For each subparser, provide a default 'func' argument that calls the
58    # corresponding method on the generator instance.
59    subparsers.add_parser(
60        "generate",
61        help="Generates the Bazel environment to the staging directory."
62    ).set_defaults(func=lambda g: g.generate())
63
64    subparsers.add_parser(
65        "sync",
66        help="Synchronizes the staged Bazel environment to the source tree."
67    ).set_defaults(func=lambda g: g.sync())
68
69    subparsers.add_parser(
70        "clean",
71        help=
72        ("Cleans up the Bazel environment by clearing anything that has been "
73         "synced to the source tree as well as the staging directory itself."
74         )).set_defaults(func=lambda g: g.clean())
75
76    return parser
77
78
79if __name__ == "__main__":
80    args = _create_arg_parser().parse_args()
81    logging.debug("prepare_bazel_test_env(%s)", args)
82
83    _configure_logging(args.verbose)
84
85    try:
86        generator = bazelenv.BazelTestEnvGenerator()
87        args.func(generator)
88    except bazelenv.Error:
89        logging.exception(
90            "A known error occurred, check the error description "
91            "or logs for more details.")
92