comparison piecrust/commands/base.py @ 3:f485ba500df3

Gigantic change to basically make PieCrust 2 vaguely functional. - Serving works, with debug window. - Baking works, multi-threading, with dependency handling. - Various things not implemented yet.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 10 Aug 2014 23:43:16 -0700
parents aaa8fb7c8918
children c8c522dacfea
comparison
equal deleted inserted replaced
2:40fa08b261b9 3:f485ba500df3
1 import logging 1 import logging
2 import functools
2 from piecrust.pathutil import SiteNotFoundError 3 from piecrust.pathutil import SiteNotFoundError
3 4
4 5
5 logger = logging.getLogger(__name__) 6 logger = logging.getLogger(__name__)
6 7
7 8
8 class CommandContext(object): 9 class CommandContext(object):
9 def __init__(self, app, args): 10 def __init__(self, app, args):
10 self.app = app 11 self.app = app
11 self.args = args 12 self.args = args
13 self.result = 0
12 14
13 15
14 class ChefCommand(object): 16 class ChefCommand(object):
15 def __init__(self): 17 def __init__(self):
16 self.name = '__unknown__' 18 self.name = '__unknown__'
17 self.description = '__unknown__' 19 self.description = '__unknown__'
18 self.requires_website = True 20 self.requires_website = True
19 21
20 def setupParser(self, parser): 22 def setupParser(self, parser, app):
21 raise NotImplementedError() 23 raise NotImplementedError()
22 24
23 def run(self, ctx): 25 def run(self, ctx):
24 raise NotImplementedError() 26 raise NotImplementedError()
25 27
26 def _runFromChef(self, app, res): 28 def _runFromChef(self, app, res):
27 if app.root is None and self.requires_website: 29 if app.root_dir is None and self.requires_website:
28 raise SiteNotFoundError() 30 raise SiteNotFoundError()
29 self.run(CommandContext(app, res)) 31 ctx = CommandContext(app, res)
32 self.run(ctx)
33 return ctx.result
30 34
35
36 class ExtendableChefCommand(ChefCommand):
37 def __init__(self):
38 super(ExtendableChefCommand, self).__init__()
39 self._extensions = None
40
41 def setupParser(self, parser, app):
42 self._loadExtensions(app)
43 subparsers = parser.add_subparsers()
44 for e in self._extensions:
45 p = subparsers.add_parser(e.name, help=e.description)
46 e.setupParser(p, app)
47 p.set_defaults(func=e._runFromChef)
48
49 def _loadExtensions(self, app):
50 if self._extensions is not None:
51 return
52 self._extensions = []
53 for e in app.plugin_loader.getCommandExtensions():
54 if e.command_name == self.name and e.supports(app):
55 self._extensions.append(e)
56
57
58 class ChefCommandExtension(ChefCommand):
59 def __init__(self):
60 super(ChefCommandExtension, self).__init__()
61 self.command_name = '__unknown__'
62
63 def supports(self, app):
64 return True
65
66
67 class _WrappedCommand(ChefCommand):
68 def __init__(self, func, name, description):
69 super(_WrappedCommand, self).__init__()
70 self.func = func
71 self.name = name
72 self.description = description
73
74 def run(self, ctx):
75 self.func(ctx)
76
77
78 def simple_command(f, name, description=None):
79 @functools.wraps(f)
80 def wrapper(*args, **kwargs):
81 return f(*args, **kwargs)
82 cmd = _WrappedCommand(f, name, description)
83 f.__command_class__ = cmd
84 return wrapper
85
86
87 def get_func_command(f):
88 return getattr(f, '__command_class__')
89