# HG changeset patch # User Ludovic Chabant # Date 1408601811 25200 # Node ID 485682a6de50ea22a8dc2fd63a14b1e11d93512a # Parent e4c345dcf33c0575057d115c044f4fa0d9a6e7ab New site layout support. diff -r e4c345dcf33c -r 485682a6de50 piecrust/__init__.py --- a/piecrust/__init__.py Wed Aug 20 21:46:27 2014 -0700 +++ b/piecrust/__init__.py Wed Aug 20 23:16:51 2014 -0700 @@ -2,13 +2,13 @@ APP_VERSION = '2.0.0alpha' CACHE_DIR = '_cache' -CONTENT_DIR = '_content' -TEMPLATES_DIR = '_content/templates' -PLUGINS_DIR = '_content/plugins' -THEME_DIR = '_content/theme' +ASSETS_DIR = 'assets' +TEMPLATES_DIR = 'templates' +PLUGINS_DIR = 'plugins' +THEME_DIR = 'theme' -CONFIG_PATH = '_content/config.yml' -THEME_CONFIG_PATH = '_content/theme_config.yml' +CONFIG_PATH = 'config.yml' +THEME_CONFIG_PATH = 'theme_config.yml' DEFAULT_FORMAT = 'markdown' DEFAULT_TEMPLATE_ENGINE = 'jinja2' diff -r e4c345dcf33c -r 485682a6de50 piecrust/app.py --- a/piecrust/app.py Wed Aug 20 21:46:27 2014 -0700 +++ b/piecrust/app.py Wed Aug 20 23:16:51 2014 -0700 @@ -7,7 +7,7 @@ import yaml from werkzeug.utils import cached_property from piecrust import (APP_VERSION, - CACHE_DIR, TEMPLATES_DIR, + CACHE_DIR, TEMPLATES_DIR, ASSETS_DIR, PLUGINS_DIR, THEME_DIR, CONFIG_PATH, THEME_CONFIG_PATH, DEFAULT_FORMAT, DEFAULT_TEMPLATE_ENGINE, DEFAULT_POSTS_FS, @@ -24,7 +24,7 @@ logger = logging.getLogger(__name__) -CACHE_VERSION = 11 +CACHE_VERSION = 12 class VariantNotFoundError(Exception): @@ -392,11 +392,24 @@ return config @cached_property + def assets_dirs(self): + assets_dirs = self._get_configurable_dirs(ASSETS_DIR, + 'site/assets_dirs') + + # Also add the theme directory, if any. + if self.theme_dir: + default_theme_dir = os.path.join(self.theme_dir, ASSETS_DIR) + if os.path.isdir(default_theme_dir): + assets_dirs.append(default_theme_dir) + + return assets_dirs + + @cached_property def templates_dirs(self): templates_dirs = self._get_configurable_dirs(TEMPLATES_DIR, 'site/templates_dirs') - # Also, add the theme directory, if nay. + # Also, add the theme directory, if any. if self.theme_dir: default_theme_dir = os.path.join(self.theme_dir, TEMPLATES_DIR) if os.path.isdir(default_theme_dir): diff -r e4c345dcf33c -r 485682a6de50 piecrust/baking/baker.py --- a/piecrust/baking/baker.py Wed Aug 20 21:46:27 2014 -0700 +++ b/piecrust/baking/baker.py Wed Aug 20 23:16:51 2014 -0700 @@ -409,11 +409,12 @@ self._waitOnWorkerPool(pool, abort) def _bakeAssets(self, record): + mounts = self.app.assets_dirs baker_params = self.app.config.get('baker') or {} skip_patterns = baker_params.get('skip_patterns') force_patterns = baker_params.get('force_patterns') proc = ProcessorPipeline( - self.app, self.out_dir, force=self.force, + self.app, mounts, self.out_dir, force=self.force, skip_patterns=skip_patterns, force_patterns=force_patterns, num_workers=self.num_workers) proc.run() diff -r e4c345dcf33c -r 485682a6de50 piecrust/pathutil.py --- a/piecrust/pathutil.py Wed Aug 20 21:46:27 2014 -0700 +++ b/piecrust/pathutil.py Wed Aug 20 23:16:51 2014 -0700 @@ -8,14 +8,14 @@ root = os.getcwd() Exception.__init__(self, "No PieCrust website in '%s' " - "('_content/config.yml' not found!)." % root) + "('config.yml' not found!)." % root) def find_app_root(cwd=None): if cwd is None: cwd = os.getcwd() - while not os.path.isfile(os.path.join(cwd, '_content', 'config.yml')): + while not os.path.isfile(os.path.join(cwd, 'config.yml')): cwd = os.path.dirname(cwd) if not cwd or cwd == '/': return None diff -r e4c345dcf33c -r 485682a6de50 piecrust/processing/base.py --- a/piecrust/processing/base.py Wed Aug 20 21:46:27 2014 -0700 +++ b/piecrust/processing/base.py Wed Aug 20 23:16:51 2014 -0700 @@ -98,14 +98,11 @@ def __init__(self): super(ProcessorPipelineRecord, self).__init__() - self.is_multi_mount = False def addEntry(self, item): self.entries.append(item) def hasOverrideEntry(self, rel_path): - if not self.is_multi_mount: - return False return self.findEntry(rel_path) is not None def findEntry(self, rel_path): @@ -133,9 +130,10 @@ class ProcessorPipeline(object): - def __init__(self, app, out_dir, force=False, mounts=None, + def __init__(self, app, mounts, out_dir, force=False, skip_patterns=None, force_patterns=None, num_workers=4): self.app = app + self.mounts = mounts tmp_dir = app.cache_dir if not tmp_dir: import tempfile @@ -143,16 +141,12 @@ self.tmp_dir = os.path.join(tmp_dir, 'proc') self.out_dir = out_dir self.force = force - self.mounts = mounts or {} self.skip_patterns = skip_patterns or [] self.force_patterns = force_patterns or [] self.processors = app.plugin_loader.getProcessors() self.num_workers = num_workers - if app.theme_dir is not None: - self.mounts['theme'] = app.theme_dir - - self.skip_patterns += ['_cache', '_content', '_counter', + self.skip_patterns += ['_cache', '_counter', 'theme_info.yml', '.DS_Store', 'Thumbs.db', '.git*', '.hg*', '.svn'] @@ -186,11 +180,15 @@ if src_dir_or_file is not None: # Process only the given path. - # Find out if this source directory is in a mount point. - base_dir = self.app.root_dir - for name, path in self.mounts.items(): + # Find out what mount point this is in. + for path in self.mounts: if src_dir_or_file[:len(path)] == path: base_dir = path + break + else: + raise Exception("Input path '%s' is not part of any known " + "mount point: %s" % + (src_dir_or_file, self.mounts)) ctx = ProcessingContext(base_dir, queue, record) logger.debug("Initiating processing pipeline on: %s" % src_dir_or_file) @@ -201,14 +199,10 @@ else: # Process everything. - ctx = ProcessingContext(self.app.root_dir, queue, record) - logger.debug("Initiating processing pipeline on: %s" % self.app.root_dir) - self.processDirectory(ctx, self.app.root_dir) - ctx.is_multi_mount = True - for name, path in self.mounts.items(): - mount_ctx = ProcessingContext(path, queue, record) + for path in self.mounts: + ctx = ProcessingContext(path, queue, record) logger.debug("Initiating processing pipeline on: %s" % path) - self.processDirectory(mount_ctx, path) + self.processDirectory(ctx, path) # Wait on all workers. for w in pool: diff -r e4c345dcf33c -r 485682a6de50 piecrust/resources/theme/_content/pages/_category.html --- a/piecrust/resources/theme/_content/pages/_category.html Wed Aug 20 21:46:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ ---- -title: -format: none ---- -

Posts in {{ category }}

- -
- {% for post in pagination.posts %} - {% include 'partial_post.html' %} - {% endfor %} -
-
- {% if pagination.prev_page %}{% endif %} - {% if pagination.next_page %}{% endif %} -
- diff -r e4c345dcf33c -r 485682a6de50 piecrust/resources/theme/_content/pages/_index.html --- a/piecrust/resources/theme/_content/pages/_index.html Wed Aug 20 21:46:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ ---- -title: -format: none ---- - -{% if pagination.has_posts %} -
- {% for post in pagination.posts %} - {% include 'partial_post.html' %} - {% endfor %} -
-
- {% if pagination.prev_page %}{% endif %} - {% if pagination.next_page %}{% endif %} -
-{% endif %} - - -<--markdown--> - -{% if not pagination.has_posts or not site.hide_quickstart %} - -## Quick Start - -Welcome to your new [PieCrust][] website! - -Since you don't seem to have any blog post or home page created yet, here's a -quick reference of things you probably want to do next. All `chef` commands need -to be run from inside your website's directory. - -For more information, refer to the [documentation][doc]. - - -### Create a new blog post - -Run `chef prepare post my-new-post-slug`, where `my-new-post-slug` is the [URL slug][slug] you want for your new post. - - -### Change this page - -To override this default home page, you can do one of the following: - -* Just hide this "quick start" section by setting the `hide_quickstart` property - to `true` in your site configuration. To do this, edit `_content/config.yml` - and `hide_quickstart: true` under the `site` section. - -* Manually rewrite this page by creating `_content/pages/_index.md` or running - `chef prepare page _index`. - -* Install a theme with `chef themes install theme-name`, where `theme-name` is - the name of a theme. You can list existing official themes with `chef themes - find`. - - -[piecrust]: {{ piecrust.url }} -[doc]: http://bolt80.com/piecrust/doc/ -[slug]: http://en.wikipedia.org/wiki/Clean_URL#Slug -{% endif %} - diff -r e4c345dcf33c -r 485682a6de50 piecrust/resources/theme/_content/pages/_tag.html --- a/piecrust/resources/theme/_content/pages/_tag.html Wed Aug 20 21:46:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ ---- -title: -format: none ---- -

