comparison piecrust/processing/pipeline.py @ 570:7dabfdd056a1

serve: Fix corner cases where the pipeline doesn't run correctly. * When `chef serve` is run before the `assets` folder is created, monitor that folder suddenly appearing and rebuild the pipeline. * Do the same when the `config.yml` file has changed.
author Ludovic Chabant <ludovic@chabant.com>
date Sat, 31 Oct 2015 00:03:32 -0700
parents 7453baeb0839
children 3ceeca7bb71c
comparison
equal deleted inserted replaced
569:34e57d4b97e2 570:7dabfdd056a1
37 if not tmp_dir: 37 if not tmp_dir:
38 import tempfile 38 import tempfile
39 tmp_dir = os.path.join(tempfile.gettempdir(), 'piecrust') 39 tmp_dir = os.path.join(tempfile.gettempdir(), 'piecrust')
40 self.tmp_dir = os.path.join(tmp_dir, 'proc') 40 self.tmp_dir = os.path.join(tmp_dir, 'proc')
41 41
42 baker_params = app.config.get('baker') or {} 42 baker_params = app.config.get('baker', {})
43 43
44 assets_dirs = baker_params.get('assets_dirs', app.assets_dirs) 44 mount_params = baker_params.get('assets_dirs', {})
45 self.mounts = make_mount_infos(assets_dirs, self.app.root_dir) 45 self.mounts = make_mount_infos(app, mount_params)
46 46
47 self.num_workers = baker_params.get( 47 self.num_workers = baker_params.get(
48 'workers', multiprocessing.cpu_count()) 48 'workers', multiprocessing.cpu_count())
49 49
50 ignores = baker_params.get('ignore', []) 50 ignores = baker_params.get('ignore', [])
191 191
192 def _process(self, src_dir_or_file, record, jobs): 192 def _process(self, src_dir_or_file, record, jobs):
193 if src_dir_or_file is not None: 193 if src_dir_or_file is not None:
194 # Process only the given path. 194 # Process only the given path.
195 # Find out what mount point this is in. 195 # Find out what mount point this is in.
196 for name, info in self.mounts.items(): 196 for path, info in self.mounts.items():
197 path = info['path']
198 if src_dir_or_file[:len(path)] == path: 197 if src_dir_or_file[:len(path)] == path:
199 base_dir = path 198 base_dir = path
200 mount_info = info 199 mount_info = info
201 break 200 break
202 else: 201 else:
203 known_roots = [i['path'] for i in self.mounts.values()] 202 known_roots = list(self.mounts.keys())
204 raise Exception("Input path '%s' is not part of any known " 203 raise Exception("Input path '%s' is not part of any known "
205 "mount point: %s" % 204 "mount point: %s" %
206 (src_dir_or_file, known_roots)) 205 (src_dir_or_file, known_roots))
207 206
208 ctx = _ProcessingContext(jobs, record, base_dir, mount_info) 207 ctx = _ProcessingContext(jobs, record, base_dir, mount_info)
213 elif os.path.isfile(src_dir_or_file): 212 elif os.path.isfile(src_dir_or_file):
214 self._processFile(ctx, src_dir_or_file) 213 self._processFile(ctx, src_dir_or_file)
215 214
216 else: 215 else:
217 # Process everything. 216 # Process everything.
218 for name, info in self.mounts.items(): 217 for path, info in self.mounts.items():
219 path = info['path']
220 ctx = _ProcessingContext(jobs, record, path, info) 218 ctx = _ProcessingContext(jobs, record, path, info)
221 logger.debug("Initiating processing pipeline on: %s" % path) 219 logger.debug("Initiating processing pipeline on: %s" % path)
222 self._processDirectory(ctx, path) 220 self._processDirectory(ctx, path)
223 221
224 def _processDirectory(self, ctx, start_dir): 222 def _processDirectory(self, ctx, start_dir):
265 worker_class=ProcessingWorker, 263 worker_class=ProcessingWorker,
266 initargs=(ctx,)) 264 initargs=(ctx,))
267 return pool 265 return pool
268 266
269 267
270 def make_mount_infos(mounts, root_dir): 268 def make_mount_infos(app, mount_params):
271 if isinstance(mounts, list): 269 mounts = {d: {} for d in app.assets_dirs}
272 mounts = {m: {} for m in mounts} 270
273 271 for name, cfg in mount_params.items():
274 for name, info in mounts.items(): 272 mdir = os.path.join(app.root_dir, name)
275 if not isinstance(info, dict): 273 mounts[mdir] = cfg
276 raise Exception("Asset directory info for '%s' is not a " 274
277 "dictionary." % name) 275 for mdir, info in mounts.items():
276 mname = os.path.basename(mdir)
277 info_from_config = mount_params.get(mname)
278 if info_from_config is not None:
279 if not isinstance(info, dict):
280 raise Exception("Asset directory info for '%s' is not a "
281 "dictionary." % mname)
282 info.update(info_from_config)
278 info.setdefault('processors', 'all -uglifyjs -cleancss') 283 info.setdefault('processors', 'all -uglifyjs -cleancss')
279 info['path'] = os.path.join(root_dir, name) 284 info['name'] = mname
280 285
281 return mounts 286 return mounts
282 287
283 288
284 def make_re(patterns): 289 def make_re(patterns):