Mercurial > piecrust2
comparison piecrust/main.py @ 666:81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
* Compute cache keys up front, so the cache directory is only chosen once.
* Buffer up config variants to apply before loading the config. Makes it
possible to cache variant-resulting configs, too.
* Make a factory class to reuse the logic that creates the `PieCrust` object
correctly for multi-process workers and such.
* Add a test.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Thu, 03 Mar 2016 08:22:41 -0800 |
parents | 3ceeca7bb71c |
children | cd3a00455b87 |
comparison
equal
deleted
inserted
replaced
665:5dc13c816045 | 666:81d9c3a3a0b5 |
---|---|
1 import os | 1 import os |
2 import os.path | 2 import os.path |
3 import io | 3 import io |
4 import sys | 4 import sys |
5 import time | 5 import time |
6 import hashlib | |
6 import logging | 7 import logging |
7 import argparse | 8 import argparse |
8 import colorama | 9 import colorama |
9 from piecrust import APP_VERSION | 10 from piecrust import APP_VERSION |
10 from piecrust.app import ( | 11 from piecrust.app import ( |
49 self.cache_dir = None | 50 self.cache_dir = None |
50 self.config = PieCrustConfiguration() | 51 self.config = PieCrustConfiguration() |
51 self.plugin_loader = PluginLoader(self) | 52 self.plugin_loader = PluginLoader(self) |
52 self.env = None | 53 self.env = None |
53 | 54 |
54 def useSubCache(self, cache_name, cache_key): | |
55 pass | |
56 | |
57 | 55 |
58 def main(): | 56 def main(): |
59 if sys.platform == 'darwin': | 57 if sys.platform == 'darwin': |
60 # There's a bug on MacOSX that can cause Python to be confused | 58 # There's a bug on MacOSX that can cause Python to be confused |
61 # about the locale. Let's try to fix that. | 59 # about the locale. Let's try to fix that. |
133 '--pid-file', | 131 '--pid-file', |
134 dest='pid_file', | 132 dest='pid_file', |
135 help="Write a PID file for the current process.") | 133 help="Write a PID file for the current process.") |
136 | 134 |
137 | 135 |
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 | |
138 between `serve` and `bake` (or, worse, *not* re-render them all correctly | |
139 and end up serving or baking the wrong version). | |
140 """ | |
141 _command_caches = { | |
142 'serve': 'server'} | |
143 | |
144 | |
138 def _pre_parse_chef_args(argv): | 145 def _pre_parse_chef_args(argv): |
139 # 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 |
140 # 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- |
141 # related arguments must be parsed first because we want to log everything | 148 # related arguments must be parsed first because we want to log everything |
142 # from the beginning. | 149 # from the beginning. |
143 parser = argparse.ArgumentParser() | 150 parser = argparse.ArgumentParser() |
144 _setup_main_parser_arguments(parser) | 151 _setup_main_parser_arguments(parser) |
145 parser.add_argument('args', nargs=argparse.REMAINDER) | 152 parser.add_argument('extra_args', nargs=argparse.REMAINDER) |
146 res, _ = parser.parse_known_args(argv) | 153 res, _ = parser.parse_known_args(argv) |
147 | 154 |
148 # Setup the logger. | 155 # Setup the logger. |
149 if res.debug and res.quiet: | 156 if res.debug and res.quiet: |
150 raise Exception("You can't specify both --debug and --quiet.") | 157 raise Exception("You can't specify both --debug and --quiet.") |
194 raise Exception("Can't write PID file: %s" % res.pid_file) from ex | 201 raise Exception("Can't write PID file: %s" % res.pid_file) from ex |
195 | 202 |
196 return res | 203 return res |
197 | 204 |
198 | 205 |
206 def _build_cache_key(pre_args): | |
207 cache_key_str = 'default' | |
208 if pre_args.extra_args: | |
209 cmd_name = pre_args.extra_args[0] | |
210 if cmd_name in _command_caches: | |
211 cache_key_str = _command_caches[cmd_name] | |
212 if pre_args.config_variant is not None: | |
213 cache_key_str += ',variant=%s' % pre_args.config_variant | |
214 if pre_args.config_values: | |
215 for name, value in pre_args.config_values: | |
216 cache_key_str += ',%s=%s' % (name, value) | |
217 | |
218 logger.debug("Using cache key: %s" % cache_key_str) | |
219 cache_key = hashlib.md5(cache_key_str.encode('utf8')).hexdigest() | |
220 return cache_key | |
221 | |
222 | |
199 def _run_chef(pre_args, argv): | 223 def _run_chef(pre_args, argv): |
200 # Setup the app. | 224 # Setup the app. |
201 start_time = time.perf_counter() | 225 start_time = time.perf_counter() |
202 root = None | 226 root = None |
203 if pre_args.root: | 227 if pre_args.root: |
206 try: | 230 try: |
207 root = find_app_root(theme=pre_args.theme) | 231 root = find_app_root(theme=pre_args.theme) |
208 except SiteNotFoundError: | 232 except SiteNotFoundError: |
209 root = None | 233 root = None |
210 | 234 |
211 if not root: | 235 # Can't apply custom configuration stuff if there's no website. |
212 app = NullPieCrust( | 236 if (pre_args.config_variant or pre_args.config_values) and not root: |
213 theme_site=pre_args.theme) | 237 raise SiteNotFoundError( |
214 else: | 238 "Can't apply any configuration variant or value overrides, " |
239 "there is no website here.") | |
240 | |
241 if root: | |
242 cache_key = None | |
243 if not pre_args.no_cache: | |
244 cache_key = _build_cache_key(pre_args) | |
215 app = PieCrust( | 245 app = PieCrust( |
216 root, | 246 root, |
217 theme_site=pre_args.theme, | 247 theme_site=pre_args.theme, |
218 cache=(not pre_args.no_cache), | 248 cache=(not pre_args.no_cache), |
249 cache_key=cache_key, | |
219 debug=pre_args.debug) | 250 debug=pre_args.debug) |
220 | 251 apply_variant_and_values( |
221 # Build a hash for a custom cache directory. | 252 app, pre_args.config_variant, pre_args.config_values) |
222 cache_key = 'default' | 253 else: |
223 | 254 app = NullPieCrust( |
224 # Handle custom configurations. | 255 theme_site=pre_args.theme) |
225 if (pre_args.config_variant or pre_args.config_values) and not root: | |
226 raise SiteNotFoundError( | |
227 "Can't apply any configuration variant or value overrides, " | |
228 "there is no website here.") | |
229 apply_variant_and_values(app, pre_args.config_variant, | |
230 pre_args.config_values) | |
231 | |
232 # Adjust the cache key. | |
233 if pre_args.config_variant is not None: | |
234 cache_key += ',variant=%s' % pre_args.config_variant | |
235 if pre_args.config_values: | |
236 for name, value in pre_args.config_values: | |
237 cache_key += ',%s=%s' % (name, value) | |
238 | 256 |
239 # Setup the arg parser. | 257 # Setup the arg parser. |
240 parser = argparse.ArgumentParser( | 258 parser = argparse.ArgumentParser( |
241 prog='chef', | 259 prog='chef', |
242 description="The PieCrust chef manages your website.", | 260 description="The PieCrust chef manages your website.", |
268 # Print the help if no command was specified. | 286 # Print the help if no command was specified. |
269 if not hasattr(result, 'func'): | 287 if not hasattr(result, 'func'): |
270 parser.print_help() | 288 parser.print_help() |
271 return 0 | 289 return 0 |
272 | 290 |
273 # Use a customized cache for the command and current config. | |
274 if result.cache_name != 'default' or cache_key != 'default': | |
275 app.useSubCache(result.cache_name, cache_key) | |
276 | |
277 # Run the command! | 291 # Run the command! |
278 ctx = CommandContext(app, parser, result) | 292 ctx = CommandContext(app, parser, result) |
279 ctx.config_variant = pre_args.config_variant | 293 ctx.config_variant = pre_args.config_variant |
280 ctx.config_values = pre_args.config_values | 294 ctx.config_values = pre_args.config_values |
281 | 295 |