Skip to content

Commit 8a3873f

Browse files
Merge pull request #696 from screamerbg/f/improve-messages
Improve warning/error formatting and various messages
2 parents 3ec1160 + 955f127 commit 8a3873f

File tree

1 file changed

+55
-47
lines changed

1 file changed

+55
-47
lines changed

mbed/mbed.py

Lines changed: 55 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@
4343
import errno
4444
import ctypes
4545
from itertools import chain, repeat
46-
import argparse
47-
import tempfile
4846
import zipfile
47+
import argparse
4948

5049

5150
# Application version
@@ -152,8 +151,8 @@
152151
_cwd = os.getcwd()
153152

154153
# Logging and output
155-
def log(msg):
156-
sys.stdout.write(msg)
154+
def log(msg, is_error=False):
155+
sys.stderr.write(msg) if is_error else sys.stdout.write(msg)
157156

158157
def message(msg):
159158
return "[mbed] %s\n" % msg
@@ -168,14 +167,18 @@ def action(msg):
168167
log(message(line))
169168

170169
def warning(msg):
171-
for line in msg.splitlines():
172-
sys.stderr.write("[mbed] WARNING: %s\n" % line)
173-
sys.stderr.write("---\n")
170+
lines = msg.splitlines()
171+
log(message("WARNING: %s" % lines.pop(0)), True)
172+
for line in lines:
173+
log(" %s\n" % line, True)
174+
log("---\n", True)
174175

175176
def error(msg, code=-1):
176-
for line in msg.splitlines():
177-
sys.stderr.write("[mbed] ERROR: %s\n" % line)
178-
sys.stderr.write("---\n")
177+
lines = msg.splitlines()
178+
log(message("ERROR: %s" % lines.pop(0)), True)
179+
for line in lines:
180+
log(" %s\n" % line, True)
181+
log("---\n", True)
179182
sys.exit(code)
180183

181184
def offline_warning(offline, top=True):
@@ -217,15 +220,15 @@ class ProcessException(Exception):
217220

218221
def popen(command, stdin=None, **kwargs):
219222
# print for debugging
220-
info('Exec "'+' '.join(command)+'" in '+getcwd())
223+
info("Exec \"%s\" in \"%s\"" % (' '.join(command), getcwd()))
221224
proc = None
222225
try:
223226
proc = subprocess.Popen(command, **kwargs)
224227
except OSError as e:
225228
if e.args[0] == errno.ENOENT:
226229
error(
227-
"Could not execute \"%s\".\n"
228-
"Please verify that it's installed and accessible from your current path by executing \"%s\".\n" % (command[0], command[0]), e.args[0])
230+
"Could not execute \"%s\" in \"%s\".\n"
231+
"You can verify that it's installed and accessible from your current path by executing \"%s\".\n" % (' '.join(command), getcwd(), command[0]), e.args[0])
229232
else:
230233
raise e
231234

@@ -234,14 +237,14 @@ def popen(command, stdin=None, **kwargs):
234237

235238
def pquery(command, output_callback=None, stdin=None, **kwargs):
236239
if very_verbose:
237-
info('Query "'+' '.join(command)+'" in '+getcwd())
240+
info("Exec \"%s\" in \"%s\"" % (' '.join(command), getcwd()))
238241
try:
239242
proc = subprocess.Popen(command, bufsize=0, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
240243
except OSError as e:
241244
if e.args[0] == errno.ENOENT:
242245
error(
243-
"Could not execute \"%s\".\n"
244-
"Please verify that it's installed and accessible from your current path by executing \"%s\".\n" % (command[0], command[0]), e.args[0])
246+
"Could not execute \"%s\" in \"%s\".\n"
247+
"You can verify that it's installed and accessible from your current path by executing \"%s\".\n" % (' '.join(command), getcwd(), command[0]), e.args[0])
245248
else:
246249
raise e
247250

