• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2021 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://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, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14"""Prints an error message and exits unsuccessfully."""
15
16import argparse
17import logging
18import os
19from pathlib import Path
20import subprocess
21import sys
22
23try:
24    from pw_cli.log import install as setup_logging
25except ImportError:
26    from logging import basicConfig as setup_logging  # type: ignore
27
28_LOG = logging.getLogger(__name__)
29
30
31def _parse_args() -> argparse.Namespace:
32    parser = argparse.ArgumentParser(description=__doc__)
33    parser.add_argument(
34        '--message', required=True, help='Error message to print'
35    )
36    parser.add_argument(
37        '--target', required=True, help='GN target in which the error occurred'
38    )
39    parser.add_argument('--root', required=True, type=Path, help='GN root')
40    parser.add_argument('--out', required=True, type=Path, help='GN out dir')
41    return parser.parse_args()
42
43
44def main(message: str, target: str, root: Path, out: Path) -> int:
45    """Logs the error message and returns 1."""
46
47    _LOG.error('')
48    _LOG.error('Build error for %s:', target)
49    _LOG.error('')
50
51    for line in message.split('\\n'):
52        _LOG.error('  %s', line)
53
54    _LOG.error('')
55
56    gn_cmd = subprocess.run(
57        ['gn', 'path', f'--root={root}', out, '//:default', target],
58        capture_output=True,
59    )
60    path_info = gn_cmd.stdout.decode(errors='replace').rstrip()
61
62    relative_out = os.path.relpath(out, root)
63
64    if gn_cmd.returncode == 0 and 'No non-data paths found' not in path_info:
65        _LOG.error('Dependency path to this target:')
66        _LOG.error('')
67        _LOG.error(
68            '  gn path %s //:default "%s"\n%s', relative_out, target, path_info
69        )
70        _LOG.error('')
71    else:
72        _LOG.error(
73            'Run this command to see the build dependency path to this target:'
74        )
75        _LOG.error('')
76        _LOG.error('  gn path %s <target> "%s"', relative_out, target)
77        _LOG.error('')
78        _LOG.error('where <target> is the GN target you are building.')
79        _LOG.error('')
80
81    return 1
82
83
84if __name__ == '__main__':
85    setup_logging()
86    sys.exit(main(**vars(_parse_args())))
87