scripts: runners: abstract jlink's missing program support
The runners/jlink.py script has a mechanism for erroring out if a host tool is not installed. Abstract it into runners/core.py and handle it from run_common.py. This will let it be used in more places. Signed-off-by: Marti Bolivar <marti.bolivar@nordicsemi.no>
This commit is contained in:
parent
db7b9a988b
commit
c07267a26a
4 changed files with 39 additions and 10 deletions
|
@ -17,7 +17,7 @@ from build_helpers import find_build_dir, is_zephyr_build, \
|
|||
FIND_BUILD_DIR_DESCRIPTION
|
||||
from west.commands import CommandContextError
|
||||
|
||||
from runners import get_runner_cls, ZephyrBinaryRunner
|
||||
from runners import get_runner_cls, ZephyrBinaryRunner, MissingProgram
|
||||
|
||||
from zephyr_ext_common import cached_runner_config
|
||||
|
||||
|
@ -229,7 +229,11 @@ def do_run_common(command, args, runner_args, cached_runner_var):
|
|||
if unknown:
|
||||
log.die('Runner', runner, 'received unknown arguments:', unknown)
|
||||
runner = runner_cls.create(cfg, parsed_args)
|
||||
runner.run(command_name)
|
||||
try:
|
||||
runner.run(command_name)
|
||||
except MissingProgram as e:
|
||||
log.die('required program', e.filename,
|
||||
'not found; install it or add its location to PATH')
|
||||
|
||||
|
||||
#
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
from runners.core import ZephyrBinaryRunner
|
||||
from runners.core import ZephyrBinaryRunner, MissingProgram
|
||||
|
||||
# We import these here to ensure the ZephyrBinaryRunner subclasses are
|
||||
# defined; otherwise, ZephyrBinaryRunner.create_for_shell_script()
|
||||
|
|
|
@ -13,8 +13,10 @@ as well as some other helpers for concrete runner classes.
|
|||
|
||||
import abc
|
||||
import argparse
|
||||
import errno
|
||||
import os
|
||||
import platform
|
||||
import shutil
|
||||
import signal
|
||||
import subprocess
|
||||
|
||||
|
@ -157,6 +159,19 @@ class BuildConfiguration:
|
|||
return value
|
||||
|
||||
|
||||
class MissingProgram(FileNotFoundError):
|
||||
'''FileNotFoundError subclass for missing program dependencies.
|
||||
|
||||
No significant changes from the parent FileNotFoundError; this is
|
||||
useful for explicitly signaling that the file in question is a
|
||||
program that some class requires to proceed.
|
||||
|
||||
The filename attribute contains the missing program.'''
|
||||
|
||||
def __init__(self, program):
|
||||
super().__init__(errno.ENOENT, os.strerror(errno.ENOENT), program)
|
||||
|
||||
|
||||
class RunnerCaps:
|
||||
'''This class represents a runner class's capabilities.
|
||||
|
||||
|
@ -415,6 +430,20 @@ class ZephyrBinaryRunner(abc.ABC):
|
|||
|
||||
In case of an unsupported command, raise a ValueError.'''
|
||||
|
||||
def require(self, program):
|
||||
'''Require that a program is installed before proceeding.
|
||||
|
||||
:param program: name of the program that is required,
|
||||
or path to a program binary.
|
||||
|
||||
If ``program`` is an absolute path to an existing program
|
||||
binary, this call succeeds. Otherwise, try to find the program
|
||||
by name on the system PATH.
|
||||
|
||||
On error, raises MissingProgram.'''
|
||||
if shutil.which(program) is None:
|
||||
raise MissingProgram(program)
|
||||
|
||||
def run_server_and_client(self, server, client):
|
||||
'''Run a server that ignores SIGINT, and a client that handles it.
|
||||
|
||||
|
|
|
@ -107,10 +107,6 @@ class JLinkBinaryRunner(ZephyrBinaryRunner):
|
|||
def print_gdbserver_message(self):
|
||||
log.inf('J-Link GDB server running on port {}'.format(self.gdb_port))
|
||||
|
||||
def check_cmd(self, cmd):
|
||||
if shutil.which(cmd) is None:
|
||||
log.die('{} is not installed or cannot be found'.format(cmd))
|
||||
|
||||
def do_run(self, command, **kwargs):
|
||||
server_cmd = ([self.gdbserver] +
|
||||
['-select', 'usb', # only USB connections supported
|
||||
|
@ -125,11 +121,11 @@ class JLinkBinaryRunner(ZephyrBinaryRunner):
|
|||
if command == 'flash':
|
||||
self.flash(**kwargs)
|
||||
elif command == 'debugserver':
|
||||
self.check_cmd(self.gdbserver)
|
||||
self.require(self.gdbserver)
|
||||
self.print_gdbserver_message()
|
||||
self.check_call(server_cmd)
|
||||
else:
|
||||
self.check_cmd(self.gdbserver)
|
||||
self.require(self.gdbserver)
|
||||
if self.gdb_cmd is None:
|
||||
raise ValueError('Cannot debug; gdb is missing')
|
||||
if self.elf_name is None:
|
||||
|
@ -149,7 +145,7 @@ class JLinkBinaryRunner(ZephyrBinaryRunner):
|
|||
self.run_server_and_client(server_cmd, client_cmd)
|
||||
|
||||
def flash(self, **kwargs):
|
||||
self.check_cmd(self.commander)
|
||||
self.require(self.commander)
|
||||
if self.bin_name is None:
|
||||
raise ValueError('Cannot flash; bin_name is missing')
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue