1414import abc
1515import argparse
1616import errno
17+ import logging
1718import os
1819import platform
20+ import shlex
1921import shutil
2022import signal
2123import subprocess
2224
23- from west import log
24- from west .util import quote_sh_list
25+ # Turn on to enable just logging the commands that would be run (at
26+ # info rather than debug level), without actually running them. This
27+ # can break runners that are expecting output or if one command
28+ # depends on another, so it's just for debugging.
29+ _DRY_RUN = False
2530
26- # Turn on to enable just printing the commands that would be run,
27- # without actually running them. This can break runners that are expecting
28- # output or if one command depends on another, so it's just for debugging.
29- JUST_PRINT = False
31+ _logger = logging .getLogger ('runners' )
3032
3133
3234class _DebugDummyPopen :
@@ -313,6 +315,17 @@ class ZephyrBinaryRunner(abc.ABC):
313315 3. Give your runner's name to the Zephyr build system in your
314316 board's board.cmake.
315317
318+ Some advice on input and output:
319+
320+ - If you need to ask the user something (e.g. using input()), do it
321+ in your create() classmethod, not do_run(). That ensures your
322+ __init__() really has everything it needs to call do_run(), and also
323+ avoids calling input() when not instantiating within a command line
324+ application.
325+
326+ - Use self.logger to log messages using the standard library's
327+ logging API; your logger is named "runner.<your-runner-name()>"
328+
316329 For command-line invocation from the Zephyr build system, runners
317330 define their own argparse-based interface through the common
318331 add_parser() (and runner-specific do_add_parser() it delegates
@@ -330,6 +343,10 @@ def __init__(self, cfg):
330343
331344 ``cfg`` is a RunnerConfig instance.'''
332345 self .cfg = cfg
346+ '''RunnerConfig for this instance.'''
347+
348+ self .logger = logging .getLogger ('runners.{}' .format (self .name ()))
349+ '''logging.Logger for this instance.'''
333350
334351 @staticmethod
335352 def get_runners ():
@@ -465,20 +482,23 @@ def run_server_and_client(self, server, client):
465482 server_proc .terminate ()
466483 server_proc .wait ()
467484
485+ def _log_cmd (self , cmd ):
486+ escaped = ' ' .join (shlex .quote (s ) for s in cmd )
487+ if not _DRY_RUN :
488+ self .logger .debug (escaped )
489+ else :
490+ self .logger .info (escaped )
491+
468492 def call (self , cmd ):
469493 '''Subclass subprocess.call() wrapper.
470494
471495 Subclasses should use this method to run command in a
472496 subprocess and get its return code, rather than
473497 using subprocess directly, to keep accurate debug logs.
474498 '''
475- quoted = quote_sh_list (cmd )
476-
477- if JUST_PRINT :
478- log .inf (quoted )
499+ self ._log_cmd (cmd )
500+ if _DRY_RUN :
479501 return 0
480-
481- log .dbg (quoted )
482502 return subprocess .call (cmd )
483503
484504 def check_call (self , cmd ):
@@ -488,13 +508,9 @@ def check_call(self, cmd):
488508 subprocess and check that it executed correctly, rather than
489509 using subprocess directly, to keep accurate debug logs.
490510 '''
491- quoted = quote_sh_list (cmd )
492-
493- if JUST_PRINT :
494- log .inf (quoted )
511+ self ._log_cmd (cmd )
512+ if _DRY_RUN :
495513 return
496-
497- log .dbg (quoted )
498514 try :
499515 subprocess .check_call (cmd )
500516 except subprocess .CalledProcessError :
@@ -507,13 +523,9 @@ def check_output(self, cmd):
507523 subprocess and check that it executed correctly, rather than
508524 using subprocess directly, to keep accurate debug logs.
509525 '''
510- quoted = quote_sh_list (cmd )
511-
512- if JUST_PRINT :
513- log .inf (quoted )
526+ self ._log_cmd (cmd )
527+ if _DRY_RUN :
514528 return b''
515-
516- log .dbg (quoted )
517529 try :
518530 return subprocess .check_output (cmd )
519531 except subprocess .CalledProcessError :
@@ -526,16 +538,14 @@ def popen_ignore_int(self, cmd):
526538 cflags = 0
527539 preexec = None
528540 system = platform .system ()
529- quoted = quote_sh_list (cmd )
530541
531542 if system == 'Windows' :
532543 cflags |= subprocess .CREATE_NEW_PROCESS_GROUP
533544 elif system in {'Linux' , 'Darwin' }:
534545 preexec = os .setsid
535546
536- if JUST_PRINT :
537- log . inf ( quoted )
547+ self . _log_cmd ( cmd )
548+ if _DRY_RUN :
538549 return _DebugDummyPopen ()
539550
540- log .dbg (quoted )
541551 return subprocess .Popen (cmd , creationflags = cflags , preexec_fn = preexec )
0 commit comments