@@ -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 | Version 0.8.5a7 | ||||
============================================================ | ============================================================ | ||||
* Bug Fix: Relative path was used in the server as the sitepath (Issue #119) | * 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** | A brand new **hyde** | ||||
==================== | ==================== | ||||
@@ -314,7 +314,13 @@ class Generator(object): | |||||
return | return | ||||
logger.debug("Processing [%s]", resource) | logger.debug("Processing [%s]", resource) | ||||
with self.context_for_resource(resource) as context: | 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) | self.update_deps(resource) | ||||
if resource.uses_template: | if resource.uses_template: | ||||
logger.debug("Rendering [%s]", resource) | logger.debug("Rendering [%s]", resource) | ||||
@@ -331,16 +337,10 @@ class Generator(object): | |||||
text = self.events.text_resource_complete( | text = self.events.text_resource_complete( | ||||
resource, text) or text | resource, text) or text | ||||
target = File(self.site.config.deploy_root_path.child( | |||||
resource.relative_deploy_path)) | |||||
target.parent.make() | |||||
target.write(text) | target.write(text) | ||||
copymode(resource.source_file.path, target.path) | copymode(resource.source_file.path, target.path) | ||||
else: | else: | ||||
logger.debug("Copying binary file [%s]", resource) | logger.debug("Copying binary file [%s]", resource) | ||||
self.events.begin_binary_resource(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) | 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): | def __init__(self, sitepath, config_file=None, config_dict=None): | ||||
self.default_config = dict( | self.default_config = dict( | ||||
mode='production', | mode='production', | ||||
simple_copy = [], | |||||
content_root='content', | content_root='content', | ||||
deploy_root='deploy', | deploy_root='deploy', | ||||
media_root='media', | media_root='media', | ||||
@@ -67,6 +67,7 @@ class Resource(Processable): | |||||
self.node = node | self.node = node | ||||
self.site = node.site | self.site = node.site | ||||
self._relative_deploy_path = None | self._relative_deploy_path = None | ||||
self.simple_copy = False | |||||
@property | @property | ||||
def relative_path(self): | def relative_path(self): | ||||
@@ -333,7 +334,9 @@ class RootNode(Node): | |||||
resource = node.add_child_resource(afile) | resource = node.add_child_resource(afile) | ||||
self.resource_map[unicode(afile)] = resource | self.resource_map[unicode(afile)] = resource | ||||
relative_path = resource.relative_path | 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]" % | logger.debug("Added resource [%s] to [%s]" % | ||||
(resource.relative_path, self.source_folder)) | (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') | blog_node = s.content.node_from_relative_path('blog') | ||||
assert not blog_node | assert not blog_node | ||||
git_node = s.content.node_from_relative_path('.git') | 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 | Handles hyde version | ||||
TODO: Use fabric like versioning scheme | TODO: Use fabric like versioning scheme | ||||
""" | """ | ||||
__version__ = '0.8.5a7' | |||||
__version__ = '0.8.5a8' |