From 688818b4d4ea3bed5173d70ab3be478c19acc348 Mon Sep 17 00:00:00 2001 From: JensDiemer Date: Wed, 19 Aug 2015 18:04:51 +0200 Subject: [PATCH 1/5] update README --- README.creole | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.creole b/README.creole index 0f858201..6da16c58 100644 --- a/README.creole +++ b/README.creole @@ -79,7 +79,7 @@ Special feature: The Line number that are used in GOTO, SOGUB etc. are extra mar == installation -IMPORTANT: The **PyPi package** name is **DragonPyEmulator** and [[https://github.com/jpanganiban/dragonpy/issues/3|not only DragonPy]]!!! +IMPORTANT: The **PyPi package** name is **DragonPyEmulator** and [[https://github.com/jpanganiban/dragonpy/issues/3|not only "DragonPy"]]!!! === Linux @@ -148,8 +148,6 @@ The following is hopeful the easiest one: The default {{{boot_dragonpy.cmd}}} will install via {{{Python Package Index}}} (PyPi) into {{{%APPDATA%\DragonPy_env}}} -There exist some {{{.cmd}}} batch files for easy startup in {{{%APPDATA%\DragonPy_env\}}} - ==== start DragonPy The is a simple "starter GUI", just call the cli without arguments: @@ -294,7 +292,6 @@ e.g. The Dragon 32 6809 machine with a 14.31818 MHz crystal runs with: == TODO: -# implement a easy tkinter startup helper # implement more Dragon 32 periphery missing 6809 unittests after coverage run: @@ -435,7 +432,7 @@ generic syntax highlighter == History -* [[https://github.com/jedie/DragonPy/compare/v0.5.0...v0.5.1|??.08.2015 - v0.5.1]]: (not released, yet) +* [[https://github.com/jedie/DragonPy/compare/v0.5.0...v0.5.1|19.08.2015 - v0.5.1]]: (not released, yet) ** Add a "starter GUI" ** Add work-a-round for tkinter usage with virtualenv under windows, see: [[https://github.com/pypa/virtualenv/issues/93|virtualenv issues #93]] ** bugfix e.g.: keyboard input in "sbc09" emulation From fb56d5f34acced3a5c01955acdce1d9043a35bf6 Mon Sep 17 00:00:00 2001 From: JensDiemer Date: Thu, 20 Aug 2015 09:09:47 +0200 Subject: [PATCH 2/5] Add run 'MC6809 benchmark' button --- dragonpy/core/cli.py | 5 +- dragonpy/core/gui_starter.py | 94 +++++++++++++++++++++++++----------- 2 files changed, 70 insertions(+), 29 deletions(-) diff --git a/dragonpy/core/cli.py b/dragonpy/core/cli.py index bf7c0f95..cb55d7e7 100755 --- a/dragonpy/core/cli.py +++ b/dragonpy/core/cli.py @@ -34,7 +34,7 @@ from basic_editor.editor import run_basic_editor import dragonpy -from dragonpy.core.gui_starter import start_gui +from dragonpy.core.gui_starter import StarterGUI from dragonpy.CoCo.config import CoCo2bCfg from dragonpy.CoCo.machine import run_CoCo2b from dragonpy.Dragon32.config import Dragon32Cfg @@ -206,7 +206,8 @@ def confirm(): click.prompt("Please press [ENTER] to exit", default="", show_default=False) atexit.register(confirm) - start_gui(__file__, machine_dict) + gui = StarterGUI(machine_dict) + gui.mainloop() else: cli() diff --git a/dragonpy/core/gui_starter.py b/dragonpy/core/gui_starter.py index 3dd2767d..963df1b2 100644 --- a/dragonpy/core/gui_starter.py +++ b/dragonpy/core/gui_starter.py @@ -14,6 +14,7 @@ import subprocess import sys import logging +import click import os @@ -103,23 +104,37 @@ def __init__(self, master, **kwargs): variable=self.var_machine, value=machine_name) b.grid(row=row, column=1, sticky=tk.W) - _row=len(self.machine_dict) - button_run = tk.Button(self, width=25, text="run machine", command=master.run_machine ) - button_run.grid(row=_row, column=1) + button_run.grid(row=len(self.machine_dict), column=1) + + + +class ActionButtonsFrame(tk.LabelFrame): + def __init__(self, master, **kwargs): + tk.LabelFrame.__init__(self, master, text="other actions") + self.grid(**kwargs) - _row+=1 + _column=0 button_run = tk.Button(self, width=25, - text="run only BASIC editor", + text="BASIC editor", command=master.run_basic_editor ) - button_run.grid(row=_row, column=1) + button_run.grid(row=0, column=_column) + + _column+=1 + + button_run = tk.Button(self, + width=25, + text="MC6809 benchmark", + command=master.run_6809_benchmark + ) + button_run.grid(row=0, column=1) class MultiStatusBar(tk.Frame): @@ -142,11 +157,10 @@ def set_label(self, name, text='', side=tk.LEFT): label.config(text=text) -class GuiStarter(tk.Tk): - def __init__(self, cli_file, machine_dict): +class StarterGUI(tk.Tk): + def __init__(self, machine_dict): tk.Tk.__init__(self) - self.cli_file = os.path.abspath(cli_file) self.machine_dict = machine_dict self.geometry("+%d+%d" % ( @@ -173,54 +187,80 @@ def add_widgets(self): } self.frame_settings = SettingsFrame(self, column=0, row=0, **defaults) - self.frame_buttons = RunButtonsFrame(self, column=1, row=0, **defaults) - self.status_bar = MultiStatusBar(self, column=0, row=1, columnspan=2, + self.frame_run_buttons = RunButtonsFrame(self, column=1, row=0, **defaults) + self.frame_action_buttons = ActionButtonsFrame(self, column=0, row=1, columnspan=2, **defaults) + self.status_bar = MultiStatusBar(self, column=0, row=2, columnspan=2, sticky=tk.NSEW, ) def set_status_bar(self): - self.status_bar.set_label("cli_file", self.cli_file) self.status_bar.set_label("python_info", get_python_info()) + def _print_run_info(self, txt): + click.echo("\n") + click.secho(txt, bg='blue', fg='white', bold=True, underline=True) + + def _print_args_info(self, *args): + click.echo("\tadd: %s" % click.style(" ".join(args), bold=True)) + def _run(self, *args): + """ + Run current executable via subprocess and given args + """ + print("execute: %s" % " ".join(args)) + subprocess.Popen(args) + + def _run_dragonpy_cli(self, *args): + """ + Run DragonPy cli with given args. + Add "--verbosity" from GUI. + """ verbosity = self.frame_settings.var_verbosity.get() verbosity_no = VERBOSITY_DICT2[verbosity] - print("Verbosity: %i (%s)" % (verbosity_no, verbosity)) + log.debug("Verbosity: %i (%s)" % (verbosity_no, verbosity)) + + verbosity_args = ["--verbosity", "%s" % verbosity_no] + self._print_args_info(*verbosity_args) cmd_args = [ - sys.executable, - self.cli_file, - "--verbosity", "%s" % verbosity_no, + "DragonPy", # "--log_list", # "--log", # "dragonpy.components.cpu6809,40", # "dragonpy.Dragon32.MC6821_PIA,50", ] + cmd_args += verbosity_args cmd_args += args - print("Startup CLI with: %s" % " ".join(cmd_args[1:])) - subprocess.Popen(cmd_args) + self._run(*cmd_args) def _run_command(self, command): """ - :param command: string like "run" or "editor" - :return: None + Run DragonPy cli with given command like "run" or "editor" + Add "--machine" from GUI. + "--verbosity" will also be set, later. """ - machine_name = self.frame_buttons.var_machine.get() - self._run("--machine", machine_name, command) + machine_name = self.frame_run_buttons.var_machine.get() + args = ["--machine", machine_name] + self._print_args_info(*args) + args.append(command) + self._run_dragonpy_cli(*args) def run_machine(self): - print("Run machine emulation") + self._print_run_info("Run machine emulation") self._run_command("run") def run_basic_editor(self): - print("Run only the BASIC editor") + self._print_run_info("Run only the BASIC editor") self._run_command("editor") + def run_6809_benchmark(self): + self._print_run_info("Run MC6809 benchmark") + cmd_args = [ + "MC6809", "benchmark" + ] + self._run(*cmd_args) -def start_gui(cli_file, machine_dict): - gui = GuiStarter(cli_file, machine_dict) - gui.mainloop() if __name__ == "__main__": From 8eac2b68a95f5f70ea8ea0f16e0aa4e49904361c Mon Sep 17 00:00:00 2001 From: Jens Diemer Date: Thu, 20 Aug 2015 22:21:12 +0200 Subject: [PATCH 3/5] remove obsolete scripts --- .../create_coverage_report.cmd | 41 ------------------- dev_startup_scripts/create_coverage_report.sh | 36 ---------------- dev_startup_scripts/create_profile.sh | 5 --- dev_startup_scripts/run_BASIC_Editor_loop.cmd | 21 ---------- dev_startup_scripts/run_BASIC_Editor_loop.sh | 15 ------- dev_startup_scripts/run_CoCo2b_PyPy2_loop.cmd | 21 ---------- dev_startup_scripts/run_CoCo2b_PyPy3_loop.cmd | 21 ---------- .../run_Dragon32_CPython2_loop.cmd | 20 --------- .../run_Dragon32_PyPy2_loop.cmd | 21 ---------- dev_startup_scripts/run_Dragon64_CPython2.sh | 24 ----------- .../run_Dragon64_CPython2_loop.cmd | 21 ---------- dev_startup_scripts/run_Dragon64_CPython3.sh | 23 ----------- .../run_Dragon64_CPython3_loop.cmd | 20 --------- dev_startup_scripts/run_Dragon64_PyPy2.sh | 23 ----------- dev_startup_scripts/run_Dragon64_loop.cmd | 21 ---------- .../run_all_tests_CPython2_loop.cmd | 22 ---------- .../run_all_tests_CPython3_loop.cmd | 21 ---------- .../run_all_tests_PyPy2_loop.cmd | 21 ---------- .../run_all_tests_PyPy3_loop.cmd | 21 ---------- .../run_benchmark_CPython2_loop.cmd | 19 --------- .../run_benchmark_CPython3_loop.cmd | 19 --------- .../run_benchmark_PyPy2_loop.cmd | 20 --------- .../run_benchmark_PyPy3_loop.cmd | 19 --------- 23 files changed, 495 deletions(-) delete mode 100755 dev_startup_scripts/create_coverage_report.cmd delete mode 100755 dev_startup_scripts/create_coverage_report.sh delete mode 100755 dev_startup_scripts/create_profile.sh delete mode 100755 dev_startup_scripts/run_BASIC_Editor_loop.cmd delete mode 100755 dev_startup_scripts/run_BASIC_Editor_loop.sh delete mode 100755 dev_startup_scripts/run_CoCo2b_PyPy2_loop.cmd delete mode 100755 dev_startup_scripts/run_CoCo2b_PyPy3_loop.cmd delete mode 100755 dev_startup_scripts/run_Dragon32_CPython2_loop.cmd delete mode 100755 dev_startup_scripts/run_Dragon32_PyPy2_loop.cmd delete mode 100755 dev_startup_scripts/run_Dragon64_CPython2.sh delete mode 100755 dev_startup_scripts/run_Dragon64_CPython2_loop.cmd delete mode 100755 dev_startup_scripts/run_Dragon64_CPython3.sh delete mode 100755 dev_startup_scripts/run_Dragon64_CPython3_loop.cmd delete mode 100755 dev_startup_scripts/run_Dragon64_PyPy2.sh delete mode 100755 dev_startup_scripts/run_Dragon64_loop.cmd delete mode 100755 dev_startup_scripts/run_all_tests_CPython2_loop.cmd delete mode 100755 dev_startup_scripts/run_all_tests_CPython3_loop.cmd delete mode 100755 dev_startup_scripts/run_all_tests_PyPy2_loop.cmd delete mode 100755 dev_startup_scripts/run_all_tests_PyPy3_loop.cmd delete mode 100755 dev_startup_scripts/run_benchmark_CPython2_loop.cmd delete mode 100755 dev_startup_scripts/run_benchmark_CPython3_loop.cmd delete mode 100755 dev_startup_scripts/run_benchmark_PyPy2_loop.cmd delete mode 100755 dev_startup_scripts/run_benchmark_PyPy3_loop.cmd diff --git a/dev_startup_scripts/create_coverage_report.cmd b/dev_startup_scripts/create_coverage_report.cmd deleted file mode 100755 index 8133565a..00000000 --- a/dev_startup_scripts/create_coverage_report.cmd +++ /dev/null @@ -1,41 +0,0 @@ -@echo off - -title "%~0" - -set python=C:\Python27\python.exe -set coverage2=C:\Python27\Scripts\coverage.exe - -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -if NOT exist %coverage2% ( - echo Error: '%coverage2%' doesn't exists! - echo Please install: https://pypi.python.org/pypi/coverage - echo e.g.: - echo C:\Python27>python.exe get-pip.py - echo C:\Python27\Scripts>pip.exe install coverage - pause - exit 1 -) - -echo on - -cd .. - -REM delete old results -%coverage2% erase - -REM run unittests -%coverage2% run --source=dragonpy setup.py test -REM ~ %coverage2% run setup.py test -s dragonpy.tests.test_BASIC_simple09 - - -REM create coverage html resport files -%coverage2% html - -%python% -m webbrowser -t "htmlcov/index.html" - -@pause \ No newline at end of file diff --git a/dev_startup_scripts/create_coverage_report.sh b/dev_startup_scripts/create_coverage_report.sh deleted file mode 100755 index 152550fc..00000000 --- a/dev_startup_scripts/create_coverage_report.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -coverage2=$(which coverage2) # e.g.: installed via pip -if [ $? != 0 ]; then - coverage2=/usr/bin/python2-coverage -fi - -if [ ! -x ${coverage2} ]; then - echo "Error: coverage2 not found!" - echo "Please install: https://pypi.python.org/pypi/coverage" - echo "e.g.:" - echo " $ sudo apt install python-coverage" - echo "or:" - echo " $ sudo apt install python-pip" - echo " $ sudo pip2 install coverage" - echo "etc." - read -p ENTER ENTER - exit 1 -fi - -set -x - -cd .. - -# delete old results -${coverage2} erase - -# run unittests -${coverage2} run --source=dragonpy setup.py test -#~ ${coverage2} run setup.py test -s dragonpy.tests.test_BASIC_simple09 - - -# create coverage html resport files -${coverage2} html - -python -m webbrowser -t "htmlcov/index.html" \ No newline at end of file diff --git a/dev_startup_scripts/create_profile.sh b/dev_startup_scripts/create_profile.sh deleted file mode 100755 index 575e08c3..00000000 --- a/dev_startup_scripts/create_profile.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -set -x -cd .. -python2 -m cProfile -s cumulative run_all_tests.py | tee profiling.txt \ No newline at end of file diff --git a/dev_startup_scripts/run_BASIC_Editor_loop.cmd b/dev_startup_scripts/run_BASIC_Editor_loop.cmd deleted file mode 100755 index a6e0e834..00000000 --- a/dev_startup_scripts/run_BASIC_Editor_loop.cmd +++ /dev/null @@ -1,21 +0,0 @@ -@echo off - -title "%~0" - -set python=C:\Python27\python.exe -REM ~ set python=D:\pypy-2.3.1-win32\pypy.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd.. - -:loop - cls - echo on - %python% DragonPy_CLI.py editor - @echo off - pause -goto:loop \ No newline at end of file diff --git a/dev_startup_scripts/run_BASIC_Editor_loop.sh b/dev_startup_scripts/run_BASIC_Editor_loop.sh deleted file mode 100755 index 3af4b239..00000000 --- a/dev_startup_scripts/run_BASIC_Editor_loop.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -cd .. - -while true -do - ( - set -x - clear - python2 DragonPy_CLI.py editor - ) - echo - read -n1 -p "Press any key to restart" __ - echo -done \ No newline at end of file diff --git a/dev_startup_scripts/run_CoCo2b_PyPy2_loop.cmd b/dev_startup_scripts/run_CoCo2b_PyPy2_loop.cmd deleted file mode 100755 index 7ee83419..00000000 --- a/dev_startup_scripts/run_CoCo2b_PyPy2_loop.cmd +++ /dev/null @@ -1,21 +0,0 @@ -@echo off - -title "%~nx0" - -REM ~ set python=C:\Python27\python.exe -set python=C:\pypy-2.4.0-win32\pypy.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd.. - -:loop - cls - echo on - %python% DragonPy_CLI.py --machine=CoCo2b run - @echo off - pause -goto:loop \ No newline at end of file diff --git a/dev_startup_scripts/run_CoCo2b_PyPy3_loop.cmd b/dev_startup_scripts/run_CoCo2b_PyPy3_loop.cmd deleted file mode 100755 index e6619201..00000000 --- a/dev_startup_scripts/run_CoCo2b_PyPy3_loop.cmd +++ /dev/null @@ -1,21 +0,0 @@ -@echo off - -title "%~nx0" - -REM ~ set python=C:\Python27\python.exe -set python=C:\pypy3-2.3.1-win32\pypy.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd.. - -:loop - cls - echo on - %python% DragonPy_CLI.py --machine=CoCo2b run - @echo off - pause -goto:loop \ No newline at end of file diff --git a/dev_startup_scripts/run_Dragon32_CPython2_loop.cmd b/dev_startup_scripts/run_Dragon32_CPython2_loop.cmd deleted file mode 100755 index dfba5199..00000000 --- a/dev_startup_scripts/run_Dragon32_CPython2_loop.cmd +++ /dev/null @@ -1,20 +0,0 @@ -@echo off - -title "%~0" - -set python=C:\Python27\python.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd.. - -:loop - cls - echo on - %python% -3 DragonPy_CLI.py --machine=Dragon32 run - @echo off - pause -goto:loop \ No newline at end of file diff --git a/dev_startup_scripts/run_Dragon32_PyPy2_loop.cmd b/dev_startup_scripts/run_Dragon32_PyPy2_loop.cmd deleted file mode 100755 index 39228e57..00000000 --- a/dev_startup_scripts/run_Dragon32_PyPy2_loop.cmd +++ /dev/null @@ -1,21 +0,0 @@ -@echo off - -title "%~0" - -REM ~ set python=C:\Python27\python.exe -set python=C:\pypy-2.3.1-win32\pypy.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd.. - -:loop - cls - echo on - %python% DragonPy_CLI.py --machine=Dragon32 run - @echo off - pause -goto:loop \ No newline at end of file diff --git a/dev_startup_scripts/run_Dragon64_CPython2.sh b/dev_startup_scripts/run_Dragon64_CPython2.sh deleted file mode 100755 index 00f4708f..00000000 --- a/dev_startup_scripts/run_Dragon64_CPython2.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -# https://github.com/jedie/PyDragon32/tree/master/misc#readme - -( - set -x - #~ python2 -3 ../DragonPy_CLI.py --verbosity=5 --machine=Dragon64 run - python2 -3 ../DragonPy_CLI.py --verbosity=30 --machine=Dragon64 run -) -echo -read -n1 -p "Start bash? [y,n]" doit -echo -case $doit in - y|Y) - bash -i - exit 0 - ;; - n|N) - echo "bye bye" - ;; - *) - echo "input, don't know, bye." - ;; -esac \ No newline at end of file diff --git a/dev_startup_scripts/run_Dragon64_CPython2_loop.cmd b/dev_startup_scripts/run_Dragon64_CPython2_loop.cmd deleted file mode 100755 index d8bc6cae..00000000 --- a/dev_startup_scripts/run_Dragon64_CPython2_loop.cmd +++ /dev/null @@ -1,21 +0,0 @@ -@echo off - -title "%~nx0" - -set python=C:\Python27\python.exe -REM ~ set python=D:\pypy-2.3.1-win32\pypy.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd.. - -:loop - cls - echo on - %python% -3 DragonPy_CLI.py --machine=Dragon64 run - @echo off - pause -goto:loop \ No newline at end of file diff --git a/dev_startup_scripts/run_Dragon64_CPython3.sh b/dev_startup_scripts/run_Dragon64_CPython3.sh deleted file mode 100755 index 55faf795..00000000 --- a/dev_startup_scripts/run_Dragon64_CPython3.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -# https://github.com/jedie/PyDragon32/tree/master/misc#readme - -( - set -x - python3 ../DragonPy_CLI.py --verbosity=30 --machine=Dragon64 run -) -echo -read -n1 -p "Start bash? [y,n]" doit -echo -case $doit in - y|Y) - bash -i - exit 0 - ;; - n|N) - echo "bye bye" - ;; - *) - echo "input, don't know, bye." - ;; -esac \ No newline at end of file diff --git a/dev_startup_scripts/run_Dragon64_CPython3_loop.cmd b/dev_startup_scripts/run_Dragon64_CPython3_loop.cmd deleted file mode 100755 index dce18e69..00000000 --- a/dev_startup_scripts/run_Dragon64_CPython3_loop.cmd +++ /dev/null @@ -1,20 +0,0 @@ -@echo off - -title "%~nx0" - -set python=C:\Python34\python.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd.. - -:loop - cls - echo on - %python% DragonPy_CLI.py --machine=Dragon64 run - @echo off - pause -goto:loop \ No newline at end of file diff --git a/dev_startup_scripts/run_Dragon64_PyPy2.sh b/dev_startup_scripts/run_Dragon64_PyPy2.sh deleted file mode 100755 index 4c29d8e7..00000000 --- a/dev_startup_scripts/run_Dragon64_PyPy2.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -# https://github.com/jedie/PyDragon32/tree/master/misc#readme - -( - set -x - ~/pypy2/bin/pypy ../DragonPy_CLI.py --verbosity=30 --machine=Dragon64 run -) -echo -read -n1 -p "Start bash? [y,n]" doit -echo -case $doit in - y|Y) - bash -i - exit 0 - ;; - n|N) - echo "bye bye" - ;; - *) - echo "input, don't know, bye." - ;; -esac \ No newline at end of file diff --git a/dev_startup_scripts/run_Dragon64_loop.cmd b/dev_startup_scripts/run_Dragon64_loop.cmd deleted file mode 100755 index 3e78b904..00000000 --- a/dev_startup_scripts/run_Dragon64_loop.cmd +++ /dev/null @@ -1,21 +0,0 @@ -@echo off - -title "%~0" - -set python=C:\Python27\python.exe -REM ~ set python=D:\pypy-2.3.1-win32\pypy.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd.. - -:loop - cls - echo on - %python% DragonPy_CLI.py --machine=Dragon64 run - @echo off - pause -goto:loop \ No newline at end of file diff --git a/dev_startup_scripts/run_all_tests_CPython2_loop.cmd b/dev_startup_scripts/run_all_tests_CPython2_loop.cmd deleted file mode 100755 index 639c429f..00000000 --- a/dev_startup_scripts/run_all_tests_CPython2_loop.cmd +++ /dev/null @@ -1,22 +0,0 @@ -@echo off - -title "%~nx0" - -set python=C:\Python27\python.exe -REM ~ set python=D:\pypy-2.3.1-win32\pypy.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd .. - -:loop - echo on - cls - REM ~ %python% setup.py test - %python% -m unittest discover - @echo off - pause -goto:loop \ No newline at end of file diff --git a/dev_startup_scripts/run_all_tests_CPython3_loop.cmd b/dev_startup_scripts/run_all_tests_CPython3_loop.cmd deleted file mode 100755 index 38cb1d44..00000000 --- a/dev_startup_scripts/run_all_tests_CPython3_loop.cmd +++ /dev/null @@ -1,21 +0,0 @@ -@echo off - -title "%~nx0" - -set python=C:\Python34\python.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd .. - -:loop - echo on - cls - REM ~ %python% setup.py test - %python% -m unittest discover - @echo off - pause -goto:loop \ No newline at end of file diff --git a/dev_startup_scripts/run_all_tests_PyPy2_loop.cmd b/dev_startup_scripts/run_all_tests_PyPy2_loop.cmd deleted file mode 100755 index 12c39b28..00000000 --- a/dev_startup_scripts/run_all_tests_PyPy2_loop.cmd +++ /dev/null @@ -1,21 +0,0 @@ -@echo off - -title "%~0" - -set python=C:\pypy-2.3.1-win32\pypy.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd .. - -:loop - echo on - cls - REM ~ %python% setup.py test - %python% -m unittest discover - @echo off - pause -goto:loop \ No newline at end of file diff --git a/dev_startup_scripts/run_all_tests_PyPy3_loop.cmd b/dev_startup_scripts/run_all_tests_PyPy3_loop.cmd deleted file mode 100755 index 7455a88f..00000000 --- a/dev_startup_scripts/run_all_tests_PyPy3_loop.cmd +++ /dev/null @@ -1,21 +0,0 @@ -@echo off - -title "%~0" - -set python=C:\pypy3-2.3.1-win32\pypy.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd .. - -:loop - echo on - cls - REM ~ %python% setup.py test - %python% -m unittest discover - @echo off - pause -goto:loop \ No newline at end of file diff --git a/dev_startup_scripts/run_benchmark_CPython2_loop.cmd b/dev_startup_scripts/run_benchmark_CPython2_loop.cmd deleted file mode 100755 index 44aacf89..00000000 --- a/dev_startup_scripts/run_benchmark_CPython2_loop.cmd +++ /dev/null @@ -1,19 +0,0 @@ -@echo off - -title "%~0" - -set python=C:\Python27\python.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd.. - -:loop - echo on - %python% -OO DragonPy_CLI.py benchmark --loops 10 - @echo off - pause -goto:loop \ No newline at end of file diff --git a/dev_startup_scripts/run_benchmark_CPython3_loop.cmd b/dev_startup_scripts/run_benchmark_CPython3_loop.cmd deleted file mode 100755 index aae7a14b..00000000 --- a/dev_startup_scripts/run_benchmark_CPython3_loop.cmd +++ /dev/null @@ -1,19 +0,0 @@ -@echo off - -title "%~0" - -set python=C:\Python34\python.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd.. - -:loop - echo on - %python% -OO DragonPy_CLI.py benchmark --loops 10 - @echo off - pause -goto:loop \ No newline at end of file diff --git a/dev_startup_scripts/run_benchmark_PyPy2_loop.cmd b/dev_startup_scripts/run_benchmark_PyPy2_loop.cmd deleted file mode 100755 index 6df34d00..00000000 --- a/dev_startup_scripts/run_benchmark_PyPy2_loop.cmd +++ /dev/null @@ -1,20 +0,0 @@ -@echo off - -title "%~0" - -REM ~ set python=C:\pypy-2.3.1-win32\pypy.exe -set python=C:\pypy-2.4.0-win32\pypy.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd.. - -:loop - echo on - %python% -OO DragonPy_CLI.py benchmark --loops 100 - @echo off - pause -goto:loop \ No newline at end of file diff --git a/dev_startup_scripts/run_benchmark_PyPy3_loop.cmd b/dev_startup_scripts/run_benchmark_PyPy3_loop.cmd deleted file mode 100755 index a80b271f..00000000 --- a/dev_startup_scripts/run_benchmark_PyPy3_loop.cmd +++ /dev/null @@ -1,19 +0,0 @@ -@echo off - -title "%~0" - -set python=C:\pypy3-2.3.1-win32\pypy.exe -if NOT exist %python% ( - echo Error: '%python%' doesn't exists?!? - pause - exit 1 -) - -cd.. - -:loop - echo on - %python% -OO DragonPy_CLI.py benchmark --loops 100 - @echo off - pause -goto:loop \ No newline at end of file From f20787721c5edf93a130b2e12dcc12a7f74f90b6 Mon Sep 17 00:00:00 2001 From: JensDiemer Date: Fri, 21 Aug 2015 22:42:22 +0200 Subject: [PATCH 4/5] Better starter solution, squashed commit of the following: commit d74f090369c0accfe85330adef9decf65b596bf1 Author: JensDiemer Date: Fri Aug 21 22:40:46 2015 +0200 update starter and add unittests for it. use click.CliRunner().invoke() for normal cli test commit 6f2c66e5ec1dc156f675671449dd255ea0c6bf67 Author: JensDiemer Date: Fri Aug 21 20:26:02 2015 +0200 WIP: sys.executable, "-m", module_name commit 3c21ffb2ddc48a973e8e715403dad5e5c86ee49e Author: JensDiemer Date: Fri Aug 21 17:59:40 2015 +0200 WIP commit 176c4376ec748ebccaedf2bee239c60af6ec7e90 Merge: 3d1cc6d 8eac2b6 Author: JensDiemer Date: Fri Aug 21 17:26:05 2015 +0200 Merge remote-tracking branch 'origin/master' into WIP commit 3d1cc6d65c6a84f91da3a4190aab9645672e808b Author: JensDiemer Date: Fri Aug 21 17:25:18 2015 +0200 merge commit d6a3e7a1a72bb96f48f45b897a20decab4aecde7 Author: Jens Diemer Date: Thu Aug 20 22:21:41 2015 +0200 WIP --- README.creole | 5 +- dragonpy/Dragon32/MC6847.py | 2 +- dragonpy/Dragon32/config.py | 2 +- dragonpy/Dragon32/dragon_charmap.py | 2 +- dragonpy/Dragon32/keyboard_map.py | 2 +- dragonpy/Dragon64/config.py | 2 +- dragonpy/__init__.py | 8 +- dragonpy/components/memory.py | 4 +- dragonpy/components/periphery.py | 2 +- dragonpy/core/cli.py | 1 + dragonpy/core/configs.py | 2 +- dragonpy/core/gui.py | 62 ++++--- dragonpy/core/gui_starter.py | 80 ++++----- dragonpy/tests/test_BASIC_Dragon32.py | 25 --- dragonpy/tests/test_BASIC_simple09.py | 30 ---- dragonpy/tests/test_base.py | 2 +- dragonpy/tests/test_cli.py | 220 ++++++++++++++--------- dragonpy/tests/test_rom_download.py | 26 --- dragonpy/tests/test_sbc09.py | 33 +--- dragonpy/utils/BASIC09_floating_point.py | 2 +- dragonpy/utils/simple_debugger.py | 2 +- dragonpy/utils/starter.py | 93 ++++++++++ dragonpy/vectrex/MOS6522.py | 2 +- setup.py | 30 ++-- 24 files changed, 347 insertions(+), 292 deletions(-) create mode 100644 dragonpy/utils/starter.py diff --git a/README.creole b/README.creole index 6da16c58..dfe87fde 100644 --- a/README.creole +++ b/README.creole @@ -432,7 +432,10 @@ generic syntax highlighter == History -* [[https://github.com/jedie/DragonPy/compare/v0.5.0...v0.5.1|19.08.2015 - v0.5.1]]: (not released, yet) +* [[https://github.com/jedie/DragonPy/compare/v0.5.1...v0.5.2|20.08.2015 - v0.5.2]]: (not released, yet) +** Add run 'MC6809 benchmark' button to 'starter GUI' +** change the GUI a little bit +* [[https://github.com/jedie/DragonPy/compare/v0.5.0...v0.5.1|19.08.2015 - v0.5.1]]: ** Add a "starter GUI" ** Add work-a-round for tkinter usage with virtualenv under windows, see: [[https://github.com/pypa/virtualenv/issues/93|virtualenv issues #93]] ** bugfix e.g.: keyboard input in "sbc09" emulation diff --git a/dragonpy/Dragon32/MC6847.py b/dragonpy/Dragon32/MC6847.py index 56888321..2c26eff9 100644 --- a/dragonpy/Dragon32/MC6847.py +++ b/dragonpy/Dragon32/MC6847.py @@ -10,7 +10,7 @@ :license: GNU GPL v3 or above, see LICENSE for more details. """ from __future__ import absolute_import, division, print_function -from dragonlib.utils import six +import six xrange = six.moves.xrange diff --git a/dragonpy/Dragon32/config.py b/dragonpy/Dragon32/config.py index 3e42fef0..a1392d6e 100644 --- a/dragonpy/Dragon32/config.py +++ b/dragonpy/Dragon32/config.py @@ -13,7 +13,7 @@ import logging -from dragonlib.utils import six +import six xrange = six.moves.xrange diff --git a/dragonpy/Dragon32/dragon_charmap.py b/dragonpy/Dragon32/dragon_charmap.py index 8bb56a99..11a85768 100644 --- a/dragonpy/Dragon32/dragon_charmap.py +++ b/dragonpy/Dragon32/dragon_charmap.py @@ -13,7 +13,7 @@ """ from __future__ import absolute_import, division, print_function, unicode_literals -from dragonlib.utils import six +import six xrange = six.moves.xrange import unicodedata diff --git a/dragonpy/Dragon32/keyboard_map.py b/dragonpy/Dragon32/keyboard_map.py index 544edd92..7546724f 100755 --- a/dragonpy/Dragon32/keyboard_map.py +++ b/dragonpy/Dragon32/keyboard_map.py @@ -40,7 +40,7 @@ """ from __future__ import absolute_import, division, print_function -from dragonlib.utils import six +import six xrange = six.moves.xrange import string diff --git a/dragonpy/Dragon64/config.py b/dragonpy/Dragon64/config.py index 82af8add..1c19bb8f 100644 --- a/dragonpy/Dragon64/config.py +++ b/dragonpy/Dragon64/config.py @@ -13,7 +13,7 @@ import logging -from dragonlib.utils import six +import six xrange = six.moves.xrange diff --git a/dragonpy/__init__.py b/dragonpy/__init__.py index f780953f..0b4a2587 100644 --- a/dragonpy/__init__.py +++ b/dragonpy/__init__.py @@ -2,7 +2,13 @@ import sys -__version__ = "0.5.1" +__version__ = "0.5.2" + + +# Used in setup.py and starter GUI to find the cli-executeable: +DISTRIBUTION_NAME="DragonPyEmulator" +DIST_GROUP = "console_scripts" +ENTRY_POINT = "DragonPy" def fix_virtualenv_tkinter(): diff --git a/dragonpy/components/memory.py b/dragonpy/components/memory.py index 4443bc46..ad12a268 100644 --- a/dragonpy/components/memory.py +++ b/dragonpy/components/memory.py @@ -20,7 +20,7 @@ """ from __future__ import absolute_import, division, print_function -from dragonlib.utils import six +import six xrange = six.moves.xrange import array @@ -28,7 +28,7 @@ import sys import logging -from dragonlib.utils import six +import six from dragonlib.utils.logging_utils import log_hexlist diff --git a/dragonpy/components/periphery.py b/dragonpy/components/periphery.py index 15a8cde9..68930a56 100644 --- a/dragonpy/components/periphery.py +++ b/dragonpy/components/periphery.py @@ -11,7 +11,7 @@ """ from __future__ import absolute_import, division, print_function -from dragonlib.utils import six +import six xrange = six.moves.xrange import sys diff --git a/dragonpy/core/cli.py b/dragonpy/core/cli.py index cb55d7e7..acc62e4e 100755 --- a/dragonpy/core/cli.py +++ b/dragonpy/core/cli.py @@ -206,6 +206,7 @@ def confirm(): click.prompt("Please press [ENTER] to exit", default="", show_default=False) atexit.register(confirm) + click.secho("\nrun DragonPy starter GUI...\n", bold=True) gui = StarterGUI(machine_dict) gui.mainloop() else: diff --git a/dragonpy/core/configs.py b/dragonpy/core/configs.py index 9fa40cd3..1a7ce38f 100644 --- a/dragonpy/core/configs.py +++ b/dragonpy/core/configs.py @@ -10,7 +10,7 @@ """ from __future__ import absolute_import, division, print_function -from dragonlib.utils import six +import six xrange = six.moves.xrange import inspect diff --git a/dragonpy/core/gui.py b/dragonpy/core/gui.py index 6b29294c..a2827e4d 100755 --- a/dragonpy/core/gui.py +++ b/dragonpy/core/gui.py @@ -12,21 +12,18 @@ from __future__ import absolute_import, division, print_function -from dragonlib.utils import six -from dragonpy.Dragon32.keyboard_map import inkey_from_tk_event, add_to_input_queue -from dragonlib.utils.auto_shift import invert_shift - -xrange = six.moves.xrange - import sys import time import logging import string +import six + +xrange = six.moves.xrange try: # Python 3 import queue - import tkinter + import tkinter as tk from tkinter import filedialog from tkinter import messagebox from tkinter import scrolledtext @@ -34,13 +31,19 @@ except ImportError: # Python 2 import Queue as queue - import Tkinter as tkinter + import Tkinter as tk import tkFileDialog as filedialog import tkMessageBox as messagebox import ScrolledText as scrolledtext import tkFont as TkFont from basic_editor.editor import EditorWindow + +from dragonpy.Dragon32.keyboard_map import inkey_from_tk_event, add_to_input_queue +from dragonlib.utils.auto_shift import invert_shift +import dragonpy +from dragonpy.Dragon32.keyboard_map import inkey_from_tk_event, add_to_input_queue +from dragonpy.core.gui_starter import MultiStatusBar from dragonpy.Dragon32.MC6847 import MC6847_TextModeCanvas from dragonpy.Dragon32.gui_config import RuntimeCfg, BaseTkinterGUIConfig from dragonpy.utils.humanize import locale_format_number, get_python_info @@ -67,7 +70,7 @@ def __init__(self, cfg, user_input_queue): self.init_statistics() # Called also after reset - self.root = tkinter.Tk(className="DragonPy") + self.root = tk.Tk(className="DragonPy") # self.root.config(font="Helvetica 16 bold italic") self.root.geometry("+%d+%d" % ( @@ -83,28 +86,29 @@ def __init__(self, cfg, user_input_queue): size=11, weight='normal' ) - self.status = tkinter.StringVar(value="startup %s...\n" % self.cfg.MACHINE_NAME) - self.status_widget = tkinter.Label( + self.status = tk.StringVar(value="startup %s...\n" % self.cfg.MACHINE_NAME) + self.status_widget = tk.Label( self.root, textvariable=self.status, text="Info:", borderwidth=1, font=menu_tk_font ) self.status_widget.grid(row=1, column=0) - self.python_info_label = tkinter.Label( - self.root, borderwidth=1, text=get_python_info(), + self.status_bar = MultiStatusBar(self.root, row=2, column=0, + sticky=tk.NSEW, ) - self.python_info_label.grid(row=2, column=0) + self.status_bar.set_label("python_version", get_python_info()) + self.status_bar.set_label("dragonpy_version", "DragonPy v%s" % dragonpy.__version__) - self.menubar = tkinter.Menu(self.root) + self.menubar = tk.Menu(self.root) - filemenu = tkinter.Menu(self.menubar, tearoff=0) + filemenu = tk.Menu(self.menubar, tearoff=0) filemenu.add_command(label="Exit", command=self.exit) self.menubar.add_cascade(label="File", menu=filemenu) # 6809 menu - self.cpu_menu = tkinter.Menu(self.menubar, tearoff=0) + self.cpu_menu = tk.Menu(self.menubar, tearoff=0) self.cpu_menu.add_command(label="pause", command=self.command_cpu_pause) - self.cpu_menu.add_command(label="resume", command=self.command_cpu_pause, state=tkinter.DISABLED) + self.cpu_menu.add_command(label="resume", command=self.command_cpu_pause, state=tk.DISABLED) self.cpu_menu.add_separator() self.cpu_menu.add_command(label="soft reset", command=self.command_cpu_soft_reset) self.cpu_menu.add_command(label="hard reset", command=self.command_cpu_hard_reset) @@ -116,7 +120,7 @@ def __init__(self, cfg, user_input_queue): # self.root.after(200, self.command_config) # help menu - helpmenu = tkinter.Menu(self.menubar, tearoff=0) + helpmenu = tk.Menu(self.menubar, tearoff=0) helpmenu.add_command(label="help", command=self.menu_event_help) helpmenu.add_command(label="about", command=self.menu_event_about) self.menubar.add_cascade(label="help", menu=helpmenu) @@ -174,13 +178,13 @@ def command_cpu_pause(self): self.root.after_cancel(self.cpu_after_id) self.cpu_after_id = None self.status_paused() - self.cpu_menu.entryconfig(index=0, state=tkinter.DISABLED) - self.cpu_menu.entryconfig(index=1, state=tkinter.NORMAL) + self.cpu_menu.entryconfig(index=0, state=tk.DISABLED) + self.cpu_menu.entryconfig(index=1, state=tk.NORMAL) else: # restart self.cpu_interval(interval=1) - self.cpu_menu.entryconfig(index=0, state=tkinter.NORMAL) - self.cpu_menu.entryconfig(index=1, state=tkinter.DISABLED) + self.cpu_menu.entryconfig(index=0, state=tk.NORMAL) + self.cpu_menu.entryconfig(index=1, state=tk.DISABLED) self.init_statistics() # Reset statistics def command_cpu_soft_reset(self): @@ -351,7 +355,7 @@ def open_basic_editor(self): self._editor_window.root.protocol("WM_DELETE_WINDOW", self.close_basic_editor) # insert menu to editor window - editmenu = tkinter.Menu(self._editor_window.menubar, tearoff=0) + editmenu = tk.Menu(self._editor_window.menubar, tearoff=0) editmenu.add_command(label="load from DragonPy", command=self.command_load_from_DragonPy) editmenu.add_command(label="inject into DragonPy", command=self.command_inject_into_DragonPy) editmenu.add_command(label="inject + RUN into DragonPy", command=self.command_inject_and_run_into_DragonPy) @@ -414,7 +418,7 @@ def __init__(self, *args, **kwargs): highlightthickness=0, font=('courier', 11), ) - self.text.grid(row=0, column=0, sticky=tkinter.NSEW) + self.text.grid(row=0, column=0, sticky=tk.NSEW) # self._editor_window = None # self.menubar.insert_command(index=3, label="BASIC editor", command=self.open_basic_editor) @@ -450,15 +454,15 @@ def display_callback(self, char): log.debug("Add to text: %s", repr(char)) if char == "\x08": # Delete last input char - self.text.delete(tkinter.INSERT + "-1c") + self.text.delete(tk.INSERT + "-1c") else: # insert the new character: - self.text.insert(tkinter.END, char) + self.text.insert(tk.END, char) # scroll down if needed: - self.text.see(tkinter.END) + self.text.see(tk.END) # Set cursor to the END position: - self.text.mark_set(tkinter.INSERT, tkinter.END) + self.text.mark_set(tk.INSERT, tk.END) diff --git a/dragonpy/core/gui_starter.py b/dragonpy/core/gui_starter.py index 963df1b2..4a403280 100644 --- a/dragonpy/core/gui_starter.py +++ b/dragonpy/core/gui_starter.py @@ -11,16 +11,13 @@ """ from __future__ import absolute_import, division, print_function + import subprocess import sys import logging import click - import os - -import dragonpy -from dragonpy.utils.humanize import get_python_info -from dragonpy.core import configs +from dragonpy.utils.starter import run_dragonpy, run_mc6809 if sys.version_info[0] == 2: # Python 2 @@ -37,8 +34,14 @@ # from tkinter import scrolledtext # from tkinter import font as TkFont +import dragonpy +from dragonpy.utils.humanize import get_python_info +from dragonpy.core import configs + + log = logging.getLogger(__name__) + VERBOSITY_DICT = { 1: "hardcode DEBUG ;)", 10: "DEBUG", @@ -70,8 +73,6 @@ assert VERBOSITY_DICT2[VERBOSITY_DEFAULT] == VERBOSITY_DEFAULT_VALUE -# sys.exit() - class SettingsFrame(tk.LabelFrame): def __init__(self, master, **kwargs): tk.LabelFrame.__init__(self, master, text="Settings") @@ -99,7 +100,7 @@ def __init__(self, master, **kwargs): self.var_machine = tk.StringVar() self.var_machine.set(configs.DRAGON64) for row, machine_name in enumerate(sorted(self.machine_dict)): - print(row, machine_name) + # print(row, machine_name) b = tk.Radiobutton(self, text=machine_name, variable=self.var_machine, value=machine_name) b.grid(row=row, column=1, sticky=tk.W) @@ -139,18 +140,28 @@ def __init__(self, master, **kwargs): class MultiStatusBar(tk.Frame): """ - code from idlelib.MultiStatusBar.MultiStatusBar + base on code from idlelib.MultiStatusBar.MultiStatusBar """ def __init__(self, master, **kwargs): tk.Frame.__init__(self, master) self.grid(**kwargs) + self.columnconfigure(0, weight=1) + self.rowconfigure(0, weight=1) self.labels = {} - def set_label(self, name, text='', side=tk.LEFT): + def set_label(self, name, text='', **kwargs): + defaults = { + "ipadx": 2, # add internal padding in x direction + "ipady": 2, # add internal padding in y direction + "padx": 1, # add padding in x direction + "pady": 0, # add padding in y direction + "sticky": tk.NSEW, # stick to the cell boundary + } + defaults.update(kwargs) if name not in self.labels: label = tk.Label(self, bd=1, relief=tk.SUNKEN, anchor=tk.W) - label.pack(side=side) + label.grid(column=len(self.labels), row=0, **defaults) self.labels[name] = label else: label = self.labels[name] @@ -161,12 +172,14 @@ class StarterGUI(tk.Tk): def __init__(self, machine_dict): tk.Tk.__init__(self) + print("\n".join(sys.path)) + self.machine_dict = machine_dict self.geometry("+%d+%d" % ( self.winfo_screenwidth() * 0.1, self.winfo_screenheight() * 0.1 )) - self.title("DragonPy v%s GUI starter" % dragonpy.__version__) + self.title("DragonPy starter GUI") self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) @@ -194,22 +207,17 @@ def add_widgets(self): ) def set_status_bar(self): - self.status_bar.set_label("python_info", get_python_info()) + defaults = { + "padx": 5, # add padding in x direction + "pady": 0, # add padding in y direction + } + self.status_bar.set_label("python_version", get_python_info(), **defaults) + self.status_bar.set_label("dragonpy_version", "DragonPy v%s" % dragonpy.__version__, **defaults) def _print_run_info(self, txt): click.echo("\n") click.secho(txt, bg='blue', fg='white', bold=True, underline=True) - def _print_args_info(self, *args): - click.echo("\tadd: %s" % click.style(" ".join(args), bold=True)) - - def _run(self, *args): - """ - Run current executable via subprocess and given args - """ - print("execute: %s" % " ".join(args)) - subprocess.Popen(args) - def _run_dragonpy_cli(self, *args): """ Run DragonPy cli with given args. @@ -219,20 +227,15 @@ def _run_dragonpy_cli(self, *args): verbosity_no = VERBOSITY_DICT2[verbosity] log.debug("Verbosity: %i (%s)" % (verbosity_no, verbosity)) - verbosity_args = ["--verbosity", "%s" % verbosity_no] - self._print_args_info(*verbosity_args) - - cmd_args = [ - "DragonPy", - + args = ( + "--verbosity", "%s" % verbosity_no # "--log_list", # "--log", # "dragonpy.components.cpu6809,40", # "dragonpy.Dragon32.MC6821_PIA,50", - ] - cmd_args += verbosity_args - cmd_args += args - self._run(*cmd_args) + ) + args + click.echo("\n") + run_dragonpy(*args, verbose=True) def _run_command(self, command): """ @@ -241,10 +244,7 @@ def _run_command(self, command): "--verbosity" will also be set, later. """ machine_name = self.frame_run_buttons.var_machine.get() - args = ["--machine", machine_name] - self._print_args_info(*args) - args.append(command) - self._run_dragonpy_cli(*args) + self._run_dragonpy_cli("--machine", machine_name, command) def run_machine(self): self._print_run_info("Run machine emulation") @@ -256,10 +256,8 @@ def run_basic_editor(self): def run_6809_benchmark(self): self._print_run_info("Run MC6809 benchmark") - cmd_args = [ - "MC6809", "benchmark" - ] - self._run(*cmd_args) + click.echo("\n") + run_mc6809("benchmark", verbose=True) diff --git a/dragonpy/tests/test_BASIC_Dragon32.py b/dragonpy/tests/test_BASIC_Dragon32.py index 993a390c..d3097c6e 100644 --- a/dragonpy/tests/test_BASIC_Dragon32.py +++ b/dragonpy/tests/test_BASIC_Dragon32.py @@ -18,7 +18,6 @@ import unittest import logging -from dragonlib.utils.unittest_utils import TextTestRunner2 from dragonlib.utils.logging_utils import setup_logging from dragonpy.tests.test_base import Test6809_Dragon32_Base @@ -102,27 +101,3 @@ def test_tokens_in_string(self): self.assertEqual(output, ['10 A=1', '20 B=2']) - -if __name__ == '__main__': - setup_logging( - # level=1 # hardcore debug ;) - # level=10 # DEBUG - # level=20 # INFO - # level=30 # WARNING - # level=40 # ERROR - level=50 # CRITICAL/FATAL - # level=99 # nearly off - ) - - unittest.main( - argv=( - sys.argv[0], -# "Test_Dragon32_BASIC.test_code_load02", -# "Test_Dragon32_BASIC.test_code_save01", -# "Test_Dragon32_BASIC.test_tokens_in_string", - ), - testRunner=TextTestRunner2, -# verbosity=1, - verbosity=2, - failfast=True, - ) diff --git a/dragonpy/tests/test_BASIC_simple09.py b/dragonpy/tests/test_BASIC_simple09.py index bf3b849c..f25aa829 100644 --- a/dragonpy/tests/test_BASIC_simple09.py +++ b/dragonpy/tests/test_BASIC_simple09.py @@ -18,7 +18,6 @@ import sys import unittest -from dragonlib.utils.unittest_utils import TextTestRunner2 from dragonpy.tests.test_base import Test6809_BASIC_simple6809_Base from dragonpy.utils.BASIC09_floating_point import BASIC09FloatingPoint @@ -653,32 +652,3 @@ def test_division(self): # FIXME! ''' -if __name__ == '__main__': - from dragonlib.utils.logging_utils import setup_logging - - setup_logging(log, -# level=1 # hardcore debug ;) -# level=10 # DEBUG -# level=20 # INFO -# level=30 # WARNING -# level=40 # ERROR - level=50 # CRITICAL/FATAL - ) - - unittest.main( - argv=( - sys.argv[0], -# "Test_simple6809_BASIC.test_print01", - -# "Test_simple6809_BASIC_Float1", -# "Test_simple6809_BASIC_NumericFunctions", -# "Test_simple6809_BASIC_Float2", -# "Test_simple6809_BASIC_Float2.test_divide_FPA0_by_10", -# "Test_simple6809_BASIC_Float2.test_FPA0_to_D", -# "Test_simple6809_BASIC_Float2.test_division", - ), - testRunner=TextTestRunner2, -# verbosity=1, - verbosity=2, - failfast=True, - ) diff --git a/dragonpy/tests/test_base.py b/dragonpy/tests/test_base.py index 0a5a7ede..04192ac3 100644 --- a/dragonpy/tests/test_base.py +++ b/dragonpy/tests/test_base.py @@ -10,7 +10,7 @@ from __future__ import absolute_import, division, print_function -from dragonlib.utils import six +import six xrange = six.moves.xrange import hashlib diff --git a/dragonpy/tests/test_cli.py b/dragonpy/tests/test_cli.py index 21a615b1..cd6c5fb1 100644 --- a/dragonpy/tests/test_cli.py +++ b/dragonpy/tests/test_cli.py @@ -9,41 +9,61 @@ """ from __future__ import absolute_import, division, print_function -from dragonlib.utils.unittest_utils import TextTestRunner2 -import os + import subprocess -import sys import unittest +from click.testing import CliRunner -CLI = "DragonPy" # entry_points in setup.py ! +import MC6809 +import dragonpy +from dragonpy.core.cli import cli +from dragonpy.utils.starter import run_dragonpy, run_mc6809 -class CLITestCase(unittest.TestCase): - """ - TODO: Do more than this simple tests - """ - def _get(self, *args): - try: - VIRTUAL_ENV = os.environ["VIRTUAL_ENV"] - except KeyError as err: - # e.g.: started by PyCharm - cli = os.path.join(os.path.dirname(sys.executable), CLI) - else: - cli = os.path.join(VIRTUAL_ENV, "bin", CLI) +class CliTestCase(unittest.TestCase): + def assert_contains_members(self, members, container): + for member in members: + msg = "%r not found in:\n%s" % (member, container) + # self.assertIn(member, container, msg) # Bad error message :( + if not member in container: + self.fail(msg) + + def assert_not_contains_members(self, members, container): + for member in members: + if member in container: + self.fail("%r found in:\n%s" % (member, container)) + + def assert_is_help(self, output): + self.assert_contains_members([ + "Usage: ", " [OPTIONS] COMMAND [ARGS]...", # Don't check "filename": It's cli or cli.py in unittests! + + "DragonPy is a Open source (GPL v3 or later) emulator for the 30 years old", + "homecomputer Dragon 32 and Tandy TRS-80 Color Computer (CoCo)...", - self.assertTrue(os.path.isfile(cli), "CLI file %r not found!" % cli) + "Homepage: https://github.com/jedie/DragonPy", + + "--machine [CoCo2b|Dragon32|Dragon64|Multicomp6809|Vectrex|sbc09]", + "Commands:", + "download_roms Download/Test only ROM files", + "editor Run only the BASIC editor", + "log_list List all exiting loggers and exit.", + "run Run a machine emulation", + ], output) - cmd_args = [cli] + list(args) - # print("\nStartup CLI with: %r" % " ".join(cmd_args)) - p = subprocess.Popen( - cmd_args, +class TestStarter(CliTestCase): + """ + Test the "starter functions" that invoke DragonPy / MC6809 via subprocess. + """ + def _run(self, func, *args, verbose=False): + p = func(*args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, + verbose=verbose ) retcode = p.wait() @@ -65,101 +85,131 @@ def _get(self, *args): return cli_out, cli_err - def assertInMultiline(self, members, container): - for member in members: - msg = "%r not found in:\n%s" % (member, container) - # self.assertIn(member, container, msg) # Bad error message :( - if not member in container: - self.fail(msg) + def _run_dragonpy(self, *args, **kwargs): + return self._run(run_dragonpy, *args, **kwargs) - def assertNotInMultiline(self, members, container): - for member in members: - if member in container: - self.fail("%r found in:\n%s" % (member, container)) + def _run_MC6809(self, *args, **kwargs): + return self._run(run_mc6809, *args, **kwargs) + + def test_run_dragonpy_version(self): + cli_out, cli_err = self._run_dragonpy( + "--version", + # verbose=True + ) + self.assertIn(dragonpy.__version__, cli_out) + self.assertEqual(cli_err, "") + + def test_run_dragonpy_help(self): + cli_out, cli_err = self._run_dragonpy( + "--help", + # verbose=True + ) + self.assert_is_help(cli_out) + self.assertEqual(cli_err, "") + + def test_run_MC6809_version(self): + cli_out, cli_err = self._run_MC6809( + "--version", + # verbose=True + ) + self.assertIn(MC6809.__version__, cli_out) + self.assertEqual(cli_err, "") + + def test_run_MC6809_help(self): + cli_out, cli_err = self._run_MC6809( + "--help", + # verbose=True + ) + self.assert_contains_members([ + "Usage: ", " [OPTIONS] COMMAND [ARGS]...", # Don't check "filename": It's cli or cli.py in unittests! + "Homepage: https://github.com/6809/MC6809", + "Run a 6809 Emulation benchmark", + ], cli_out) + self.assertEqual(cli_err, "") + + +class CLITestCase(CliTestCase): + """ + Test the click cli via click.CliRunner().invoke() + """ + def _invoke(self, *args): + runner = CliRunner() + result = runner.invoke(cli, args) + + if result.exit_code != 0: + msg = ( + "\nstart CLI with: '%s'\n" + "return code: %r\n" + " *** output: ***\n" + "%s\n" + " *** exception: ***\n" + "%s\n" + "****************\n" + ) % (" ".join(args), result.exit_code, result.output, result.exception) + self.assertEqual(result.exit_code, 0, msg=msg) + + return result def test_main_help(self): - cli_out, cli_err = self._get("--help") - # print(cli_out) + result = self._invoke("--help") + # print(result.output) # print(cli_err) - self.assertInMultiline([ - "Usage: DragonPy [OPTIONS] COMMAND [ARGS]...", - "--machine [CoCo2b|Dragon32|Dragon64|Multicomp6809|Vectrex|sbc09]", - "Commands:", - "download_roms Download/Test only ROM files", - "editor Run only the BASIC editor", - "log_list List all exiting loggers and exit.", - "run Run a machine emulation", - ], cli_out) + self.assert_is_help(result.output) errors = ["Error", "Traceback"] - self.assertNotInMultiline(errors, cli_out) - self.assertNotInMultiline(errors, cli_err) + self.assert_not_contains_members(errors, result.output) + + def test_version(self): + result = self._invoke("--version") + self.assertIn(dragonpy.__version__, result.output) def test_log_list(self): - cli_out, cli_err = self._get("log_list") - # print(cli_out) + result = self._invoke("log_list") + # print(result.output) # print(cli_err) - self.assertInMultiline([ + self.assert_contains_members([ "A list of all loggers:", "DragonPy.cpu6809", "dragonpy.Dragon32.MC6821_PIA", - ], cli_out) + ], result.output) errors = ["Error", "Traceback"] - self.assertNotInMultiline(errors, cli_out) - self.assertNotInMultiline(errors, cli_err) + self.assert_not_contains_members(errors, result.output) def test_run_help(self): - cli_out, cli_err = self._get("run", "--help") - # print(cli_out) + result = self._invoke("run", "--help") + # print(result.output) # print(cli_err) - self.assertInMultiline([ - "Usage: DragonPy run [OPTIONS]", - ], cli_out) + self.assert_contains_members([ + "Usage: cli run [OPTIONS]", + ], result.output) errors = ["Error", "Traceback"] - self.assertNotInMultiline(errors, cli_out) - self.assertNotInMultiline(errors, cli_err) + self.assert_not_contains_members(errors, result.output) def test_editor_help(self): - cli_out, cli_err = self._get("editor", "--help") - # print(cli_out) + result = self._invoke("editor", "--help") + # print(result.output) # print(cli_err) - self.assertInMultiline([ - "Usage: DragonPy editor [OPTIONS]", - ], cli_out) + self.assert_contains_members([ + "Usage: cli editor [OPTIONS]", + ], result.output) errors = ["Error", "Traceback"] - self.assertNotInMultiline(errors, cli_out) - self.assertNotInMultiline(errors, cli_err) + self.assert_not_contains_members(errors, result.output) def test_download_roms(self): - cli_out, cli_err = self._get("download_roms") - # print(cli_out) + result = self._invoke("download_roms") + # print(result.output) # print(cli_err) - self.assertInMultiline([ + self.assert_contains_members([ "ROM file: d64_ic17.rom", "Read ROM file", "ROM SHA1:", "ok", "file size is", - ], cli_out) + ], result.output) errors = ["Error", "Traceback"] - self.assertNotInMultiline(errors, cli_out) - self.assertNotInMultiline(errors, cli_err) - - - -if __name__ == '__main__': - unittest.main( - argv=( - sys.argv[0], - # "CLITestCase.test_download_roms", - ), - testRunner=TextTestRunner2, - # verbosity=1, - verbosity=2, - failfast=False, - # failfast=True, - ) + self.assert_not_contains_members(errors, result.output) + diff --git a/dragonpy/tests/test_rom_download.py b/dragonpy/tests/test_rom_download.py index 51b58777..7cfbb4a1 100644 --- a/dragonpy/tests/test_rom_download.py +++ b/dragonpy/tests/test_rom_download.py @@ -15,7 +15,6 @@ import unittest import sys -from dragonlib.utils.unittest_utils import TextTestRunner2 from dragonlib.utils.logging_utils import setup_logging from dragonpy.CoCo.CoCo2b_rom import CoCo2b_Basic13_ROM, \ @@ -59,28 +58,3 @@ def test_Simple6809Rom(self): self._test_rom(Simple6809Rom(address=None)) -if __name__ == '__main__': - setup_logging( - # level=1 # hardcore debug ;) - # level=10 # DEBUG - # level=20 # INFO - # level=30 # WARNING - # level=40 # ERROR - level=50 # CRITICAL/FATAL - # level=99 # nearly off - ) - - unittest.main( - argv=( - sys.argv[0], - # "ROMTest.test_Multicomp6809Rom", - # "ROMTest.test_Simple6809Rom", - # "ROMTest.test_CoCo2b_Basic13_ROM", - # "ROMTest.test_CoCo2b_ExtendedBasic11_ROM", - ), - testRunner=TextTestRunner2, - # verbosity=1, - verbosity=2, - failfast=False, - # failfast=True, - ) diff --git a/dragonpy/tests/test_sbc09.py b/dragonpy/tests/test_sbc09.py index 5ed17458..7218cfa4 100644 --- a/dragonpy/tests/test_sbc09.py +++ b/dragonpy/tests/test_sbc09.py @@ -18,8 +18,8 @@ """ from __future__ import absolute_import, division, print_function -from dragonlib.utils.unittest_utils import TextTestRunner2 -from dragonlib.utils import six + +import six xrange = six.moves.xrange import logging @@ -213,32 +213,3 @@ def test_disassemble(self): 'E416 CE0000 LDU #$0000\r\n' ]) - -if __name__ == '__main__': - from dragonlib.utils.logging_utils import setup_logging - - setup_logging(log, - level=1 # hardcore debug ;) -# level=10 # DEBUG -# level=20 # INFO -# level=30 # WARNING -# level=40 # ERROR -# level=50 # CRITICAL/FATAL - ) - - import doctest - print(doctest.testmod(verbose=0)) - - unittest.main( - argv=( - sys.argv[0], -# "Create_sbc09_trace", -# "Test_sbc09.test_S_records", -# "Test_sbc09.test_calculate_hex_negative", - ), - testRunner=TextTestRunner2, -# verbosity=1, - verbosity=2, -# failfast=True, - ) - print(" --- END --- ") diff --git a/dragonpy/utils/BASIC09_floating_point.py b/dragonpy/utils/BASIC09_floating_point.py index cc5a3e8b..837320fa 100644 --- a/dragonpy/utils/BASIC09_floating_point.py +++ b/dragonpy/utils/BASIC09_floating_point.py @@ -9,7 +9,7 @@ """ from __future__ import absolute_import, division, print_function -from dragonlib.utils import six +import six xrange = six.moves.xrange import math diff --git a/dragonpy/utils/simple_debugger.py b/dragonpy/utils/simple_debugger.py index 5072b68f..85b4f62b 100644 --- a/dragonpy/utils/simple_debugger.py +++ b/dragonpy/utils/simple_debugger.py @@ -14,7 +14,7 @@ from __future__ import absolute_import, division, print_function import click -from dragonlib.utils import six +import six xrange = six.moves.xrange import sys diff --git a/dragonpy/utils/starter.py b/dragonpy/utils/starter.py new file mode 100644 index 00000000..a79bf618 --- /dev/null +++ b/dragonpy/utils/starter.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# encoding:utf8 + +""" + DragonPy - Dragon 32 emulator in Python + ======================================= + + :created: 2015 by Jens Diemer - www.jensdiemer.de + :copyleft: 2015 by the DragonPy team, see AUTHORS for more details. + :license: GNU GPL v3 or above, see LICENSE for more details. +""" + +from __future__ import absolute_import, print_function +import os + +import sys +import subprocess + +import MC6809 +import click +import dragonpy + +from pkg_resources import get_distribution + + +def get_module_name(package): + """ + package must have these attributes: + e.g.: + package.DISTRIBUTION_NAME = "DragonPyEmulator" + package.DIST_GROUP = "console_scripts" + package.ENTRY_POINT = "DragonPy" + + :return: a string like: "dragonpy.core.cli" + """ + distribution = get_distribution(package.DISTRIBUTION_NAME) + entry_info = distribution.get_entry_info(package.DIST_GROUP, package.ENTRY_POINT) + if not entry_info: + raise RuntimeError( + "Can't find entry info for distribution: %r (group: %r, entry point: %r)" % ( + package.DISTRIBUTION_NAME, package.DIST_GROUP, package.ENTRY_POINT + ) + ) + return entry_info.module_name + + +def get_subprocess_args(package): + module_name = get_module_name(package) + subprocess_args = (sys.executable, "-m", module_name) + return subprocess_args + + +def _run(*args, **kwargs): + """ + Run current executable via subprocess and given args + """ + verbose = kwargs.pop("verbose", False) + if verbose: + click.secho(" ".join([repr(i) for i in args]), bg='blue', fg='white') + + executable = args[0] + if not os.path.isfile(executable): + raise RuntimeError("First argument %r is not a existing file!" % executable) + if not os.access(executable, os.X_OK): + raise RuntimeError("First argument %r exist, but is not executeable!" % executable) + + return subprocess.Popen(args, **kwargs) + + +def run_dragonpy(*args, **kwargs): + args = get_subprocess_args(dragonpy) + args + return _run(*args, **kwargs) + + +def run_mc6809(*args, **kwargs): + args = get_subprocess_args(MC6809) + args + return _run(*args, **kwargs) + + +if __name__ == '__main__': + def example(package): + print(package.__name__) + module_name = get_module_name(package) + print("\t* module name:", module_name) + subprocess_args = get_subprocess_args(package) + print("\t* subprocess args:", subprocess_args) + print() + + for package in (dragonpy, MC6809): + example(package) + + run_dragonpy("--version").wait() + run_mc6809("--version").wait() \ No newline at end of file diff --git a/dragonpy/vectrex/MOS6522.py b/dragonpy/vectrex/MOS6522.py index 6af17240..f2913d46 100755 --- a/dragonpy/vectrex/MOS6522.py +++ b/dragonpy/vectrex/MOS6522.py @@ -17,7 +17,7 @@ """ from __future__ import absolute_import, division, print_function -from dragonlib.utils import six +import six xrange = six.moves.xrange import logging diff --git a/setup.py b/setup.py index 1fde5aab..1337612f 100755 --- a/setup.py +++ b/setup.py @@ -18,8 +18,7 @@ import subprocess import shutil -from dragonpy import __version__ - +from dragonpy import __version__, DISTRIBUTION_NAME, DIST_GROUP, ENTRY_POINT PACKAGE_ROOT = os.path.dirname(os.path.abspath(__file__)) @@ -199,7 +198,11 @@ def rmtree(path): setup( - name="DragonPyEmulator", # Name conflict with https://github.com/jpanganiban/dragonpy :( + name=DISTRIBUTION_NAME, + # PyPi package is: "DragonPyEmulator" and not "DragonPy" + # because of name conflict with https://github.com/jpanganiban/dragonpy :( + # see:https://github.com/jpanganiban/dragonpy/issues/3 + version=__version__, py_modules=["DragonPy"], provides=["DragonPy"], @@ -207,16 +210,27 @@ def rmtree(path): "dragonlib", "MC6809", "pygments", + "click", + "six", + ], + tests_require=[ + "nose", # https://pypi.python.org/pypi/nose ], + # https://pythonhosted.org/setuptools/setuptools.html#automatic-script-creation + entry_points={ + # Here we use constants, because of usage in "starter GUI", too. + # DIST_GROUP = "console_scripts" + # ENTRY_POINT = "DragonPy" + DIST_GROUP: ["%s = dragonpy.core.cli:main" % ENTRY_POINT], + # e.g.: + # "console_scripts": ["DragonPy = dragonpy.core.cli:main"], + }, author="Jens Diemer", author_email="DragonPy@jensdiemer.de", description="Emulator for 6809 CPU based system like Dragon 32 / CoCo written in Python...", keywords="Emulator 6809 Dragon CoCo Vectrex tkinter pypy", long_description=long_description, url="https://github.com/jedie/DragonPy", - entry_points={ - "console_scripts": ["DragonPy = dragonpy.core.cli:main"], - }, license="GPL v3+", classifiers=[ # https://pypi.python.org/pypi?%3Aaction=list_classifiers @@ -243,8 +257,4 @@ def rmtree(path): packages=find_packages(), include_package_data=True, zip_safe=False, - test_suite="dragonpy.tests.get_tests", - tests_require=[ - "nose", # https://pypi.python.org/pypi/nose - ], ) From ae81f860d0786531c95e9cf649e3748eb1713bd6 Mon Sep 17 00:00:00 2001 From: JensDiemer Date: Fri, 21 Aug 2015 22:45:53 +0200 Subject: [PATCH 5/5] update README and release as v0.5.2 --- README.creole | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.creole b/README.creole index dfe87fde..b221dc37 100644 --- a/README.creole +++ b/README.creole @@ -154,6 +154,9 @@ The is a simple "starter GUI", just call the cli without arguments: {{{%APPDATA%\DragonPy_env\Scripts\DragonPy.exe}}} +It looks like this: + +{{http://www.jensdiemer.de/static/jensdiemer.de/screenshots/20150821_DragonPy_starterGUI.png|starter GUI}} == ROMs @@ -432,8 +435,9 @@ generic syntax highlighter == History -* [[https://github.com/jedie/DragonPy/compare/v0.5.1...v0.5.2|20.08.2015 - v0.5.2]]: (not released, yet) +* [[https://github.com/jedie/DragonPy/compare/v0.5.1...v0.5.2|20.08.2015 - v0.5.2]]: ** Add run 'MC6809 benchmark' button to 'starter GUI' +** bugfix 'file not found' in 'starter GUI' ** change the GUI a little bit * [[https://github.com/jedie/DragonPy/compare/v0.5.0...v0.5.1|19.08.2015 - v0.5.1]]: ** Add a "starter GUI"