Mercurial > piecrust2
comparison piecrust/main.py @ 852:4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
* Everything is a `ContentSource`, including assets directories.
* Most content sources are subclasses of the base file-system source.
* A source is processed by a "pipeline", and there are 2 built-in pipelines,
one for assets and one for pages. The asset pipeline is vaguely functional,
but the page pipeline is completely broken right now.
* Rewrite the baking process as just running appropriate pipelines on each
content item. This should allow for better parallelization.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 17 May 2017 00:11:48 -0700 |
parents | cd3a00455b87 |
children | eed19a80c00e |
comparison
equal
deleted
inserted
replaced
851:2c7e57d80bba | 852:4850f8c21b6e |
---|---|
7 import logging | 7 import logging |
8 import argparse | 8 import argparse |
9 import colorama | 9 import colorama |
10 from piecrust import APP_VERSION | 10 from piecrust import APP_VERSION |
11 from piecrust.app import ( | 11 from piecrust.app import ( |
12 PieCrust, PieCrustConfiguration, apply_variant_and_values) | 12 PieCrustFactory, PieCrustConfiguration) |
13 from piecrust.chefutil import ( | 13 from piecrust.chefutil import ( |
14 format_timed, log_friendly_exception, print_help_item) | 14 format_timed, log_friendly_exception, print_help_item) |
15 from piecrust.commands.base import CommandContext | 15 from piecrust.commands.base import CommandContext |
16 from piecrust.pathutil import SiteNotFoundError, find_app_root | 16 from piecrust.pathutil import SiteNotFoundError, find_app_root |
17 from piecrust.plugins.base import PluginLoader | 17 from piecrust.plugins.base import PluginLoader |
18 | 18 |
19 | 19 |
20 logger = logging.getLogger(__name__) | 20 logger = logging.getLogger(__name__) |
21 | 21 |
22 | 22 |
23 class ColoredFormatter(logging.Formatter): | 23 class ColoredFormatter(logging.Formatter): |
24 COLORS = { | 24 COLORS = { |
25 'DEBUG': colorama.Fore.BLACK + colorama.Style.BRIGHT, | 25 'DEBUG': colorama.Fore.BLACK + colorama.Style.BRIGHT, |
26 'INFO': '', | 26 'INFO': '', |
27 'WARNING': colorama.Fore.YELLOW, | 27 'WARNING': colorama.Fore.YELLOW, |
28 'ERROR': colorama.Fore.RED, | 28 'ERROR': colorama.Fore.RED, |
29 'CRITICAL': colorama.Back.RED + colorama.Fore.WHITE | 29 'CRITICAL': colorama.Back.RED + colorama.Fore.WHITE |
30 } | 30 } |
31 | 31 |
32 def __init__(self, fmt=None, datefmt=None): | 32 def __init__(self, fmt=None, datefmt=None): |
33 super(ColoredFormatter, self).__init__(fmt, datefmt) | 33 super(ColoredFormatter, self).__init__(fmt, datefmt) |
34 | 34 |
35 def format(self, record): | 35 def format(self, record): |
77 sys.exit(exit_code) | 77 sys.exit(exit_code) |
78 | 78 |
79 | 79 |
80 def _setup_main_parser_arguments(parser): | 80 def _setup_main_parser_arguments(parser): |
81 parser.add_argument( | 81 parser.add_argument( |
82 '--version', | 82 '--version', |
83 action='version', | 83 action='version', |
84 version=('%(prog)s ' + APP_VERSION)) | 84 version=('%(prog)s ' + APP_VERSION)) |
85 parser.add_argument( | 85 parser.add_argument( |
86 '--root', | 86 '--root', |
87 help="The root directory of the website.") | 87 help="The root directory of the website.") |
88 parser.add_argument( | 88 parser.add_argument( |
89 '--theme', | 89 '--theme', |
90 action='store_true', | 90 action='store_true', |
91 help="Makes the current command apply to a theme website.") | 91 help="Makes the current command apply to a theme website.") |
92 parser.add_argument( | 92 parser.add_argument( |
93 '--config', | 93 '--config', |
94 dest='config_variant', | 94 dest='config_variant', |
95 help="The configuration variant to use for this command.") | 95 help="The configuration variant to use for this command.") |
96 parser.add_argument( | 96 parser.add_argument( |
97 '--config-set', | 97 '--config-set', |
98 nargs=2, | 98 nargs=2, |
99 metavar=('NAME', 'VALUE'), | 99 metavar=('NAME', 'VALUE'), |
100 action='append', | 100 action='append', |
101 dest='config_values', | 101 dest='config_values', |
102 help="Sets a specific site configuration setting.") | 102 help="Sets a specific site configuration setting.") |
103 parser.add_argument( | 103 parser.add_argument( |
104 '--debug', | 104 '--debug', |
105 help="Show debug information.", action='store_true') | 105 help="Show debug information.", action='store_true') |
106 parser.add_argument( | 106 parser.add_argument( |
107 '--debug-only', | 107 '--debug-only', |
108 action='append', | 108 action='append', |
109 help="Only show debug information for the given categories.") | 109 help="Only show debug information for the given categories.") |
110 parser.add_argument( | 110 parser.add_argument( |
111 '--no-cache', | 111 '--no-cache', |
112 help="When applicable, disable caching.", | 112 help="When applicable, disable caching.", |
113 action='store_true') | 113 action='store_true') |
114 parser.add_argument( | 114 parser.add_argument( |
115 '--quiet', | 115 '--quiet', |
116 help="Print only important information.", | 116 help="Print only important information.", |
117 action='store_true') | 117 action='store_true') |
118 parser.add_argument( | 118 parser.add_argument( |
119 '--log', | 119 '--log', |
120 dest='log_file', | 120 dest='log_file', |
121 help="Send log messages to the specified file.") | 121 help="Send log messages to the specified file.") |
122 parser.add_argument( | 122 parser.add_argument( |
123 '--log-debug', | 123 '--log-debug', |
124 help="Log debug messages to the log file.", | 124 help="Log debug messages to the log file.", |
125 action='store_true') | 125 action='store_true') |
126 parser.add_argument( | 126 parser.add_argument( |
127 '--no-color', | 127 '--no-color', |
128 help="Don't use colorized output.", | 128 help="Don't use colorized output.", |
129 action='store_true') | 129 action='store_true') |
130 parser.add_argument( | 130 parser.add_argument( |
131 '--pid-file', | 131 '--pid-file', |
132 dest='pid_file', | 132 dest='pid_file', |
133 help="Write a PID file for the current process.") | 133 help="Write a PID file for the current process.") |
134 | 134 |
135 | 135 |
136 """ Kinda hacky, but we want the `serve` command to use a different cache | 136 """ Kinda hacky, but we want the `serve` command to use a different cache |
137 so that PieCrust doesn't need to re-render all the pages when going | 137 so that PieCrust doesn't need to re-render all the pages when going |
138 between `serve` and `bake` (or, worse, *not* re-render them all correctly | 138 between `serve` and `bake` (or, worse, *not* re-render them all correctly |
139 and end up serving or baking the wrong version). | 139 and end up serving or baking the wrong version). |
140 """ | 140 """ |
141 _command_caches = { | 141 _command_caches = { |
142 'serve': 'server'} | 142 'serve': 'server'} |
143 | 143 |
144 | 144 |
145 def _pre_parse_chef_args(argv): | 145 def _pre_parse_chef_args(argv): |
146 # We need to parse some arguments before we can build the actual argument | 146 # We need to parse some arguments before we can build the actual argument |
147 # parser, because it can affect which plugins will be loaded. Also, log- | 147 # parser, because it can affect which plugins will be loaded. Also, log- |
233 root = None | 233 root = None |
234 | 234 |
235 # Can't apply custom configuration stuff if there's no website. | 235 # Can't apply custom configuration stuff if there's no website. |
236 if (pre_args.config_variant or pre_args.config_values) and not root: | 236 if (pre_args.config_variant or pre_args.config_values) and not root: |
237 raise SiteNotFoundError( | 237 raise SiteNotFoundError( |
238 "Can't apply any configuration variant or value overrides, " | 238 "Can't apply any configuration variant or value overrides, " |
239 "there is no website here.") | 239 "there is no website here.") |
240 | 240 |
241 if root: | 241 if root: |
242 cache_key = None | 242 cache_key = None |
243 if not pre_args.no_cache: | 243 if not pre_args.no_cache: |
244 cache_key = _build_cache_key(pre_args) | 244 cache_key = _build_cache_key(pre_args) |
245 app = PieCrust( | 245 appfactory = PieCrustFactory( |
246 root, | 246 root, |
247 theme_site=pre_args.theme, | 247 theme_site=pre_args.theme, |
248 cache=(not pre_args.no_cache), | 248 cache=(not pre_args.no_cache), |
249 cache_key=cache_key, | 249 cache_key=cache_key, |
250 debug=pre_args.debug) | 250 debug=pre_args.debug, |
251 apply_variant_and_values( | 251 config_variant=pre_args.config_variant, |
252 app, pre_args.config_variant, pre_args.config_values) | 252 config_values=pre_args.config_values) |
253 app = appfactory.create() | |
253 else: | 254 else: |
255 appfactory = None | |
254 app = NullPieCrust( | 256 app = NullPieCrust( |
255 theme_site=pre_args.theme) | 257 theme_site=pre_args.theme) |
256 | 258 |
257 # Setup the arg parser. | 259 # Setup the arg parser. |
258 parser = argparse.ArgumentParser( | 260 parser = argparse.ArgumentParser( |
259 prog='chef', | 261 prog='chef', |
260 description="The PieCrust chef manages your website.", | 262 description="The PieCrust chef manages your website.", |
261 formatter_class=argparse.RawDescriptionHelpFormatter) | 263 formatter_class=argparse.RawDescriptionHelpFormatter) |
262 _setup_main_parser_arguments(parser) | 264 _setup_main_parser_arguments(parser) |
263 | 265 |
264 commands = sorted(app.plugin_loader.getCommands(), | 266 commands = sorted(app.plugin_loader.getCommands(), |
265 key=lambda c: c.name) | 267 key=lambda c: c.name) |
266 subparsers = parser.add_subparsers(title='list of commands') | 268 subparsers = parser.add_subparsers(title='list of commands') |
287 if not hasattr(result, 'func'): | 289 if not hasattr(result, 'func'): |
288 parser.print_help() | 290 parser.print_help() |
289 return 0 | 291 return 0 |
290 | 292 |
291 # Run the command! | 293 # Run the command! |
292 ctx = CommandContext(app, parser, result) | 294 ctx = CommandContext(appfactory, app, parser, result) |
293 ctx.config_variant = pre_args.config_variant | |
294 ctx.config_values = pre_args.config_values | |
295 | |
296 exit_code = result.func(ctx) | 295 exit_code = result.func(ctx) |
297 if exit_code is None: | 296 if exit_code is None: |
298 return 0 | 297 return 0 |
299 if not isinstance(exit_code, int): | 298 if not isinstance(exit_code, int): |
300 logger.error("Got non-integer exit code: %s" % exit_code) | 299 logger.error("Got non-integer exit code: %s" % exit_code) |