From fc471a457ae334e24422f939c04be25587d6d357 Mon Sep 17 00:00:00 2001 From: Joe Esposito Date: Sun, 3 Apr 2016 02:05:06 -0400 Subject: [PATCH] Add --afterrun option instead of --oninterrupt: * Name chosen for consistency with --beforerun * Pass the py.test exit code as a CLI parameter * Always run this hook, even on KeyboardInterrupt * Clarify that --onexit runs when pytest-watch exits * Clarify that --runner overrides the literal "py.test" command * Use subprocess.call instead of os.system in run_hook (and handle passing arguments) --- pytest_watch/command.py | 9 +++++---- pytest_watch/watcher.py | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/pytest_watch/command.py b/pytest_watch/command.py index 0cd472f..19eaad5 100644 --- a/pytest_watch/command.py +++ b/pytest_watch/command.py @@ -16,11 +16,12 @@ (if relative, starts from root of each watched dir). -c --clear Automatically clear the screen before each run. --beforerun= Run arbitrary command before tests are run. + --afterrun Run arbitrary command on completion or interruption. + The exit code of "py.test" is passed as an argument. --onpass= Run arbitrary command on pass. --onfail= Run arbitrary command on failure. - --onexit= Run arbitrary command when exiting. - --oninterrupt= Run arbitrary command on KeyboardInterrupt. - --runner= Run a custom command instead of py.test. + --onexit= Run arbitrary command when exiting pytest-watch. + --runner= Run a custom command instead of "py.test". --pdb Start the interactive Python debugger on errors. This also enables --wait to prevent pdb interruption. --nobeep Do not beep on failure. @@ -105,8 +106,8 @@ def main(argv=None): onfail=args['--onfail'], runner=args['--runner'], beforerun=args['--beforerun'], + afterrun=args['--afterrun'], onexit=args['--onexit'], - oninterrupt=args['--oninterrupt'], poll=args['--poll'], extensions=extensions, args=pytest_args, diff --git a/pytest_watch/watcher.py b/pytest_watch/watcher.py index 16d147f..b8fabd0 100644 --- a/pytest_watch/watcher.py +++ b/pytest_watch/watcher.py @@ -45,7 +45,6 @@ # Exit codes from pytest # http://pytest.org/latest/_modules/_pytest/main.html EXIT_OK = 0 -EXIT_INTERRUPTED = 2 EXIT_NOTESTSCOLLECTED = 5 @@ -170,17 +169,18 @@ def _split_recursive(directories, ignore): return sorted(set(recursedirs)), sorted(set(norecursedirs)) -def run_hook(cmd): +def run_hook(cmd, *args): """ Runs a command hook, if specified. """ if cmd: - os.system(cmd) + command = ' '.join(map(str, (cmd,) + args)) + subprocess.call(command, shell=True) def watch(directories=[], ignore=[], auto_clear=False, beep_on_failure=True, - onpass=None, onfail=None, runner=None, beforerun=None, onexit=None, - oninterrupt=None, poll=False, extensions=[], args=[], spool=None, + onpass=None, onfail=None, runner=None, beforerun=None, afterrun=None, + onexit=None, poll=False, extensions=[], args=[], spool=None, wait=False, verbose=False, quiet=False): argv = (runner or 'py.test').split(' ') + (args or []) @@ -237,15 +237,15 @@ def watch(directories=[], ignore=[], auto_clear=False, beep_on_failure=True, sleep(0.1) except KeyboardInterrupt: # Wait for current test run cleanup - if p.wait() == EXIT_INTERRUPTED: - run_hook(oninterrupt) + run_hook(afterrun, p.wait()) # Exit, since this keyboard interrupt was user-initiated break - # Run custom commands - if exit_code == EXIT_INTERRUPTED: - run_hook(oninterrupt) - elif exit_code in [EXIT_OK, EXIT_NOTESTSCOLLECTED]: + # Run custom command + run_hook(afterrun, exit_code) + + # Run dependent commands + if exit_code in [EXIT_OK, EXIT_NOTESTSCOLLECTED]: run_hook(onpass) else: if beep_on_failure: