changeset 879:58ae026b4c31

chef: Optimize startup time.
author Ludovic Chabant <ludovic@chabant.com>
date Thu, 15 Jun 2017 22:38:05 -0700
parents 313db67cfc35
children 342e3ea24b5d
files piecrust/commands/builtin/baking.py piecrust/commands/builtin/info.py piecrust/commands/builtin/plugins.py piecrust/commands/builtin/publishing.py piecrust/commands/builtin/scaffolding.py piecrust/commands/builtin/themes.py piecrust/commands/builtin/util.py piecrust/plugins/builtin.py piecrust/publishing/publisher.py
diffstat 9 files changed, 96 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/piecrust/commands/builtin/baking.py	Thu Jun 15 22:16:34 2017 -0700
+++ b/piecrust/commands/builtin/baking.py	Thu Jun 15 22:38:05 2017 -0700
@@ -1,9 +1,6 @@
 import os.path
 import time
-import pprint
 import logging
-import fnmatch
-import textwrap
 import datetime
 from colorama import Fore
 from piecrust.commands.base import ChefCommand
@@ -166,6 +163,7 @@
             help="Show manifest entries from the record.")
 
     def run(self, ctx):
+        import fnmatch
         from piecrust.baking.baker import get_bake_records_path
         from piecrust.pipelines.records import load_records
 
@@ -281,6 +279,9 @@
 
 
 def _print_record_entry(e):
+    import pprint
+    import textwrap
+
     logger.info(" - %s" % e.item_spec)
     logger.info("   Outputs:")
     out_paths = list(e.getAllOutputPaths())
--- a/piecrust/commands/builtin/info.py	Thu Jun 15 22:16:34 2017 -0700
+++ b/piecrust/commands/builtin/info.py	Thu Jun 15 22:38:05 2017 -0700
@@ -1,9 +1,6 @@
 import os.path
 import logging
-import fnmatch
 from piecrust.commands.base import ChefCommand
-from piecrust.configuration import ConfigurationDumper
-from piecrust.sources.fs import FSContentSourceBase
 
 
 logger = logging.getLogger(__name__)
@@ -35,6 +32,9 @@
             nargs='?')
 
     def run(self, ctx):
+        import yaml
+        from piecrust.configuration import ConfigurationDumper
+
         if ctx.args.path:
             show = ctx.app.config.get(ctx.args.path)
         else:
@@ -42,7 +42,6 @@
 
         if show is not None:
             if isinstance(show, (dict, list)):
-                import yaml
                 out = yaml.dump(show, default_flow_style=False,
                                 Dumper=ConfigurationDumper)
                 logger.info(out)
@@ -147,6 +146,9 @@
             action='store_true')
 
     def run(self, ctx):
+        import fnmatch
+        from piecrust.sources.fs import FSContentSourceBase
+
         pattern = ctx.args.pattern
         sources = list(ctx.app.sources)
         if not ctx.args.exact and pattern is not None:
--- a/piecrust/commands/builtin/plugins.py	Thu Jun 15 22:16:34 2017 -0700
+++ b/piecrust/commands/builtin/plugins.py	Thu Jun 15 22:38:05 2017 -0700
@@ -1,6 +1,5 @@
 import logging
 from piecrust.commands.base import ChefCommand
-from piecrust.pathutil import SiteNotFoundError
 
 
 logger = logging.getLogger(__name__)
@@ -20,17 +19,19 @@
 
         subparsers = parser.add_subparsers()
         p = subparsers.add_parser(
-                'list',
-                help="Lists the plugins installed in the current website.")
+            'list',
+            help="Lists the plugins installed in the current website.")
         p.add_argument(
-                '-a', '--all',
-                action='store_true',
-                help=("Also list all the available plugins for the "
-                      "current environment. The installed one will have an "
-                      "asterix (*)."))
+            '-a', '--all',
+            action='store_true',
+            help=("Also list all the available plugins for the "
+                  "current environment. The installed one will have an "
+                  "asterix (*)."))
         p.set_defaults(sub_func=self._listPlugins)
 
     def checkedRun(self, ctx):
+        from piecrust.pathutil import SiteNotFoundError
+
         if ctx.app.root_dir is None:
             raise SiteNotFoundError(theme=ctx.app.theme_site)
 
@@ -40,10 +41,11 @@
         ctx.args.sub_func(ctx)
 
     def _listPlugins(self, ctx):
+        import pip
+
         names = {}
         installed_suffix = ''
         if ctx.args.all:
-            import pip
             prefix = 'PieCrust-'
             installed_packages = pip.get_installed_distributions()
             for plugin in installed_packages:
