scripts: runners: handle uninstalled dependencies

Catch ImportError whenever a non-standard module import fails from any
runners that do one. Complain at runtime about it if the user actually
needs the runner.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This commit is contained in:
Martí Bolívar 2020-05-08 15:51:14 -07:00 committed by Carles Cufí
commit 0b5c58fcab
3 changed files with 27 additions and 5 deletions

View file

@ -7,11 +7,15 @@
import argparse
import os
import canopen
from progress.bar import Bar
from runners.core import ZephyrBinaryRunner, RunnerCaps
try:
import canopen
from progress.bar import Bar
MISSING_REQUIREMENTS = False
except ImportError:
MISSING_REQUIREMENTS = True
# Default Python-CAN context to use, see python-can documentation for details
DEFAULT_CAN_CONTEXT = 'default'
@ -38,6 +42,11 @@ class CANopenBinaryRunner(ZephyrBinaryRunner):
def __init__(self, cfg, node_id, can_context=DEFAULT_CAN_CONTEXT,
program_number=1, confirm=True,
confirm_only=True, timeout=10):
if MISSING_REQUIREMENTS:
raise RuntimeError('one or more Python dependencies were missing; '
"see the getting started guide for details on "
"how to fix")
super(CANopenBinaryRunner, self).__init__(cfg)
self.bin_file = cfg.bin_file
self.confirm = confirm

View file

@ -313,7 +313,13 @@ class ZephyrBinaryRunner(abc.ABC):
3. Give your runner's name to the Zephyr build system in your
board's board.cmake.
Some advice on input and output:
Additional advice:
- If you need to import any non-standard-library modules, make sure
to catch ImportError and defer complaints about it to a RuntimeError
if one is missing. This avoids affecting users that don't require your
runner, while still making it clear what went wrong to users that do
require it that don't have the necessary modules installed.
- If you need to ask the user something (e.g. using input()), do it
in your create() classmethod, not do_run(). That ensures your

View file

@ -5,7 +5,11 @@
'''Runner for openocd.'''
from os import path
from elftools.elf.elffile import ELFFile
try:
from elftools.elf.elffile import ELFFile
except ImportError:
ELFFile = None
from runners.core import ZephyrBinaryRunner
@ -106,6 +110,9 @@ class OpenOcdBinaryRunner(ZephyrBinaryRunner):
def do_run(self, command, **kwargs):
self.require(self.openocd_cmd[0])
if ELFFile is None:
raise RuntimeError(
'elftools missing; please "pip3 install elftools"')
self.cfg_cmd = []
if self.openocd_config is not None: