Mercurial > piecrust2
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 |