@@ -785,9 +788,9 @@ def update(rev=None, clean=False, clean_files=False, is_local=False):
785788
else:
786789
err = "Unable to update \"%s\" in \"%s\"." % (os.path.basename(getcwd()), getcwd())
787790
if not remote:
788-
info(err+" The local repository is not associated with a remote one.")
791+
info(err+"\nThe local repository is not associated with a remote one.\nYou should associate your repository with a remote one.")
789792
if not branch:
790-
info(err+" Working set is not on a branch.")
793+
info(err+"\nThe working set is not on a branch.\nYou should switch to a branch or create a new one from the current revision.")
791794

792795
def status():
793796
return pquery([git_cmd, 'status', '-s'] + (['-v'] if very_verbose else []))
@@ -971,9 +974,9 @@ def action_progress(line, sep):
971974
if m.group(1) == "Receiving objects":
972975
show_progress('Downloading', (float(m.group(3)) / float(m.group(4))) * 80)
973976
if m.group(1) == "Resolving deltas":
974-
show_progress('Downloading', (float(m.group(3)) / float(m.group(4))) * 10 + 80)
977+
show_progress('Downloading', (float(m.group(3)) / float(m.group(4))) * 20 + 80)
975978
if m.group(1) == "Checking out files":
976-
show_progress('Downloading', (float(m.group(3)) / float(m.group(4))) * 10 + 90)
979+
show_progress('Checking out', (float(m.group(3)) / float(m.group(4))) * 100)
977980

978981

979982
# Repository object
@@ -1496,23 +1499,23 @@ def check_requirements(self, show_warning=False):
14961499
pquery([python_cmd, '-m', 'pip', 'install', '-q', '-r', os.path.join(req_path, req_file)])
14971500
missing = []
14981501
except ProcessException:
1499-
warning("Unable to auto-install required Python modules.")
1502+
pass
15001503

15011504
except (IOError, ImportError, OSError):
15021505
pass
15031506

