diff 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
line wrap: on
line diff
--- a/piecrust/commands/base.py	Wed Dec 25 22:16:46 2013 -0800
+++ b/piecrust/commands/base.py	Sun Aug 10 23:43:16 2014 -0700
@@ -1,4 +1,5 @@
 import logging
+import functools
 from piecrust.pathutil import SiteNotFoundError
 
 
@@ -9,6 +10,7 @@
     def __init__(self, app, args):
         self.app = app
         self.args = args
+        self.result = 0
 
 
 class ChefCommand(object):
@@ -17,14 +19,71 @@
         self.description = '__unknown__'
         self.requires_website = True
 
-    def setupParser(self, parser):
+    def setupParser(self, parser, app):
         raise NotImplementedError()
 
     def run(self, ctx):
         raise NotImplementedError()
 
     def _runFromChef(self, app, res):
-        if app.root is None and self.requires_website:
+        if app.root_dir is None and self.requires_website:
             raise SiteNotFoundError()
-        self.run(CommandContext(app, res))
+        ctx = CommandContext(app, res)
+        self.run(ctx)
+        return ctx.result
+
+
+class ExtendableChefCommand(ChefCommand):
+    def __init__(self):
+        super(ExtendableChefCommand, self).__init__()
+        self._extensions = None
+
+    def setupParser(self, parser, app):
+        self._loadExtensions(app)
+        subparsers = parser.add_subparsers()
+        for e in self._extensions:
+            p = subparsers.add_parser(e.name, help=e.description)
+            e.setupParser(p, app)
+            p.set_defaults(func=e._runFromChef)
+
+    def _loadExtensions(self, app):
+        if self._extensions is not None:
+            return
+        self._extensions = []
+        for e in app.plugin_loader.getCommandExtensions():
+            if e.command_name == self.name and e.supports(app):
+                self._extensions.append(e)
+
 
+class ChefCommandExtension(ChefCommand):
+    def __init__(self):
+        super(ChefCommandExtension, self).__init__()
+        self.command_name = '__unknown__'
+
+    def supports(self, app):
+        return True
+
+
+class _WrappedCommand(ChefCommand):
+    def __init__(self, func, name, description):
+        super(_WrappedCommand, self).__init__()
+        self.func = func
+        self.name = name
+        self.description = description
+
+    def run(self, ctx):
+        self.func(ctx)
+
+
+def simple_command(f, name, description=None):
+    @functools.wraps(f)
+    def wrapper(*args, **kwargs):
+        return f(*args, **kwargs)
+    cmd = _WrappedCommand(f, name, description)
+    f.__command_class__ = cmd
+    return wrapper
+
+
+def get_func_command(f):
+    return getattr(f, '__command_class__')
+