Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: cms/sources.py

Issue 29555839: Issue 5336 - Allow additional include, page, and template paths using CMS (Closed)
Patch Set: Address comments on PS2, improve docstring of create_source Created Sept. 28, 2017, 9 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cms/bin/test_server.py ('k') | tests/__init__.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # This file is part of the Adblock Plus web scripts, 1 # This file is part of the Adblock Plus web scripts,
2 # Copyright (C) 2006-present eyeo GmbH 2 # Copyright (C) 2006-present eyeo GmbH
3 # 3 #
4 # Adblock Plus is free software: you can redistribute it and/or modify 4 # Adblock Plus is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License version 3 as 5 # it under the terms of the GNU General Public License version 3 as
6 # published by the Free Software Foundation. 6 # published by the Free Software Foundation.
7 # 7 #
8 # Adblock Plus is distributed in the hope that it will be useful, 8 # Adblock Plus is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 path = os.path.join(dir, filename) 296 path = os.path.join(dir, filename)
297 if os.path.isfile(path): 297 if os.path.isfile(path):
298 result.append(relpath + filename) 298 result.append(relpath + filename)
299 elif os.path.isdir(path): 299 elif os.path.isdir(path):
300 do_list(path, relpath + filename + '/') 300 do_list(path, relpath + filename + '/')
301 do_list(self.get_path(subdir), '') 301 do_list(self.get_path(subdir), '')
302 return result 302 return result
303 303
304 def get_cache_dir(self): 304 def get_cache_dir(self):
305 return os.path.join(self._dir, 'cache') 305 return os.path.join(self._dir, 'cache')
306
307
308 class MultiSource(Source):
309 """A source that combines the contents of multiple other sources."""
310
311 def __init__(self, base_sources):
312 self._bases = base_sources
313
314 @property
315 def version(self):
316 return self._bases[0].version
317
318 def get_cache_dir(self):
319 return self._bases[0].get_cache_dir()
320
321 def __enter__(self):
322 for base in self._bases:
323 base.__enter__()
324 return self
325
326 def __exit__(self, exc_type, exc_value, tb):
327 return any(base.__exit__(exc_type, exc_value, tb)
328 for base in self._bases)
329
330 def close(self):
331 for base in self._bases:
332 base.close()
333
334 def has_file(self, filename):
335 return any(base.has_file(filename) for base in self._bases)
336
337 def read_file(self, filename, binary=False):
338 for base in self._bases:
339 if base.has_file(filename):
340 return base.read_file(filename, binary)
341 raise KeyError('File not found {}'.format(filename))
342
343 def list_files(self, subdir):
344 return {f for base in self._bases for f in base.list_files(subdir)}
345
346
347 def _memoize(func):
348 """Cache results of functions calls."""
349 memoized = {}
350
351 def wrapper(*args):
352 try:
353 return memoized[args]
354 except KeyError:
355 return memoized.setdefault(args, func(*args))
356 wrapper.cache_clear = memoized.clear
357 return wrapper
358
359
360 def create_source(path, static=False, revision='default'):
Wladimir Palant 2017/09/29 08:50:44 The default revision should be 'master', not 'defa
Vasily Kuznetsov 2017/09/29 10:49:09 Changed to `None`, following your next comment. Do
361 """Create a source from path and optional revision.
362
363 `static` flag indicates that the website source under `path` can be assumed
364 to not change after the source was created and any changes can be safely
365 ignored.
366 - If `static` is `True`, no interim changes are expected and caching will
367 be used to optimize performance (source directory is also assumed to be a
368 Mercurial repository, and `revision` parameter can be used to select a
369 source revision from which the files will be read).
370 - If `static` is `False`, changes on the filesystem are expected and will
371 be reflected in the outputs of the calls. This mode can be used for live
372 preview.
373
374 If `settings.ini` in the source contains `[paths]` section with an
375 `additional-paths` key that contains the list of additional root folders,
376 `MultiSource` will be instantiated and its bases will be the original
377 source plus an additional source for each additional root folder.
378 `MultiSource` looks up files in its base sources in the order they are
379 provided, so the files in the additional folders will only be used if the
380 original source doesn't contain that file.
381 """
382 if static:
Wladimir Palant 2017/09/29 08:50:44 Should this flag really determine which type of so
Vasily Kuznetsov 2017/09/29 10:49:10 Yeah, you're right. `static` parameter should cont
383 source = MercurialSource(path, revision)
384 else:
385 source = FileSource(path)
386
387 config = source.read_config()
388 try:
389 ap = config.get('paths', 'additional-paths').strip()
390 additional_paths = filter(None, ap.split())
391 except ConfigParser.NoSectionError:
Wladimir Palant 2017/09/29 08:50:44 What about NoOptionError?
Vasily Kuznetsov 2017/09/29 10:49:09 Thank you. Done.
392 additional_paths = []
393
394 if additional_paths:
395 additional_sources = [
396 create_source(os.path.join(path, p))
Sebastian Noack 2017/09/28 20:48:21 This seems to be equivalent to FileSource(os.path.
Wladimir Palant 2017/09/29 08:50:44 Not quite equivalent. The directory we link to mig
Vasily Kuznetsov 2017/09/29 10:49:09 Yes, nested dependencies are the reason why I made
Sebastian Noack 2017/09/29 15:55:07 I agree with Wladimir. His suggestion seems to be
397 for p in additional_paths
398 ]
399 source = MultiSource([source] + additional_sources)
400
401 if static:
402 for fname in [
403 'resolve_link',
404 'read_config',
405 'read_template',
406 'read_locale',
407 'read_include',
408 'exec_file',
409 ]:
410 setattr(source, fname, _memoize(getattr(source, fname)))
411
412 return source
OLDNEW
« no previous file with comments | « cms/bin/test_server.py ('k') | tests/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld