| @@ -1,3 +1,9 @@ | |||
| Version 0.8.5a8 | |||
| ============================================================ | |||
| * Added `simple_copy` feature to account for unprocessable files that | |||
| are nonetheless required to be deployed (Issue #121) | |||
| Version 0.8.5a7 | |||
| ============================================================ | |||
| * Bug Fix: Relative path was used in the server as the sitepath (Issue #119) | |||
| @@ -1,4 +1,4 @@ | |||
| Version 0.8.5a7 | |||
| Version 0.8.5a8 | |||
| A brand new **hyde** | |||
| ==================== | |||
| @@ -314,7 +314,13 @@ class Generator(object): | |||
| return | |||
| logger.debug("Processing [%s]", resource) | |||
| with self.context_for_resource(resource) as context: | |||
| if resource.source_file.is_text: | |||
| target = File(self.site.config.deploy_root_path.child( | |||
| resource.relative_deploy_path)) | |||
| target.parent.make() | |||
| if resource.simple_copy: | |||
| logger.debug("Simply Copying [%s]", resource) | |||
| resource.source_file.copy_to(target) | |||
| elif resource.source_file.is_text: | |||
| self.update_deps(resource) | |||
| if resource.uses_template: | |||
| logger.debug("Rendering [%s]", resource) | |||
| @@ -331,16 +337,10 @@ class Generator(object): | |||
| text = self.events.text_resource_complete( | |||
| resource, text) or text | |||
| target = File(self.site.config.deploy_root_path.child( | |||
| resource.relative_deploy_path)) | |||
| target.parent.make() | |||
| target.write(text) | |||
| copymode(resource.source_file.path, target.path) | |||
| else: | |||
| logger.debug("Copying binary file [%s]", resource) | |||
| self.events.begin_binary_resource(resource) | |||
| target = File(self.site.config.deploy_root_path.child( | |||
| resource.relative_deploy_path)) | |||
| target.parent.make() | |||
| resource.source_file.copy_to(target) | |||
| self.events.binary_resource_complete(resource) | |||
| self.events.binary_resource_complete(resource) | |||
| @@ -142,6 +142,7 @@ class Config(Expando): | |||
| def __init__(self, sitepath, config_file=None, config_dict=None): | |||
| self.default_config = dict( | |||
| mode='production', | |||
| simple_copy = [], | |||
| content_root='content', | |||
| deploy_root='deploy', | |||
| media_root='media', | |||
| @@ -67,6 +67,7 @@ class Resource(Processable): | |||
| self.node = node | |||
| self.site = node.site | |||
| self._relative_deploy_path = None | |||
| self.simple_copy = False | |||
| @property | |||
| def relative_path(self): | |||
| @@ -333,7 +334,9 @@ class RootNode(Node): | |||
| resource = node.add_child_resource(afile) | |||
| self.resource_map[unicode(afile)] = resource | |||
| relative_path = resource.relative_path | |||
| resource.simple_copy = any(fnmatch.fnmatch(relative_path, pattern) for pattern in self.site.config.simple_copy) | |||
| resource.simple_copy = any(fnmatch.fnmatch(relative_path, pattern) | |||
| for pattern | |||
| in self.site.config.simple_copy) | |||
| logger.debug("Added resource [%s] to [%s]" % | |||
| (resource.relative_path, self.source_folder)) | |||
| @@ -0,0 +1,139 @@ | |||
| # -*- coding: utf-8 -*- | |||
| """ | |||
| Tests the simple copy feature. | |||
| In order to mark some files to simply be copied to the | |||
| destination without any processing what so ever add this | |||
| to the config (site.yaml for example): | |||
| simple_copy: | |||
| - media/css/*.css | |||
| - media/js/*.js | |||
| - **/*.js | |||
| Matching is done with `fnmatch` module. So any `glob` that fnmatch | |||
| can process is a valid pattern. | |||
| Use nose | |||
| `$ pip install nose` | |||
| `$ nosetests` | |||
| """ | |||
| import yaml | |||
| from urllib import quote | |||
| from hyde.fs import File, Folder | |||
| from hyde.model import Config, Expando | |||
| from hyde.site import Node, RootNode, Site | |||
| from hyde.generator import Generator | |||
| from nose.tools import raises, with_setup, nottest | |||
| TEST_SITE_ROOT = File(__file__).parent.child_folder('sites/test_jinja') | |||
| class TestSimpleCopy(object): | |||
| @classmethod | |||
| def setup_class(cls): | |||
| cls.SITE_PATH = File(__file__).parent.child_folder('sites/test_jinja_with_config') | |||
| cls.SITE_PATH.make() | |||
| TEST_SITE_ROOT.copy_contents_to(cls.SITE_PATH) | |||
| @classmethod | |||
| def teardown_class(cls): | |||
| cls.SITE_PATH.delete() | |||
| @nottest | |||
| def setup_config(self, passthru): | |||
| self.config_file = File(self.SITE_PATH.child('site.yaml')) | |||
| with open(self.config_file.path) as config: | |||
| conf = yaml.load(config) | |||
| conf['simple_copy'] = passthru | |||
| self.config = Config(sitepath=self.SITE_PATH, config_dict=conf) | |||
| def test_simple_copy_basic(self): | |||
| self.setup_config([ | |||
| 'about.html' | |||
| ]) | |||
| s = Site(self.SITE_PATH, config=self.config) | |||
| s.load() | |||
| res = s.content.resource_from_relative_path('about.html') | |||
| assert res | |||
| assert res.simple_copy | |||
| def test_simple_copy_directory(self): | |||
| self.setup_config([ | |||
| '**/*.html' | |||
| ]) | |||
| s = Site(self.SITE_PATH, config=self.config) | |||
| s.load() | |||
| res = s.content.resource_from_relative_path('about.html') | |||
| assert res | |||
| assert not res.simple_copy | |||
| res = s.content.resource_from_relative_path('blog/2010/december/merry-christmas.html') | |||
| assert res | |||
| assert res.simple_copy | |||
| def test_simple_copy_multiple(self): | |||
| self.setup_config([ | |||
| '**/*.html', | |||
| 'media/css/*.css' | |||
| ]) | |||
| s = Site(self.SITE_PATH, config=self.config) | |||
| s.load() | |||
| res = s.content.resource_from_relative_path('about.html') | |||
| assert res | |||
| assert not res.simple_copy | |||
| res = s.content.resource_from_relative_path('blog/2010/december/merry-christmas.html') | |||
| assert res | |||
| assert res.simple_copy | |||
| res = s.content.resource_from_relative_path('media/css/site.css') | |||
| assert res | |||
| assert res.simple_copy | |||
| def test_generator(self): | |||
| self.setup_config([ | |||
| '**/*.html', | |||
| 'media/css/*.css' | |||
| ]) | |||
| s = Site(self.SITE_PATH, self.config) | |||
| g = Generator(s) | |||
| g.generate_all() | |||
| source = s.content.resource_from_relative_path('blog/2010/december/merry-christmas.html') | |||
| target = File(s.config.deploy_root_path.child(source.relative_deploy_path)) | |||
| left = source.source_file.read_all() | |||
| right = target.read_all() | |||
| assert left == right | |||
| def test_plugins(self): | |||
| text = """ | |||
| --- | |||
| title: Hey | |||
| author: Me | |||
| twitter: @me | |||
| --- | |||
| {%% extends "base.html" %%} | |||
| {%% block main %%} | |||
| Hi! | |||
| I am a test template to make sure jinja2 generation works well with hyde. | |||
| <span class="title">{{resource.meta.title}}</span> | |||
| <span class="author">{{resource.meta.author}}</span> | |||
| <span class="twitter">{{resource.meta.twitter}}</span> | |||
| {%% endblock %%} | |||
| """ | |||
| index = File(self.SITE_PATH.child('content/blog/index.html')) | |||
| index.write(text) | |||
| self.setup_config([ | |||
| '**/*.html', | |||
| 'media/css/*.css' | |||
| ]) | |||
| conf = {'plugins': ['hyde.ext.plugins.meta.MetaPlugin']} | |||
| conf.update(self.config.to_dict()) | |||
| s = Site(self.SITE_PATH, Config(sitepath=self.SITE_PATH, config_dict=conf)) | |||
| g = Generator(s) | |||
| g.generate_all() | |||
| source = s.content.resource_from_relative_path('blog/index.html') | |||
| target = File(s.config.deploy_root_path.child(source.relative_deploy_path)) | |||
| left = source.source_file.read_all() | |||
| right = target.read_all() | |||
| assert left == right | |||
| @@ -276,63 +276,4 @@ class TestSiteWithConfig(object): | |||
| blog_node = s.content.node_from_relative_path('blog') | |||
| assert not blog_node | |||
| git_node = s.content.node_from_relative_path('.git') | |||
| assert not git_node | |||
| class TestSimpleCopy(object): | |||
| @classmethod | |||
| def setup_class(cls): | |||
| cls.SITE_PATH = File(__file__).parent.child_folder('sites/test_jinja_with_config') | |||
| cls.SITE_PATH.make() | |||
| TEST_SITE_ROOT.copy_contents_to(cls.SITE_PATH) | |||
| @classmethod | |||
| def teardown_class(cls): | |||
| cls.SITE_PATH.delete() | |||
| @nottest | |||
| def setup_config(self, passthru): | |||
| self.config_file = File(self.SITE_PATH.child('site.yaml')) | |||
| with open(self.config_file.path) as config: | |||
| conf = yaml.load(config) | |||
| conf['simple_copy'] = passthru | |||
| self.config = Config(sitepath=self.SITE_PATH, config_dict=conf) | |||
| def test_simple_copy_basic(self): | |||
| self.setup_config([ | |||
| 'about.html' | |||
| ]) | |||
| s = Site(self.SITE_PATH, config=self.config) | |||
| s.load() | |||
| res = s.content.resource_from_relative_path('about.html') | |||
| assert res | |||
| assert res.simple_copy | |||
| def test_simple_copy_directory(self): | |||
| self.setup_config([ | |||
| '**/*.html' | |||
| ]) | |||
| s = Site(self.SITE_PATH, config=self.config) | |||
| s.load() | |||
| res = s.content.resource_from_relative_path('about.html') | |||
| assert res | |||
| assert not res.simple_copy | |||
| res = s.content.resource_from_relative_path('blog/2010/december/merry-christmas.html') | |||
| assert res | |||
| assert res.simple_copy | |||
| def test_simple_copy_multiple(self): | |||
| self.setup_config([ | |||
| '**/*.html', | |||
| 'media/css/*.css' | |||
| ]) | |||
| s = Site(self.SITE_PATH, config=self.config) | |||
| s.load() | |||
| res = s.content.resource_from_relative_path('about.html') | |||
| assert res | |||
| assert not res.simple_copy | |||
| res = s.content.resource_from_relative_path('blog/2010/december/merry-christmas.html') | |||
| assert res | |||
| assert res.simple_copy | |||
| res = s.content.resource_from_relative_path('media/css/site.css') | |||
| assert res | |||
| assert res.simple_copy | |||
| assert not git_node | |||
| @@ -3,4 +3,4 @@ | |||
| Handles hyde version | |||
| TODO: Use fabric like versioning scheme | |||
| """ | |||
| __version__ = '0.8.5a7' | |||
| __version__ = '0.8.5a8' | |||