15041507
if missing:
1505-
err = (
1506-
"-----------------------------------------------------------------\n"
1508+
msg = (
1509+
"Unable to auto-install required Python modules.\n"
15071510
"The mbed OS tools in this program require the following Python modules: %s\n"
15081511
"You can install all missing modules by running \"pip install -r %s\" in \"%s\"" % (', '.join(missing), req_file, req_path))
15091512
if os.name == 'posix':
1510-
err += "\nOn Posix systems (Linux, Mac, etc) you might have to switch to superuser account or use \"sudo\""
1513+
msg += "\nOn Posix systems (Linux, Mac, etc) you might have to switch to superuser account or use \"sudo\""
15111514

15121515
if show_warning:
1513-
warning(err)
1516+
warning(msg)
15141517
else:
1515-
error(err, 1)
1518+
error(msg, 1)
15161519

15171520

15181521
# Routines after cloning mbed-os
@@ -1562,7 +1565,7 @@ def update_tools(self, path):
15621565
def get_tools(self):
15631566
mbed_tools_path = self.get_tools_dir()
15641567
if not mbed_tools_path:
1565-
error('The mbed tools were not found in "%s". \nRun `mbed deploy` to install dependencies and tools. ' % self.path, -1)
1568+
error("The mbed tools were not found in \"%s\". \nYou can run \"mbed deploy\" to install dependencies and tools." % self.path, -1)
15661569
return mbed_tools_path
15671570

15681571
def get_env(self):
@@ -1585,14 +1588,14 @@ def get_target(self, target=None):
15851588
target = detected['name']
15861589

15871590
if target is None:
1588-
error("Please specify target using the -m switch or set default target using command 'mbed target'", 1)
1591+
error("Please specify target using the -m switch or set default target using command \"mbed target\"", 1)
15891592
return target
15901593

15911594
def get_toolchain(self, toolchain=None):
15921595
toolchain_cfg = self.get_cfg('TOOLCHAIN')
15931596
tchain = toolchain if toolchain else toolchain_cfg
15941597
if tchain is None:
1595-
error("Please specify toolchain using the -t switch or set default toolchain using command 'mbed toolchain'", 1)
1598+
error("Please specify toolchain using the -t switch or set default toolchain using command \"mbed toolchain\"", 1)
15961599
return tchain
15971600

15981601
def set_defaults(self, target=None, toolchain=None):
@@ -1623,7 +1626,7 @@ def ignore_build_dir(self):
16231626
def detect_target(self, info=None):
16241627
targets = self.get_detected_targets()
16251628
if targets == False:
1626-
error("The target detection requires that the 'mbed-ls' python module is installed.\nYou can install mbed-ls by running 'pip install mbed-ls'.", 1)
1629+
error("The target detection requires that the 'mbed-ls' python module is installed.\nYou can install mbed-ls by running \"pip install mbed-ls\".", 1)
16271630
elif len(targets) > 1:
16281631
error("Multiple targets were detected.\nOnly 1 target board should be connected to your system.", 1)
16291632
elif len(targets) == 0:
@@ -1785,6 +1788,8 @@ def formaturl(url, format="default"):
17851788
def mbed_sterm(port, baudrate=9600, echo=True, reset=False, sterm=False):
17861789
try:
17871790
from .mbed_terminal import MbedTerminal
1791+
except(ValueError): # relative import fails on Python 2 in non-package mode
1792+
from mbed_terminal import MbedTerminal
17881793
except (IOError, ImportError, OSError):
17891794
error("The serial terminal functionality requires that the 'mbed-terminal' python module is installed.\nYou can install mbed-terminal by running 'pip install mbed-terminal'.", 1)
17901795

@@ -1808,7 +1813,7 @@ def mbed_sterm(port, baudrate=9600, echo=True, reset=False, sterm=False):
18081813

18091814
# Subparser handling
18101815
parser = argparse.ArgumentParser(prog='mbed',
1811-
description="Command-line code management tool for ARM mbed OS - http://www.mbed.com\nversion %s\n\nUse 'mbed <command> -h|--help' for detailed help.\nOnline manual and guide available at https://github.com/ARMmbed/mbed-cli" % ver,
1816+
description="Command-line code management tool for ARM mbed OS - http://www.mbed.com\nversion %s\n\nUse \"mbed <command> -h|--help\" for detailed help.\nOnline manual and guide available at https://github.com/ARMmbed/mbed-cli" % ver,
18121817
formatter_class=argparse.RawTextHelpFormatter)
18131818
subparsers = parser.add_subparsers(title="Commands", metavar=" ")
18141819
parser.add_argument("--version", action="store_true", dest="version", help="print version number and exit")
@@ -1963,7 +1968,7 @@ def new(name, scm='git', program=False, library=False, mbedlib=False, create_onl
19631968
description=(
19641969
"Imports mbed program and its dependencies from a source control based URL\n"
19651970
"(GitHub, Bitbucket, mbed.org) into the current directory or specified\npath.\n"
1966-
"Use 'mbed add <URL>' to add a library into an existing program."))
1971+
"Use \"mbed add <URL>\" to add a library into an existing program."))
19671972
def import_(url, path=None, ignore=False, depth=None, protocol=None, insecure=False, offline=False, top=True):
19681973
global cwd_root
19691974
offline_warning(offline, top)
@@ -2041,7 +2046,7 @@ def import_(url, path=None, ignore=False, depth=None, protocol=None, insecure=Fa
20412046
description=(
20422047
"Adds mbed library and its dependencies from a source control based URL\n"
20432048
"(GitHub, Bitbucket, mbed.org) into an existing program.\n"
2044-
"Use 'mbed import <URL>' to import as a program"))
2049+
"Use \"mbed import <URL>\" to import as a program"))
20452050
def add(url, path=None, ignore=False, depth=None, protocol=None, insecure=False, offline=False, top=True):
20462051
offline_warning(offline, top)
20472052

@@ -2065,7 +2070,7 @@ def add(url, path=None, ignore=False, depth=None, protocol=None, insecure=False,
20652070
hidden_aliases=['rm', 'rem'],
20662071
description=(
20672072
"Remove specified library, its dependencies and references from the current\n"
2068-
"You can re-add the library from its URL via 'mbed add <library URL>'."))
2073+
"You can re-add the library from its URL via \"mbed add <URL>\"."))
20692074
def remove(path):
20702075
repo = Repo.fromrepo()
20712076
if not Repo.isrepo(path):
@@ -2088,8 +2093,8 @@ def remove(path):
20882093
help='Find and add missing libraries',
20892094
description=(
20902095
"Import missing dependencies in an existing program or library.\n"
2091-
"Use 'mbed import <URL>' and 'mbed add <URL>' instead of cloning manually and\n"
2092-
"then running 'mbed deploy'"))
2096+
"Hint: Use \"mbed import <URL>\" and \"mbed add <URL>\" instead of cloning\n"
2097+
"manually and then running \"mbed deploy\""))
20932098
def deploy(ignore=False, depth=None, protocol=None, insecure=False, offline=False, top=True):
20942099
offline_warning(offline, top)
20952100

@@ -2444,7 +2449,7 @@ def status_(ignore=False):
24442449
dict(name=['--sterm'], action='store_true', help='Open serial terminal after compiling. Can be chained with --flash'),
24452450
dict(name=['-N', '--artifact-name'], help='Name of the built program or library'),
24462451
dict(name=['-S', '--supported'], dest='supported', const=True, choices=["matrix", "toolchains", "targets"], nargs="?", help='Shows supported matrix of targets and toolchains'),
2447-
dict(name='--app-config', dest="app_config", help="Path of an app configuration file (Default is to look for 'mbed_app.json')"),
2452+
dict(name='--app-config', dest="app_config", help="Path of an application configuration file. Default is to look for \"mbed_app.json\"."),
24482453
help='Compile code using the mbed build tools',
24492454
description="Compile this program using the mbed build tools.")
24502455
def compile_(toolchain=None, target=None, profile=False, compile_library=False, compile_config=False, config_prefix=None, source=False, build=False, clean=False, flash=False, sterm=False, artifact_name=None, supported=False, app_config=None):
@@ -2532,15 +2537,15 @@ def compile_(toolchain=None, target=None, profile=False, compile_library=False,
25322537
try:
25332538
from mbed_host_tests.host_tests_toolbox import flash_dev
25342539
except (IOError, ImportError, OSError):
2535-
error("The '-f/--flash' option requires that the 'mbed-greentea' python module is installed.\nYou can install mbed-greentea by running 'pip install mbed-greentea'.", 1)
2540+
error("The '-f/--flash' option requires that the 'mbed-greentea' python module is installed.\nYou can install mbed-greentea by running \"%s -m pip install mbed-greentea\"." % python_cmd, 1)
25362541

25372542
if flash:
25382543
fw_name = artifact_name if artifact_name else program.name
25392544
fw_fbase = os.path.join(build_path, fw_name)
25402545
fw_file = fw_fbase + ('.hex' if os.path.exists(fw_fbase+'.hex') else '.bin')
25412546
if not os.path.exists(fw_file):
25422547
error("Build program file (firmware) not found \"%s\"" % fw_file, 1)
2543-
if not flash_dev(detected['msd'], fw_file, program_cycle_s=2):
2548+
if not flash_dev(detected['msd'], fw_file, program_cycle_s=4):
25442549
error("Unable to flash the target board connected to your system.", 1)
25452550

25462551
if flash or sterm:
@@ -2564,7 +2569,7 @@ def compile_(toolchain=None, target=None, profile=False, compile_library=False,
25642569
dict(name=['--profile'], action='append', help='Path of a build profile configuration file. Example: mbed-os/tools/profiles/debug.json'),
25652570
dict(name=['-c', '--clean'], action='store_true', help='Clean the build directory before compiling'),
25662571
dict(name='--test-spec', dest="test_spec", help="Path used for the test spec file used when building and running tests (the default path is the build directory)"),
2567-
dict(name='--app-config', dest="app_config", help="Path of an app configuration file (Default is to look for 'mbed_app.json')"),
2572+
dict(name='--app-config', dest="app_config", help="Path of an application configuration file. Default is to look for \"mbed_app.json\""),
25682573
dict(name='--test-config', dest="test_config", help="Path or mbed OS keyword of a test configuration file. Example: ethernet, odin_wifi, or path/to/config.json"),
25692574
help='Find, build and run tests',
25702575
description="Find, build, and run tests in a program and libraries")
@@ -2659,7 +2664,7 @@ def test_(toolchain=None, target=None, compile_list=False, run_list=False, compi
26592664
dict(name='--source', action='append', help='Source directory. Default: . (current dir)'),
26602665
dict(name=['-c', '--clean'], action='store_true', help='Clean the build directory before compiling'),
26612666
dict(name=['-S', '--supported'], dest='supported', const=True, choices=['matrix', 'ides'], nargs='?', help='Shows supported matrix of targets and toolchains'),
2662-
dict(name='--app-config', dest="app_config", help="Path of an app configuration file (Default is to look for 'mbed_app.json')"),
2667+
dict(name='--app-config', dest="app_config", help="Path of an application configuration file. Default is to look for \"mbed_app.json\""),
26632668
help='Generate an IDE project',
26642669
description=(
26652670
"Generate IDE project files for the current program."))
@@ -2751,7 +2756,7 @@ def detect():
27512756

27522757
if unknown_found:
27532758
warning("If you're developing a new target, you can mock the device to continue your development. "
2754-
"Use 'mbedls --mock ID:NAME' to do so (see 'mbedls --help' for more information)")
2759+
"Use \"mbedls --mock ID:NAME\" to do so. See \"mbedls --help\" for more information.")
27552760