Posts tagged with {{ tag }}

- -
- {% for post in pagination.posts %} - {% include 'partial_post.html' %} - {% endfor %} -
-
- {% if pagination.prev_page %}{% endif %} - {% if pagination.next_page %}{% endif %} -
- diff -r e4c345dcf33c -r 485682a6de50 piecrust/resources/theme/_content/templates/default.html --- a/piecrust/resources/theme/_content/templates/default.html Wed Aug 20 21:46:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ - - - - - - - {{ site.title }}{% if page.title %} — {{ page.title }}{% endif %} - {% if site.css %} - - {% else %} - - {% endif %} - - -
-
- {% block header %} - {% if page.title %} -

{{ site.title }}

- {% else %} -

{{ site.title }}

- {% endif %} - {% endblock %} -
-
- {% block main %} - {% if page.title %} -

{{ page.title }}

- {% endif %} - - {{ content|raw }} - {% endblock %} -
-
- {% block footer %} - {% endblock %} - {{ piecrust.debug_info|raw }} -

{{ piecrust.branding|raw }}

-
-
- - diff -r e4c345dcf33c -r 485682a6de50 piecrust/resources/theme/_content/templates/partial_post.html --- a/piecrust/resources/theme/_content/templates/partial_post.html Wed Aug 20 21:46:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -
-
-

{{ post.title }}

- {{ post.date }} - {% if post.tags %} - in - {% for t in post.tags %} - {{ t }}{% if not loop.last %}, {% endif %} - {% endfor %} - {% endif %} - {% if post.category %} - | {{ post.category }} - {% endif %} - -
-
- {{ post.content|raw }} -
-
diff -r e4c345dcf33c -r 485682a6de50 piecrust/resources/theme/_content/templates/post.html --- a/piecrust/resources/theme/_content/templates/post.html Wed Aug 20 21:46:27 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -{% extends "default.html" %} - diff -r e4c345dcf33c -r 485682a6de50 piecrust/resources/theme/_content/theme_config.yml diff -r e4c345dcf33c -r 485682a6de50 piecrust/resources/theme/pages/_category.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/piecrust/resources/theme/pages/_category.html Wed Aug 20 23:16:51 2014 -0700 @@ -0,0 +1,16 @@ +--- +title: +format: none +--- +