--- a/piecrust/commands/builtin/publishing.py	Thu Jun 15 22:16:34 2017 -0700
+++ b/piecrust/commands/builtin/publishing.py	Thu Jun 15 22:38:05 2017 -0700
@@ -1,8 +1,5 @@
 import logging
-import urllib.parse
 from piecrust.commands.base import ChefCommand
-from piecrust.pathutil import SiteNotFoundError
-from piecrust.publishing.publisher import Publisher, find_publisher_name
 
 
 logger = logging.getLogger(__name__)
@@ -18,13 +15,13 @@
 
     def setupParser(self, parser, app):
         parser.add_argument(
-                '--log-publisher',
-                metavar='LOG_FILE',
-                help="Log the publisher's output to a given file.")
+            '--log-publisher',
+            metavar='LOG_FILE',
+            help="Log the publisher's output to a given file.")
         parser.add_argument(
-                '--preview',
-                action='store_true',
-                help="Only preview what the publisher would do.")
+            '--preview',
+            action='store_true',
+            help="Only preview what the publisher would do.")
 
         # Don't setup anything for a null app.
         if app.root_dir is None:
@@ -33,8 +30,8 @@
         subparsers = parser.add_subparsers()
         for pub in app.publishers:
             p = subparsers.add_parser(
-                    pub.target,
-                    help="Publish using target '%s'." % pub.target)
+                pub.target,
+                help="Publish using target '%s'." % pub.target)
             pub.setupPublishParser(p, app)
             p.set_defaults(sub_func=self._doPublish)
             p.set_defaults(target=pub.target)
@@ -47,6 +44,8 @@
                 "https://bolt80.com/piecrust/en/latest/docs/publishing/")
 
     def checkedRun(self, ctx):
+        from piecrust.pathutil import SiteNotFoundError
+
         if ctx.app.root_dir is None:
             raise SiteNotFoundError(theme=ctx.app.theme_site)
 
@@ -56,12 +55,14 @@
         ctx.args.sub_func(ctx)
 
     def _doPublish(self, ctx):
+        from piecrust.publishing.publisher import Publisher
+
         pub = Publisher(ctx.app)
         pub.run(
-                ctx.args.target,
-                preview=ctx.args.preview,
-                extra_args=ctx.args,
-                log_file=ctx.args.log_publisher,
-                applied_config_variant=ctx.config_variant,
-                applied_config_values=ctx.config_values)
+            ctx.args.target,
+            preview=ctx.args.preview,
+            extra_args=ctx.args,
+            log_file=ctx.args.log_publisher,
+            applied_config_variant=ctx.config_variant,
+            applied_config_values=ctx.config_values)
 
--- a/piecrust/commands/builtin/scaffolding.py	Thu Jun 15 22:16:34 2017 -0700
+++ b/piecrust/commands/builtin/scaffolding.py	Thu Jun 15 22:38:05 2017 -0700
@@ -1,15 +1,7 @@
 import os
 import os.path
-import io
-import time
-import glob
 import logging
-import textwrap
-from piecrust import RESOURCES_DIR
-from piecrust.chefutil import print_help_item
 from piecrust.commands.base import ExtendableChefCommand, ChefCommandExtension
-from piecrust.pathutil import SiteNotFoundError
-from piecrust.sources.fs import FSContentSourceBase
 
 
 logger = logging.getLogger(__name__)
@@ -56,6 +48,8 @@
             p.set_defaults(sub_func=self._doRun)
 
     def checkedRun(self, ctx):
+        from piecrust.pathutil import SiteNotFoundError
+
         if ctx.app.root_dir is None:
             raise SiteNotFoundError(theme=ctx.app.theme_site)
 
@@ -65,7 +59,9 @@
         ctx.args.sub_func(ctx)
 
     def _doRun(self, ctx):
+        import time
         from piecrust.uriutil import multi_replace
+        from piecrust.sources.fs import FSContentSourceBase
 
         if not hasattr(ctx.args, 'source'):
             raise Exception("No source specified. "
@@ -144,6 +140,8 @@
         return descs[name]
 
     def getTemplate(self, app, name):
+        from piecrust import RESOURCES_DIR
+
         assert name in ['default', 'rss', 'atom']
         src_path = os.path.join(RESOURCES_DIR, 'prepare', '%s.html' % name)
         with open(src_path, 'r', encoding='utf8') as fp:
@@ -174,6 +172,8 @@
         return "User-defined template."
 
     def getTemplate(self, app, name):
+        import glob
+
         templates_dir = self._getTemplatesDir(app)
         pattern = os.path.join(templates_dir, '%s.*' % name)
         matches = glob.glob(pattern)
@@ -196,6 +196,10 @@
                  "Available templates for the 'prepare' command.")]
 
     def getHelpTopic(self, topic, app):
+        import io
+        import textwrap
+        from piecrust.chefutil import print_help_item
+
         with io.StringIO() as tplh:
             extensions = app.plugin_loader.getCommandExtensions()
             for e in extensions:
--- a/piecrust/commands/builtin/themes.py	Thu Jun 15 22:16:34 2017 -0700
+++ b/piecrust/commands/builtin/themes.py	Thu Jun 15 22:38:05 2017 -0700
@@ -1,12 +1,8 @@
 import os
 import os.path
-import shutil
 import logging
-import yaml
-from piecrust import (
-        RESOURCES_DIR, THEME_DIR, THEME_CONFIG_PATH, THEME_INFO_PATH)
+from piecrust import THEME_DIR, THEME_CONFIG_PATH, THEME_INFO_PATH
 from piecrust.commands.base import ChefCommand
-from piecrust.pathutil import SiteNotFoundError
 
 
 logger = logging.getLogger(__name__)
@@ -21,34 +17,36 @@
     def setupParser(self, parser, app):
         subparsers = parser.add_subparsers()
         p = subparsers.add_parser(
-                'info',
-                help="Provides information about the current theme.")
+            'info',
+            help="Provides information about the current theme.")
         p.set_defaults(sub_func=self._info)
 
         p = subparsers.add_parser(
-                'override',
-                help="Copies the current theme to the website for "
-                     "customization.")
+            'override',
+            help="Copies the current theme to the website for "
+            "customization.")
         p.set_defaults(sub_func=self._overrideTheme)
 
         p = subparsers.add_parser(
-                'link',
-                help="Makes a given theme the active one for the current "
-                     "website by creating a symbolic link to it from the "
-                     "'theme' directory.")
+            'link',
+            help="Makes a given theme the active one for the current "
+            "website by creating a symbolic link to it from the "
+            "'theme' directory.")
         p.add_argument(
-                'theme_dir',
-                help="The directory of the theme to link.")
+            'theme_dir',
+            help="The directory of the theme to link.")
         p.set_defaults(sub_func=self._linkTheme)
 
         p = subparsers.add_parser(
-                'unlink',
-                help="Removes the currently active theme for the website. "
-                     "This removes the symbolic link to the theme, if any, or "
-                     "deletes the theme folder if it was copied locally.")
+            'unlink',
+            help="Removes the currently active theme for the website. "
+            "This removes the symbolic link to the theme, if any, or "
+            "deletes the theme folder if it was copied locally.")
         p.set_defaults(sub_func=self._unlinkTheme)
 
     def checkedRun(self, ctx):
+        from piecrust.pathutil import SiteNotFoundError
+
         if ctx.app.root_dir is None:
             raise SiteNotFoundError(theme=ctx.app.theme_site)
 
@@ -58,6 +56,8 @@
         ctx.args.sub_func(ctx)
 
     def _info(self, ctx):
+        import yaml
+
         theme_dir = ctx.app.theme_dir
         if not os.path.exists(theme_dir):
             logger.info("Using default theme, from: %s" % ctx.app.theme_dir)
@@ -84,6 +84,8 @@
                     logger.info("  - %s: %s" % (str(k), str(v)))
 
     def _overrideTheme(self, ctx):
+        import shutil
+
         theme_dir = ctx.app.theme_dir
         if not theme_dir:
             logger.error("There is no theme currently applied.")
@@ -126,7 +128,7 @@
             return 1
 
         msg = ("A theme already exists, and will be deleted. "
-                "Are you sure? [Y/n]")
+               "Are you sure? [Y/n]")
         self._doUnlinkTheme(ctx.app.root_dir, msg)
 
         theme_dir = os.path.join(ctx.app.root_dir, THEME_DIR)
@@ -139,10 +141,12 @@
 
     def _unlinkTheme(self, ctx):
         msg = ("The active theme is local. Are you sure you want "
-                "to delete the theme directory? [Y/n]")
+               "to delete the theme directory? [Y/n]")
         self._doUnlinkTheme(ctx.app.root_dir, msg)
 
     def _doUnlinkTheme(self, root_dir, delete_message):
+        import shutil
+
         theme_dir = os.path.join(root_dir, THEME_DIR)
 
         if os.path.islink(theme_dir):
--- a/piecrust/commands/builtin/util.py	Thu Jun 15 22:16:34 2017 -0700
+++ b/piecrust/commands/builtin/util.py	Thu Jun 15 22:38:05 2017 -0700
@@ -1,9 +1,6 @@
 import os
 import os.path
-import shutil
-import codecs
 import logging
