Skip to content

Commit

Permalink
Add control handling logic
Browse files Browse the repository at this point in the history
  • Loading branch information
prophile committed Mar 6, 2013
1 parent c2d710d commit 3ce04d5
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
65 changes: 65 additions & 0 deletions src/control.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""compctl
Usage:
compctl halt
compctl usage
"""

import shlex
import re
from docopt import docopt, DocoptExit

class CommandError(Exception):
pass

def parse(cmd):
parts = shlex.split(cmd)
try:
options = docopt(__doc__, argv = parts,
help = False, version = None)
return options
except DocoptExit:
raise CommandError()

HANDLERS = {}

def handler(subcommand):
def wrapper(fn):
HANDLERS[subcommand] = fn
return fn
return wrapper

def dispatch(options, responder):
for name, callback in HANDLERS.iteritems():
if options[name]:
callback(responder, options)
return
raise CommandError()

@handler('usage')
def handle_usage(responder, opts):
regex = re.compile(' compctl (.*)')
for line in __doc__.split('\n')[3:]:
match = regex.match(line)
if match:
responder('Usage: {0}'.format(match.group(1)))

@handler('halt')
def halt_system(responder, options):
import sys
responder("System going down for halt")
sys.exit(0)

def default_responder(output):
print output

def handle(cmd, responder = default_responder, no_auto_fail = False):
try:
dispatch(parse(cmd), responder)
except CommandError:
if no_auto_fail:
raise
else:
handle('usage', responder, no_auto_fail = True)

30 changes: 30 additions & 0 deletions src/test_control.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import control
import mock
import sys

def test_halt_parse():
options = control.parse('halt')
assert options['halt']

def check_showed_usage(responder):
responder.assert_any_call('Usage: halt')
responder.assert_any_call('Usage: usage')

def test_usage():
responder = mock.Mock()
control.handle('usage', responder)
check_showed_usage(responder)

def test_halt():
exit_handler = mock.Mock()
responder = mock.Mock()
with mock.patch('sys.exit', exit_handler):
control.handle('halt', responder)
responder.assert_called_once_with('System going down for halt')
exit_handler.assert_called_once_with(0)

def test_unknown():
responder = mock.Mock()
control.handle('hnnnng', responder)
check_showed_usage(responder)

0 comments on commit 3ce04d5

Please sign in to comment.