From 504903607bbf8a76a6210f73f527c81f1eb4a044 Mon Sep 17 00:00:00 2001 From: Alessandro Thea Date: Sun, 4 Apr 2021 01:28:23 +0200 Subject: [PATCH] #128 - Moving cmds/vivado to rich --- requirements.txt | 4 +- src/ipbb/cmds/vivado.py | 157 +++++++++++------------- src/ipbb/scripts/builder.py | 96 ++++----------- src/ipbb/tools/xilinx/vivado_console.py | 3 +- src/ipbb/utils.py | 10 +- 5 files changed, 105 insertions(+), 165 deletions(-) diff --git a/requirements.txt b/requirements.txt index e9a3da44..5aca4b3d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,5 +10,5 @@ pexpect==4.8.0 psutil==5.8.0 pytest==6.2.2 PyYAML==5.4.1 -rich==9.13.0 -sh==1.14.1 \ No newline at end of file +rich==10.1.0 +sh==1.14.1 diff --git a/src/ipbb/cmds/vivado.py b/src/ipbb/cmds/vivado.py index c2fc9685..68881ad5 100644 --- a/src/ipbb/cmds/vivado.py +++ b/src/ipbb/cmds/vivado.py @@ -13,14 +13,15 @@ # Elements from os.path import join, split, exists, splitext, abspath, basename -from click import echo, secho, style, confirm -from texttable import Texttable +# from click import echo, secho, style, confirm from collections import OrderedDict +from rich.table import Table from .dep import hash +from ..console import cprint, console from ..tools.common import which, SmartOpen, mkdir -from ..utils import ensureNoParsingErrors, ensureNoMissingFiles, echoVivadoConsoleError +from ..utils import ensureNoParsingErrors, ensureNoMissingFiles, logVivadoConsoleError from ..generators.vivadoproject import VivadoProjectGenerator from ..tools.xilinx import VivadoSession, VivadoSessionManager, VivadoConsoleError, VivadoSnoozer, VivadoProject @@ -145,13 +146,14 @@ def genproject(env, aEnableIPCache, aOptimise, aToScript, aToStdout): ) except VivadoConsoleError as lExc: - echoVivadoConsoleError(lExc) + logVivadoConsoleError(lExc) raise click.Abort() except RuntimeError as lExc: - secho( - "Error caught while generating Vivado TCL commands:\n" + "\n".join(lExc), - fg='red', + cprint( + "Error caught while generating Vivado TCL commands:", + style='red', ) + cprint(lExc) raise click.Abort() # ------------------------------------------------------------------------- @@ -181,12 +183,12 @@ def checksyntax(env): lConsole('check_syntax') except VivadoConsoleError as lExc: - echoVivadoConsoleError(lExc) + logVivadoConsoleError(lExc) raise click.Abort() - secho( + cprint( "\n{}: Synthax check completed successfully.\n".format(env.currentproj.name), - fg='green', + style='green', ) # ------------------------------------- @@ -225,9 +227,9 @@ def synth(env, aNumJobs, aUpdateInt): # Reset IP runs, if needed for run in lIPRunsToReset: - secho( - 'IP run {} found in running state. Resetting.'.format(run), - fg='yellow', + cprint( + f"IP run {run} found in running state. Resetting.", + style='yellow', ) lConsole('reset_run {}'.format(run)) @@ -237,10 +239,10 @@ def synth(env, aNumJobs, aUpdateInt): # Monitor OOC and synth run progress if not aUpdateInt: - secho("Run monitoring disabled", fg='cyan') + cprint("Run monitoring disabled", style='cyan') lConsole('wait_on_run synth_1') else: - secho("Starting run monitoring loop, update interval: {} min(s)".format(aUpdateInt), fg='cyan') + cprint(f"Starting run monitoring loop, update interval: {aUpdateInt} min(s)", style='cyan') while True: with VivadoSnoozer(lConsole): @@ -254,13 +256,13 @@ def synth(env, aNumJobs, aUpdateInt): ] if lPendingOOCRuns: - secho('\n' + makeRunsTable(lOOCRunProps).draw(), fg='cyan') + cprint(makeRunsTable(lOOCRunProps), style='light_sky_blue1') else: - secho('\n OOC runs: {} completed.'.format(len(lOOCRunProps)), fg='cyan') + cprint(f"OOC runs: {len(lOOCRunProps)} completed.", style='light_sky_blue1') lSynthProps = { k: v for k, v in lRunProps.items() if k == lSynthRun } - secho('\n' + makeRunsTable(lSynthProps).draw(), fg='cyan') + cprint(makeRunsTable(lSynthProps), style='light_sky_blue1') lRunsInError = [ k for k, v in lRunProps.items() if v['STATUS'] == 'synth_design ERROR'] if lRunsInError: @@ -273,18 +275,19 @@ def synth(env, aNumJobs, aUpdateInt): lConsole('wait_on_run synth_1 -timeout {}'.format(aUpdateInt)) except VivadoConsoleError as lExc: - echoVivadoConsoleError(lExc) + logVivadoConsoleError(lExc) raise click.Abort() except RuntimeError as lExc: - secho( - "ERROR: " + str(lExc), - fg='red', + console.log( + "ERROR", + style='red', ) + console.log(lExc) raise click.Abort() - secho( - "\n{}: Synthesis completed successfully.\n".format(env.currentproj.name), - fg='green', + console.log( + f"{env.currentproj.name}: Synthesis completed successfully.", + style='green', ) @@ -329,12 +332,12 @@ def impl(env, aNumJobs, aStopOnTimingErr): lConsole(c) except VivadoConsoleError as lExc: - echoVivadoConsoleError(lExc) + logVivadoConsoleError(lExc) raise click.Abort() - secho( - "\n{}: Implementation completed successfully.\n".format(env.currentproj.name), - fg='green', + console.log( + f"{env.currentproj.name}: Implementation completed successfully.\n", + style='green', ) @@ -367,7 +370,7 @@ def resource_usage(env, aCell, aDepth, aFile): ): lConsole(c) except VivadoConsoleError as lExc: - echoVivadoConsoleError(lExc) + logVivadoConsoleError(lExc) raise click.Abort() @@ -394,11 +397,12 @@ def bitfile(env): lConsole(lWriteBitStreamCmd) except VivadoConsoleError as lExc: - echoVivadoConsoleError(lExc) + logVivadoConsoleError(lExc) raise click.Abort() - secho( - "\n{}: Bitfile successfully written.\n".format(env.currentproj.name), fg='green' + console.log( + f"{env.currentproj.name}: Bitfile successfully written.", + style='green' ) @@ -431,14 +435,14 @@ def debugprobes(env): lConsole(lWriteDebugProbesCmd) except VivadoConsoleError as lExc: - echoVivadoConsoleError(lExc) + logVivadoConsoleError(lExc) raise click.Abort() - secho( - "\n{}: Debug probes file successfully written.\n".format(env.currentproj.name), fg='green' + console.log( + f"{env.currentproj.name}: Debug probes file successfully written.", + style='green' ) - # ------------------------------------------------------------------------------ def memcfg(env): '''Create a memcfg file for PROM programming @@ -464,7 +468,7 @@ def memcfg(env): lBaseName = env.vivadoProdFileBase if 'vivado' not in lDepFileParser.settings: - secho('No memcfg settings found in this project. Exiting.', fg='yellow') + cprint('No memcfg settings found in this project. Exiting.', style='yellow') return lBitPath = lBaseName + '.bit' @@ -494,13 +498,13 @@ def memcfg(env): ) ) except VivadoConsoleError as lExc: - echoVivadoConsoleError(lExc) + logVivadoConsoleError(lExc) raise click.Abort() - secho( - "\n{}: {}file successfully written.\n".format(k.capitalize(), env.currentproj.name), fg='green' - ) - + console.log( + f"{env.currentproj.name}: {k.capitalize} file successfully written.", + style='green' + ) # ------------------------------------------------------------------------------ def readRunInfo(aConsole, aProps=None): @@ -529,22 +533,16 @@ def readRunInfo(aConsole, aProps=None): return lInfos # ------------------------------------------------------------------------------ -def makeRunsTable(lInfos): - lSummary = Texttable(max_width=0) - if not lInfos: +def makeRunsTable(aInfos, title=None): + lSummary = Table("Run", *list(next(iter(aInfos.values()))), title=title) + if not aInfos: return lSummary - # lSummary.set_deco(Texttable.HEADER | Texttable.BORDER) - lSummary.set_deco(Texttable.HEADER | Texttable.BORDER) - lSummary.set_chars( ['-', '|', '+', '-'] ) - lSummary.header(['Run'] + list(next(iter(lInfos.values())))) - for lRun in sorted(lInfos): - lInfo = lInfos[lRun] - lSummary.add_row([lRun] + list(lInfo.values())) - + for lRun in sorted(aInfos): + lInfo = aInfos[lRun] + lSummary.add_row(lRun, *list(lInfo.values())) return lSummary - # ------------------------------------------------------------------------------ def status(env): '''Show the status of all runs in the current project.''' @@ -577,18 +575,15 @@ def status(env): lInfos = lProject.readRunInfo(lProps) except VivadoConsoleError as lExc: - echoVivadoConsoleError(lExc) + logVivadoConsoleError(lExc) raise click.Abort() - echo() + # echo() - lOocTable = makeRunsTable({ k: v for k, v in lInfos.items() if lOOCRegex.match(k)}) - secho("Out of context runs", fg='blue') - echo(lOocTable.draw()) - echo() - secho("Design runs", fg='blue') - aaa = makeRunsTable({ k: v for k, v in lInfos.items() if lRunRegex.match(k)}) - echo(aaa.draw()) + lOocTable = makeRunsTable({ k: v for k, v in lInfos.items() if lOOCRegex.match(k)}, title="Out of context runs") + cprint(lOocTable) + lDesignRuns = makeRunsTable({ k: v for k, v in lInfos.items() if lRunRegex.match(k)}, title="Design runs") + cprint(lDesignRuns) # ------------------------------------------------------------------------------ @@ -614,12 +609,12 @@ def reset(env): lConsole(c) except VivadoConsoleError as lExc: - echoVivadoConsoleError(lExc) + logVivadoConsoleError(lExc) raise click.Abort() - secho( - "\n{}: synth_1 and impl_1 successfully reset.\n".format(env.currentproj.name), - fg='green', + console.log( + f"{env.currentproj.name}: synth_1 and impl_1 successfully reset.", + style='green', ) # ------------------------------------------------------------------------------ @@ -633,7 +628,7 @@ def package(env, aTag): ensureVivado(env) if not exists(env.vivadoProjFile): - secho('Vivado project does not exist. Creating the project...', fg='yellow') + cprint('Vivado project does not exist. Creating the project...', style='yellow') genproject(env, True, True, None, False) lProjName = env.currentproj.name @@ -643,7 +638,7 @@ def package(env, aTag): lBaseName = env.vivadoProdFileBase lBitPath = lBaseName + '.bit' if not exists(lBitPath): - secho('Bitfile does not exist. Attempting a build ...', fg='yellow') + cprint('Bitfile does not exist. Starting a build ...', style='yellow') bitfile(env) try: @@ -675,7 +670,7 @@ def package(env, aTag): # ------------------------------------------------------------------------- # Generate a json signature file - secho("Generating summary files", fg='blue') + console.log("Generating summary files", style='blue') # ------------------------------------------------------------------------- @@ -699,21 +694,19 @@ def package(env, aTag): # ------------------------------------------------------------------------- # Copy bitfile, memcfg, and address table into the packaging area - secho("Collecting bitfile", fg='blue') + console.log("Collecting bitfile", style='blue') sh.cp('-av', lBitPath, lPkgSrcPath, _out=sys.stdout) echo() for f in lMemCfgFiles: - secho("Collecting memcfg {}".format(f), fg='blue') + console.log("Collecting memcfg {}".format(f), style='blue') sh.cp('-av', f, lPkgSrcPath, _out=sys.stdout) - echo() if lDebugProbesPath: - secho("Collecting debug-probes file", fg='blue') + console.log("Collecting debug-probes file", style='blue') sh.cp('-av', lDebugProbesPath, lPkgSrcPath, _out=sys.stdout) - echo() - secho("Collecting address tables", fg='blue') + console.log("Collecting address tables", style='blue') for addrtab in env.depParser.commands['addrtab']: sh.cp('-avL', addrtab.filepath, join(lPkgSrcPath, 'addrtab'), _out=sys.stdout) echo() @@ -721,7 +714,7 @@ def package(env, aTag): # ------------------------------------------------------------------------- # Tar everything up - secho("Generating tarball", fg='blue') + console.log("Generating tarball", style='blue') lTgzBaseName = '_'.join( [env.currentproj.settings['name']] @@ -743,9 +736,9 @@ def package(env, aTag): ) echo() - secho( - "Package " + style('%s' % lTgzPath, fg='green') + " successfully created.", - fg='green', + console.log( + f"Package {lTgzPath} successfully created.", + style='green', ) # ------------------------------------------------------------------------- @@ -769,7 +762,7 @@ def archive(env): ) ) except VivadoConsoleError as lExc: - echoVivadoConsoleError(lExc) + logVivadoConsoleError(lExc) raise click.Abort() diff --git a/src/ipbb/scripts/builder.py b/src/ipbb/scripts/builder.py index 99bf35d7..f8f1b1fe 100755 --- a/src/ipbb/scripts/builder.py +++ b/src/ipbb/scripts/builder.py @@ -5,14 +5,13 @@ import ipbb import sys import traceback -import rich from io import StringIO, BytesIO from ..context import Context from ..depparser import DepFormatter -from ..console import cprint +from ..console import cprint, console from .._version import __version__ # ------------------------------------------------------------------------------ @@ -87,55 +86,6 @@ def _compose_cli(): climain.add_command(debug.debug) - -# ------------------------------------------------------------------------------ -def validate_completion(): - """ - This function should be moved to an unit test - """ - - _compose_cli() - - from click._bashcomplete import get_choices - - def choices_without_help(cli, args, incomplete): - completions = get_choices(cli, 'dummy', args, incomplete) - return [c[0] for c in completions] - - for inc in [ - '', - 'f', - 'felix-pie', - 'felix-pie:', - 'felix-pie:p', - 'felix-pie:projects/', - 'felix-pie:projects/hi', - 'felix-pie:projects/hitfinder/' - ]: - print("-" * 80) - print("Completing component'" + inc + "'") - print("-" * 80) - print(choices_without_help(climain, ['proj', 'create', 'vivado', 'jbsc-hf-fc-tightG'], inc)) - print() - - for inc in [ - '', - ]: - print("-" * 80) - print("Completing dep file'" + inc + "'") - print("-" * 80) - print(choices_without_help(climain, ['ipbb', 'toolbox', 'check-dep', 'felix-pie:projects/hitfinder'], inc)) - print() - - for inc in [ - '', - ]: - print("-" * 80) - print("Completing dep file'" + inc + "'") - print("-" * 80) - print(choices_without_help(climain, ['proj', 'create', 'vivado', 'jbsc-hf-fc-tightG', 'felix-pie:projects/hitfinder', '-t'], inc)) - print() - raise SystemExit(0) # ------------------------------------------------------------------------------ def main(): '''Discovers the env at startup''' @@ -150,30 +100,28 @@ def main(): try: climain(obj=obj, show_default=True) except Exception as e: - from sys import version_info - exc_type, exc_obj, exc_tb = sys.exc_info() - lFirstFrame = traceback.extract_tb(exc_tb)[-1] - - cprint( - u"ERROR ('{}' exception caught): '{}'\n\nFile \"{}\", line {}, in {}\n {}".format( - exc_type.__name__, - e, - lFirstFrame[0], - lFirstFrame[1], - lFirstFrame[2], - lFirstFrame[3], - ), - markup=False, - style='red', - ) - + # from sys import version_info + # exc_type, exc_obj, exc_tb = sys.exc_info() + # lFirstFrame = traceback.extract_tb(exc_tb)[-1] + + # cprint( + # u"ERROR ('{}' exception caught): '{}'\n\nFile \"{}\", line {}, in {}\n {}".format( + # exc_type.__name__, + # e, + # lFirstFrame[0], + # lFirstFrame[1], + # lFirstFrame[2], + # lFirstFrame[3], + # ), + # markup=False, + # style='red', + # ) + + console.log(e) + if obj.printExceptionStack: - lExc = StringIO() - traceback.print_exc(file=lExc) - cprint("Exception in user code:") - cprint('-' * 60) - cprint(lExc.getvalue(), style='red') - cprint('-' * 60) + console.print_exception() + raise SystemExit(-1) diff --git a/src/ipbb/tools/xilinx/vivado_console.py b/src/ipbb/tools/xilinx/vivado_console.py index e57d26e5..1f85f834 100644 --- a/src/ipbb/tools/xilinx/vivado_console.py +++ b/src/ipbb/tools/xilinx/vivado_console.py @@ -174,7 +174,7 @@ def __init__(self, executable='vivado', prompt=None, stopOnCWarnings=False, echo echo=echo, logfile=self._out, encoding=DEFAULT_ENCODING, - # preexec_fn=on_parent_exit('SIGTERM') + preexec_fn=on_parent_exit('SIGTERM') ) # Compile the list of patterns to detect the prompt @@ -393,7 +393,6 @@ class VivadoSession(VivadoConsole): """Summary """ - pass diff --git a/src/ipbb/utils.py b/src/ipbb/utils.py index 0f933902..1341f6ea 100644 --- a/src/ipbb/utils.py +++ b/src/ipbb/utils.py @@ -10,7 +10,7 @@ from rich.table import Table from .tools.alien import AlienBranch -from .console import cprint +from .console import cprint, console from .depparser import DepFormatter # ------------------------------------------------------------------------------ @@ -145,10 +145,10 @@ def ensureNoMissingFiles(aCurrentProj, aDepFileParser): # ------------------------------------------------------------------------------ -def echoVivadoConsoleError( aExc ): - cprint("Vivado error/critical warnings detected", style='red') - cprint("\n".join(aExc.errors), markup=False, style='red') - cprint("\n".join(aExc.criticalWarns), markup=False, style='yellow') +def logVivadoConsoleError( aExc ): + console.log("Vivado error/critical warnings detected", style='red') + console.log("\n".join(aExc.errors), markup=False, style='red') + console.log("\n".join(aExc.criticalWarns), markup=False, style='yellow') # ------------------------------------------------------------------------------