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