• 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"""Pigweed Console entry point."""
15
16import argparse
17import inspect
18import logging
19from pathlib import Path
20import sys
21
22import pw_cli.log
23import pw_cli.argument_types
24
25import pw_console
26import pw_console.python_logging
27from pw_console.log_store import LogStore
28from pw_console.plugins.calc_pane import CalcPane
29from pw_console.plugins.clock_pane import ClockPane
30
31_LOG = logging.getLogger(__package__)
32_ROOT_LOG = logging.getLogger('')
33
34
35# TODO(tonymd): Remove this when no downstream projects are using it.
36def create_temp_log_file():
37    return pw_console.python_logging.create_temp_log_file()
38
39
40def _build_argument_parser() -> argparse.ArgumentParser:
41    """Setup argparse."""
42    parser = argparse.ArgumentParser(description=__doc__)
43
44    parser.add_argument('-l',
45                        '--loglevel',
46                        type=pw_cli.argument_types.log_level,
47                        default=logging.DEBUG,
48                        help='Set the log level'
49                        '(debug, info, warning, error, critical)')
50
51    parser.add_argument('--logfile', help='Pigweed Console log file.')
52
53    parser.add_argument('--test-mode',
54                        action='store_true',
55                        help='Enable fake log messages for testing purposes.')
56    parser.add_argument('--config-file',
57                        type=Path,
58                        help='Path to a pw_console yaml config file.')
59    parser.add_argument('--console-debug-log-file',
60                        help='Log file to send console debug messages to.')
61
62    return parser
63
64
65def main() -> int:
66    """Pigweed Console."""
67
68    parser = _build_argument_parser()
69    args = parser.parse_args()
70
71    if not args.logfile:
72        # Create a temp logfile to prevent logs from appearing over stdout. This
73        # would corrupt the prompt toolkit UI.
74        args.logfile = pw_console.python_logging.create_temp_log_file()
75
76    pw_cli.log.install(level=args.loglevel,
77                       use_color=True,
78                       hide_timestamp=False,
79                       log_file=args.logfile)
80
81    if args.console_debug_log_file:
82        pw_cli.log.install(level=logging.DEBUG,
83                           use_color=True,
84                           hide_timestamp=False,
85                           log_file=args.console_debug_log_file,
86                           logger=logging.getLogger('pw_console'))
87
88    global_vars = None
89    default_loggers = {}
90    if args.test_mode:
91        root_log_store = LogStore()
92        _ROOT_LOG.addHandler(root_log_store)
93        _ROOT_LOG.debug('pw_console test-mode starting...')
94
95        fake_logger = logging.getLogger(
96            pw_console.console_app.FAKE_DEVICE_LOGGER_NAME)
97        default_loggers = {
98            # Don't include pw_console package logs (_LOG) in the log pane UI.
99            # Add the fake logger for test_mode.
100            'Fake Device Logs': [fake_logger],
101            'PwConsole Debug': [logging.getLogger('pw_console')],
102            'All Logs': root_log_store,
103        }
104        # Give access to adding log messages from the repl via: `LOG.warning()`
105        global_vars = dict(LOG=fake_logger)
106
107    help_text = None
108    app_title = None
109    if args.test_mode:
110        app_title = 'Console Test Mode'
111        help_text = inspect.cleandoc("""
112            Welcome to the Pigweed Console Test Mode!
113
114            Example commands:
115
116              rpcs.pw.rpc.EchoService.Echo(msg='hello!')
117
118              LOG.warning('Message appears console log window.')
119        """)
120
121    console = pw_console.PwConsoleEmbed(
122        global_vars=global_vars,
123        loggers=default_loggers,
124        test_mode=args.test_mode,
125        help_text=help_text,
126        app_title=app_title,
127        config_file_path=args.config_file,
128    )
129
130    # Add example plugins used to validate behavior in the Pigweed Console
131    # manual test procedure: https://pigweed.dev/pw_console/testing.html
132    if args.test_mode:
133        _ROOT_LOG.debug('pw_console.PwConsoleEmbed init complete')
134        _ROOT_LOG.debug('Adding plugins...')
135        console.add_window_plugin(ClockPane())
136        console.add_window_plugin(CalcPane())
137        _ROOT_LOG.debug('Starting prompt_toolkit full-screen application...')
138
139    console.embed()
140
141    if args.logfile:
142        print(f'Logs saved to: {args.logfile}')
143
144    return 0
145
146
147if __name__ == '__main__':
148    sys.exit(main())
149