Posts in {{ category }}

+ +
+ {% for post in pagination.posts %} + {% include 'partial_post.html' %} + {% endfor %} +
+
+ {% if pagination.prev_page %}{% endif %} + {% if pagination.next_page %}{% endif %} +
+ diff -r e4c345dcf33c -r 485682a6de50 piecrust/resources/theme/pages/_index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/piecrust/resources/theme/pages/_index.html Wed Aug 20 23:16:51 2014 -0700 @@ -0,0 +1,59 @@ +--- +title: +format: none +--- + +{% if pagination.has_posts %} +
+ {% for post in pagination.posts %} + {% include 'partial_post.html' %} + {% endfor %} +
+
+ {% if pagination.prev_page %}{% endif %} + {% if pagination.next_page %}{% endif %} +
+{% endif %} + + +<--markdown--> + +{% if not pagination.has_posts or not site.hide_quickstart %} + +## Quick Start + +Welcome to your new [PieCrust][] website! + +Since you don't seem to have any blog post or home page created yet, here's a +quick reference of things you probably want to do next. All `chef` commands need +to be run from inside your website's directory. + +For more information, refer to the [documentation][doc]. + + +### Create a new blog post + +Run `chef prepare post my-new-post-slug`, where `my-new-post-slug` is the [URL slug][slug] you want for your new post. + + +### Change this page + +To override this default home page, you can do one of the following: + +* Just hide this "quick start" section by setting the `hide_quickstart` property + to `true` in your site configuration. To do this, edit `_content/config.yml` + and `hide_quickstart: true` under the `site` section. + +* Manually rewrite this page by creating `_content/pages/_index.md` or running + `chef prepare page _index`. + +* Install a theme with `chef themes install theme-name`, where `theme-name` is + the name of a theme. You can list existing official themes with `chef themes + find`. + + +[piecrust]: {{ piecrust.url }} +[doc]: http://bolt80.com/piecrust/doc/ +[slug]: http://en.wikipedia.org/wiki/Clean_URL#Slug +{% endif %} + diff -r e4c345dcf33c -r 485682a6de50 piecrust/resources/theme/pages/_tag.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/piecrust/resources/theme/pages/_tag.html Wed Aug 20 23:16:51 2014 -0700 @@ -0,0 +1,16 @@ +--- +title: +format: none +--- +

Posts tagged with {{ tag }}

+ +
+ {% for post in pagination.posts %} + {% include 'partial_post.html' %} + {% endfor %} +
+
+ {% if pagination.prev_page %}{% endif %} + {% if pagination.next_page %}{% endif %} +
+ diff -r e4c345dcf33c -r 485682a6de50 piecrust/resources/theme/templates/default.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/piecrust/resources/theme/templates/default.html Wed Aug 20 23:16:51 2014 -0700 @@ -0,0 +1,89 @@ + + + + + + + {{ site.title }}{% if page.title %} — {{ page.title }}{% endif %} + {% if site.css %} + + {% else %} + + {% endif %} + + +
+
+ {% block header %} + {% if page.title %} +

{{ site.title }}

+ {% else %} +

{{ site.title }}

+ {% endif %} + {% endblock %} +
+
+ {% block main %} + {% if page.title %} +

{{ page.title }}

+ {% endif %} + + {{ content|raw }} + {% endblock %} +
+
+ {% block footer %} + {% endblock %} + {{ piecrust.debug_info|raw }} +

{{ piecrust.branding|raw }}

+
+
+ + diff -r e4c345dcf33c -r 485682a6de50 piecrust/resources/theme/templates/partial_post.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/piecrust/resources/theme/templates/partial_post.html Wed Aug 20 23:16:51 2014 -0700 @@ -0,0 +1,19 @@ +
+
+

{{ post.title }}

