from __future__ import print_function

import os
import sys
from subprocess import check_call, CalledProcessError

import tst
from tst.colors import *
from tst.utils import cprint

EXTERNALS = [
    "test",
    "status",
    "new",
    "delete",
]
DEFAULT_COMMAND = "test"


def run_external_command(command, args):
    script_name = os.path.expanduser("tst-%s" % command)
    args.insert(0, script_name)
    try:
        check_call(args)
    except CalledProcessError:
        pass
    except OSError:
        print("tst: couldn't run command '%s'" % command, file=sys.stderr)


def identify_and_run_command(args):
    from distutils.spawn import find_executable
    if args and (args[0] in EXTERNALS):
        command_name = args.pop(0)
        run_external_command(command_name, args)

    elif args and find_executable('tst-%s' % args[0]):
        command_name = args.pop(0)
        run_external_command(command_name, args)
            
    else: # neither internal, nor external command!?
        command_name = DEFAULT_COMMAND
        run_external_command(command_name, args)

    return command_name


def dispatcher(args):
    possible_command = args[0] if args else None
    if possible_command in ['--version', '-v', 'version']:
        import version
        version.main()

    elif possible_command == 'info':
        import info
        info.main()

    elif possible_command == 'login':
        import login
        login.main()

    elif possible_command == 'ls':
        import ls
        ls.main()

    elif possible_command == 'commit':
        dirtype = tst.dirtype()
        if dirtype == "old:activity":
            cprint(LRED, "┌──────────────────────────────────────────────────────────┐")
            cprint(LRED, "│ Oops...                                                  │")
            cprint(LRED, "│                                                          │")
            cprint(LRED, "│ This directory contains an activity in an old format. It │")
            cprint(LRED, "│ is no longer supported, however. Consider discarding     │")
            cprint(LRED, "│ this directory and performing a new checkout of the same │")
            cprint(LRED, "│ activity from the source site to have it updated to the  │")
            cprint(LRED, "│ latest version and current format.                       │")
            cprint(LRED, "└──────────────────────────────────────────────────────────┘")
            sys.exit(1)

        elif dirtype in ["assignment", None]:
            import commit
            commit.main()

        else:
            cprint(LRED, "No assignment found in this directory")
            sys.exit(1)

    elif possible_command == 'checkout':
        dirtype = tst.dirtype()
        if dirtype == "old:activity":
            cprint(YELLOW, "┌─────────────────────────────────────────────────────────┐")
            cprint(YELLOW, "│ IMPORTANT                                               │")
            cprint(YELLOW, "│                                                         │")
            cprint(YELLOW, "│ This is an old style activity. The old checkout command │")
            cprint(YELLOW, "│ will be used.                                           │")
            cprint(YELLOW, "└─────────────────────────────────────────────────────────┘")
            run_external_command("checkout", args[1:])

        elif dirtype not in [None, "assignment"]:
            cprint(LRED, "┌───────────────────────────────────────────────┐")
            cprint(LRED, "│ checkout cannot be executed in this directory │")
            cprint(LRED, "│                                               │")
            cprint(LRED, "│ Currently, the checkout command must be used  │")
            cprint(LRED, "│ in a non tst directory.                       │")
            cprint(LRED, "└───────────────────────────────────────────────┘")

        else:
            import checkout
            checkout.main()

    elif possible_command == 'update':
        cprint(LRED, "┌─────────────────────────────────────┐")
        cprint(LRED, "│ update is deprecated                │")
        cprint(LRED, "│                                     │")
        cprint(LRED, "│ Use pip to update tst:              │")
        cprint(LRED, "│ $ pip install tst --upgrade --user  │")
        cprint(LRED, "└─────────────────────────────────────┘")

    elif possible_command == 'config':
        cprint(LRED, "┌────────────────────────────────────────────────────┐")
        cprint(LRED, "│ config is deprecated                               │")
        cprint(LRED, "│                                                    │")
        cprint(LRED, "│ Edit ~/.tst/config.yaml directly to configure tst. │")
        cprint(LRED, "│ See documentation to see existing options.         │")
        cprint(LRED, "└────────────────────────────────────────────────────┘")

    else:
        command = identify_and_run_command(args)


def main():
    args = sys.argv[:]
    args.pop(0) # pop dispatcher name
    config = tst.get_config()
    dispatcher(args) 

@@ -4957,16 +4957,29 @@
 main():%0A
+    try:%0A    
     args
@@ -4993,24 +4993,28 @@
 argv%5B:%5D%0A    
+  
+  
 args.pop(0) 
@@ -5035,16 +5035,20 @@
 er name%0A
+    
     conf
@@ -5073,16 +5073,20 @@
 g()%0A    
+ 
+   
 dispatch
@@ -5095,8 +5095,96 @@
 (args) %0A
+    except (KeyboardInterrupt, SystemExit):%0A        cprint(LRED, %22%5Cnuser interruption%22)%0A

Add try/except block to catch Ctrl-C nicely