-import yaml
 from piecrust import CACHE_DIR, RESOURCES_DIR
 from piecrust.app import CONFIG_PATH, THEME_CONFIG_PATH
 from piecrust.commands.base import ChefCommand
@@ -21,8 +18,8 @@
 
     def setupParser(self, parser, app):
         parser.add_argument(
-                'destination',
-                help="The destination directory in which to create the website.")
+            'destination',
+            help="The destination directory in which to create the website.")
 
     def run(self, ctx):
         destination = ctx.args.destination
@@ -41,7 +38,8 @@
 
         tpl_path = os.path.join(RESOURCES_DIR, 'webinit', CONFIG_PATH)
         if ctx.args.theme:
-            tpl_path = os.path.join(RESOURCES_DIR, 'webinit', THEME_CONFIG_PATH)
+            tpl_path = os.path.join(RESOURCES_DIR, 'webinit',
+                                    THEME_CONFIG_PATH)
         with open(tpl_path, 'r', encoding='utf-8') as fp:
             config_text = fp.read()
 
@@ -59,6 +57,8 @@
         pass
 
     def run(self, ctx):
+        import shutil
+
         cache_dir = os.path.join(ctx.app.root_dir, CACHE_DIR)
         if cache_dir and os.path.isdir(cache_dir):
             logger.info("Purging cache: %s" % cache_dir)
--- a/piecrust/plugins/builtin.py	Thu Jun 15 22:16:34 2017 -0700
+++ b/piecrust/plugins/builtin.py	Thu Jun 15 22:38:05 2017 -0700
@@ -16,8 +16,8 @@
         from piecrust.commands.builtin.plugins import PluginsCommand
         from piecrust.commands.builtin.publishing import PublishCommand
         from piecrust.commands.builtin.scaffolding import PrepareCommand
-        from piecrust.commands.builtin.serving import (ServeCommand)
-        from piecrust.commands.builtin.themes import (ThemesCommand)
+        from piecrust.commands.builtin.serving import ServeCommand
+        from piecrust.commands.builtin.themes import ThemesCommand
         from piecrust.commands.builtin.util import (
             InitCommand, PurgeCommand, ImportCommand)
 
--- a/piecrust/publishing/publisher.py	Thu Jun 15 22:16:34 2017 -0700
+++ b/piecrust/publishing/publisher.py	Thu Jun 15 22:38:05 2017 -0700
@@ -1,7 +1,6 @@
 import os.path
 import time
 import logging
-import urllib.parse
 from piecrust.chefutil import format_timed
 from piecrust.publishing.base import PublishingContext
 
@@ -30,7 +29,7 @@
         pub = self.app.getPublisher(target)
         if pub is None:
             raise InvalidPublishTargetError(
-                    "No such publish target: %s" % target)
+                "No such publish target: %s" % target)
 
         # Will we need to bake first?
         bake_first = True
@@ -61,31 +60,31 @@
 
                 from piecrust.baking.baker import Baker
                 baker = Baker(
-                        self.app, bake_out_dir,
-                        applied_config_variant=applied_config_variant,
-                        applied_config_values=applied_config_values)
+                    self.app, bake_out_dir,
+                    applied_config_variant=applied_config_variant,
+                    applied_config_values=applied_config_values)
                 rec1 = baker.bake()
 
                 from piecrust.processing.pipeline import ProcessorPipeline
                 proc = ProcessorPipeline(
-                        self.app, bake_out_dir,
-                        applied_config_variant=applied_config_variant,
-                        applied_config_values=applied_config_values)
+                    self.app, bake_out_dir,
+                    applied_config_variant=applied_config_variant,
+                    applied_config_values=applied_config_values)
                 rec2 = proc.run()
 
                 was_baked = True
 
                 if not rec1.success or not rec2.success:
                     raise Exception(
-                            "Error during baking, aborting publishing.")
+                        "Error during baking, aborting publishing.")
                 logger.info(format_timed(bake_start_time, "Baked website."))
             else:
                 logger.info("Would bake to: %s" % bake_out_dir)
 
         # Publish!
         logger.debug(
-                "Running publish target '%s' with publisher: %s" %
-                (target, pub.PUBLISHER_NAME))
+            "Running publish target '%s' with publisher: %s" %
+            (target, pub.PUBLISHER_NAME))
         pub_start_time = time.perf_counter()
 
         ctx = PublishingContext()
@@ -99,7 +98,7 @@
             pub.run(ctx)
         except Exception as ex:
             raise PublishingError(
-                    "Error publishing to target: %s" % target) from ex
+                "Error publishing to target: %s" % target) from ex
         finally:
             if hdlr:
                 root_logger.removeHandler(hdlr)