+ {{ post.date }} + {% if post.tags %} + in + {% for t in post.tags %} + {{ t }}{% if not loop.last %}, {% endif %} + {% endfor %} + {% endif %} + {% if post.category %} + | {{ post.category }} + {% endif %} + +
+
+ {{ post.content|raw }} +
+
diff -r e4c345dcf33c -r 485682a6de50 piecrust/resources/theme/templates/post.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/piecrust/resources/theme/templates/post.html Wed Aug 20 23:16:51 2014 -0700 @@ -0,0 +1,2 @@ +{% extends "default.html" %} + diff -r e4c345dcf33c -r 485682a6de50 piecrust/resources/theme/theme_config.yml diff -r e4c345dcf33c -r 485682a6de50 piecrust/sources/base.py --- a/piecrust/sources/base.py Wed Aug 20 21:46:27 2014 -0700 +++ b/piecrust/sources/base.py Wed Aug 20 23:16:51 2014 -0700 @@ -3,7 +3,6 @@ import os.path import logging from werkzeug.utils import cached_property -from piecrust import CONTENT_DIR from piecrust.configuration import ConfigurationError from piecrust.data.base import IPaginationSource, PaginationData from piecrust.data.filters import PaginationFilter @@ -292,7 +291,7 @@ def __init__(self, app, name, config): super(SimplePageSource, self).__init__(app, name, config) self.fs_endpoint = config.get('fs_endpoint', name) - self.fs_endpoint_path = os.path.join(self.root_dir, CONTENT_DIR, self.fs_endpoint) + self.fs_endpoint_path = os.path.join(self.root_dir, self.fs_endpoint) self.supported_extensions = list(app.config.get('site/auto_formats').keys()) self.default_auto_format = app.config.get('site/default_auto_format') diff -r e4c345dcf33c -r 485682a6de50 piecrust/sources/posts.py --- a/piecrust/sources/posts.py Wed Aug 20 21:46:27 2014 -0700 +++ b/piecrust/sources/posts.py Wed Aug 20 23:16:51 2014 -0700 @@ -4,7 +4,6 @@ import glob import logging import datetime -from piecrust import CONTENT_DIR from piecrust.sources.base import (PageSource, IPreparingSource, SimplePaginationSourceMixin, PageNotFoundError, InvalidFileSystemEndpointError, @@ -20,7 +19,7 @@ def __init__(self, app, name, config): super(PostsSource, self).__init__(app, name, config) self.fs_endpoint = config.get('fs_endpoint', name) - self.fs_endpoint_path = os.path.join(self.root_dir, CONTENT_DIR, self.fs_endpoint) + self.fs_endpoint_path = os.path.join(self.root_dir, self.fs_endpoint) self.supported_extensions = list(app.config.get('site/auto_formats').keys()) self.default_auto_format = app.config.get('site/default_auto_format') diff -r e4c345dcf33c -r 485682a6de50 tests/mockutil.py --- a/tests/mockutil.py Wed Aug 20 21:46:27 2014 -0700 +++ b/tests/mockutil.py Wed Aug 20 23:16:51 2014 -0700 @@ -37,7 +37,7 @@ self._fs = {self._root: {}} if default_spec: self.withDir('counter') - self.withFile('kitchen/_content/config.yml', + self.withFile('kitchen/config.yml', "site:\n title: Mock Website\n") def path(self, p): @@ -72,12 +72,12 @@ def withConfig(self, config): return self.withFile( - 'kitchen/_content/config.yml', + 'kitchen/config.yml', yaml.dump(config)) def withThemeConfig(self, config): return self.withFile( - 'kitchen/_content/theme/_content/theme_config.yml', + 'kitchen/theme/theme_config.yml', yaml.dump(config)) def withPage(self, url, config=None, contents=None): @@ -92,13 +92,13 @@ if not ext: url += '.md' url = url.lstrip('/') - return self.withAsset('_content/' + url, text) + return self.withAsset(url, text) def withPageAsset(self, page_url, name, contents=None): contents = contents or "A test asset." url_base, ext = os.path.splitext(page_url) dirname = url_base + '-assets' - return self.withAsset('_content/%s/%s' % (dirname, name), + return self.withAsset('%s/%s' % (dirname, name), contents) def getStructure(self, path=None): diff -r e4c345dcf33c -r 485682a6de50 tests/test_data_assetor.py --- a/tests/test_data_assetor.py Wed Aug 20 21:46:27 2014 -0700 +++ b/tests/test_data_assetor.py Wed Aug 20 23:16:51 2014 -0700 @@ -22,7 +22,7 @@ page = MagicMock() page.app = fs.getApp() page.app.env.base_asset_url_format = '%uri%' - page.path = fs.path('/kitchen/_content/pages/foo/bar.md') + page.path = fs.path('/kitchen/pages/foo/bar.md') assetor = Assetor(page, '/foo/bar') for en in expected.keys(): assert hasattr(assetor, en) @@ -37,7 +37,7 @@ with mock_fs_scope(fs): page = MagicMock() page.app = fs.getApp() - page.path = fs.path('/kitchen/_content/pages/foo/bar.md') + page.path = fs.path('/kitchen/pages/foo/bar.md') assetor = Assetor(page, '/foo/bar') assetor['this_doesnt_exist'] @@ -51,7 +51,7 @@ with mock_fs_scope(fs): page = MagicMock() page.app = fs.getApp() - page.path = fs.path('/kitchen/_content/pages/foo/bar.md') + page.path = fs.path('/kitchen/pages/foo/bar.md') assetor = Assetor(page, '/foo/bar') assetor['one'] diff -r e4c345dcf33c -r 485682a6de50 tests/test_processing_base.py --- a/tests/test_processing_base.py Wed Aug 20 21:46:27 2014 -0700 +++ b/tests/test_processing_base.py Wed Aug 20 23:16:51 2014 -0700 @@ -1,12 +1,16 @@ +import os.path import pytest from piecrust.processing.base import ProcessorPipeline from .mockutil import mock_fs, mock_fs_scope def _get_pipeline(fs, **kwargs): - return ProcessorPipeline(fs.getApp(), fs.path('counter'), + app = fs.getApp() + mounts = [os.path.join(app.root_dir, 'assets')] + return ProcessorPipeline(app, mounts, fs.path('counter'), num_workers=1, **kwargs) + def test_empty(): fs = mock_fs() with mock_fs_scope(fs): @@ -21,7 +25,7 @@ def test_one_file(): fs = (mock_fs() - .withFile('kitchen/something.html', 'A test file.')) + .withFile('kitchen/assets/something.html', 'A test file.')) with mock_fs_scope(fs): pp = _get_pipeline(fs) pp.filterProcessors(['copy']) @@ -43,9 +47,9 @@ ]) def test_skip_pattern(patterns, expected): fs = (mock_fs() - .withFile('kitchen/something.html', 'A test file.') - .withFile('kitchen/_hidden.html', 'Shhh') - .withFile('kitchen/foo/_important.html', 'Important!')) + .withFile('kitchen/assets/something.html', 'A test file.') + .withFile('kitchen/assets/_hidden.html', 'Shhh') + .withFile('kitchen/assets/foo/_important.html', 'Important!')) with mock_fs_scope(fs): pp = _get_pipeline(fs, skip_patterns=['/^_/']) pp.filterProcessors(['copy']) diff -r e4c345dcf33c -r 485682a6de50 tests/test_sources_base.py --- a/tests/test_sources_base.py Wed Aug 20 21:46:27 2014 -0700 +++ b/tests/test_sources_base.py Wed Aug 20 23:16:51 2014 -0700 @@ -29,7 +29,7 @@ {'url': '/%path%', 'source': 'test'}] } }) - fs.withDir('kitchen/_content/test') + fs.withDir('kitchen/test') with mock_fs_scope(fs): app = PieCrust(fs.path('kitchen'), cache=False) s = app.getSource('test') @@ -42,8 +42,8 @@ @pytest.mark.parametrize('ref_path, expected', [ - ('foo.html', '/kitchen/_content/test/foo.html'), - ('foo/bar.html', '/kitchen/_content/test/foo/bar.html'), + ('foo.html', '/kitchen/test/foo.html'), + ('foo/bar.html', '/kitchen/test/foo/bar.html'), ]) def test_default_source_resolve_ref(ref_path, expected): fs = mock_fs()