27562761

27572762
# Serial terminal command
@@ -2851,7 +2856,7 @@ def config_(var=None, value=None, global_cfg=False, unset=False, list_config=Fal
28512856
if program.is_cwd and not var == 'ROOT':
28522857
error(
28532858
"Could not find mbed program in current path \"%s\".\n"
2854-
"Change the current directory to a valid mbed program, set the current directory as an mbed program with 'mbed config root .', or use the '--global' option to set global configuration." % program.path)
2859+
"Change the current directory to a valid mbed program, set the current directory as an mbed program with \"mbed config root .\", or use the '--global' option to set global configuration." % program.path)
28552860
with cd(program.path):
28562861
if unset:
28572862
program.set_cfg(var, None)
@@ -2874,7 +2879,7 @@ def config_(var=None, value=None, global_cfg=False, unset=False, list_config=Fal
28742879
help='Set or get default target',
28752880
description=(
28762881
"Set or get default toolchain\n"
2877-
"This is an alias to 'mbed config [--global] target [name]'\n"))
2882+
"This is an alias to \"mbed config [--global] target [name]\"\n"))
28782883
def target_(name=None, global_cfg=False, supported=False):
28792884
if supported:
28802885
return compile_(supported=supported)
@@ -2888,7 +2893,7 @@ def target_(name=None, global_cfg=False, supported=False):
28882893
help='Set or get default toolchain',
28892894
description=(
28902895
"Set or get default toolchain\n"
2891-
"This is an alias to 'mbed config [--global] toolchain [name]'\n"))
2896+
"This is an alias to \"mbed config [--global] toolchain [name]\"\n"))
28922897
def toolchain_(name=None, global_cfg=False, supported=False):
28932898
if supported:
28942899
return compile_(supported=supported)
@@ -3001,8 +3006,11 @@ def main():
30013006
status = pargs.command(pargs)
30023007
except ProcessException as e:
30033008
error(
3004-
"\"%s\" returned error code %d.\n"
3005-
"Command \"%s\" in \"%s\"" % (e.args[1], e.args[0], e.args[2], e.args[3]), e.args[0])
3009+
"\"%s\" returned error.\n"
3010+
"Code: %d\n"
3011+
"Path: \"%s\"\n"
3012+
"Command: \"%s\"\n"
3013+
"Tip: You could retry the last command with \"-v\" flag for verbose output\n" % (e.args[1], e.args[0], e.args[3], e.args[2]), e.args[0])
30063014
except OSError as e:
30073015
if e.args[0] == errno.ENOENT:
30083016
error(

0 commit comments

Comments
 (0)