Browse Source

Merge pull request #39 from vincentbernat/hyde

---

This new plugin allow to combine multiple files into one. Here is an
example:

```
---
combine:
    files: luffy.*.js
    where: top
---

luffy.effects();
luffy.search();
```

All luffy.*.js files will be combined and added to the top of the file.
main
Lakshmi Vyasarajan 13 years ago
parent
commit
77b9bc2ad4
6 changed files with 198 additions and 1 deletions
  1. +108
    -0
      hyde/ext/plugins/combine.py
  2. +1
    -1
      hyde/generator.py
  3. +1
    -0
      hyde/tests/ext/combine/script.1.js
  4. +1
    -0
      hyde/tests/ext/combine/script.2.js
  5. +1
    -0
      hyde/tests/ext/combine/script.3.js
  6. +86
    -0
      hyde/tests/ext/test_combine.py

+ 108
- 0
hyde/ext/plugins/combine.py View File

@@ -0,0 +1,108 @@
# -*- coding: utf-8 -*-
"""
Contains classes to combine files into one
"""

from fnmatch import fnmatch

from hyde.model import Expando
from hyde.plugin import Plugin

class CombinePlugin(Plugin):
"""
To use this combine, the following configuration should be added
to meta data::
combine:
files:
- ns1.*.js
- ns2.*.js
where: top
remove: yes

`files` is a list of resources (or just a resource) that should be
combined. Globbing is performed. `where` indicate where the
combination should be done. This could be `top` or `bottom` of the
file. `remove` tell if we should remove resources that have been
combined into the resource.
"""

def __init__(self, site):
super(CombinePlugin, self).__init__(site)

def _combined(self, resource):
"""
Return the list of resources to combine to build this one.
"""
try:
config = resource.meta.combine
except AttributeError:
return [] # Not a combined resource
try:
files = config.files
except AttributeError:
raise AttributeError("No resources to combine for [%s]" % resource)
if type(files) is str:
files = [ files ]

# Grab resources to combine
resources = []
for r in resource.node.resources:
for f in files:
if fnmatch(r.name, f):
resources.append(r)
break
if not resources:
self.logger.debug("No resources to combine for [%s]" % resource)
return []

return sorted(resources, key=lambda r: r.name)

def begin_site(self):
"""
Initialize the plugin and search for the combined resources
"""
for node in self.site.content.walk():
for resource in node.resources:
resources = self._combined(resource)
if not resources:
continue

# Build depends
if not hasattr(resource, 'depends'):
resource.depends = []
resource.depends.extend(
[r.relative_path for r in resources
if r.relative_path not in resource.depends])

# Remove combined resources if needed
if hasattr(resource.meta.combine, "remove") and \
resource.meta.combine.remove:
for r in resources:
self.logger.debug(
"Resource [%s] removed because combined" % r)
r.is_processable = False

def begin_text_resource(self, resource, text):
"""
When generating a resource, add combined file if needed.
"""
resources = self._combined(resource)
if not resources:
return

where = "bottom"
try:
where = resource.meta.combine.where
except AttributeError:
pass

if where not in [ "top", "bottom" ]:
raise ValueError("%r should be either `top` or `bottom`" % where)

self.logger.debug(
"Combining %d resources for [%s]" % (len(resources),
resource))
if where == "top":
return "".join([r.source.read_all() for r in resources] + [text])
else:
return "".join([text] + [r.source.read_all() for r in resources])

+ 1
- 1
hyde/generator.py View File

@@ -161,7 +161,7 @@ class Generator(object):
if not target.exists or target.older_than(resource.source_file):
logger.debug("Found changes in %s" % resource)
return True
if resource.source_file.is_binary or not resource.uses_template:
if resource.source_file.is_binary:
logger.debug("No Changes found in %s" % resource)
return False
deps = self.get_dependencies(resource)


+ 1
- 0
hyde/tests/ext/combine/script.1.js View File

@@ -0,0 +1 @@
var a = 1 + 2;

+ 1
- 0
hyde/tests/ext/combine/script.2.js View File

@@ -0,0 +1 @@
var b = a + 3;

+ 1
- 0
hyde/tests/ext/combine/script.3.js View File

@@ -0,0 +1 @@
var c = a + 5;

+ 86
- 0
hyde/tests/ext/test_combine.py View File

@@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
"""
Use nose
`$ pip install nose`
`$ nosetests`
"""
from hyde.fs import File, Folder
from hyde.model import Expando
from hyde.generator import Generator
from hyde.site import Site

COMBINE_SOURCE = File(__file__).parent.child_folder('combine')
TEST_SITE = File(__file__).parent.parent.child_folder('_test')


class TestCombine(object):

def setUp(self):
TEST_SITE.make()
TEST_SITE.parent.child_folder(
'sites/test_jinja').copy_contents_to(TEST_SITE)
TEST_SITE.child_folder('content/media/js').make()
COMBINE_SOURCE.copy_contents_to(TEST_SITE.child('content/media/js'))

def tearDown(self):
TEST_SITE.delete()

def _test_combine(self, content):
s = Site(TEST_SITE)
s.config.plugins = [
'hyde.ext.plugins.meta.MetaPlugin',
'hyde.ext.plugins.combine.CombinePlugin']
source = TEST_SITE.child('content/media/js/script.js')
target = File(Folder(s.config.deploy_root_path).child('media/js/script.js'))
File(source).write(content)

gen = Generator(s)
gen.generate_resource_at_path(source)

assert target.exists
text = target.read_all()
return text, s

def test_combine_top(self):
text, _ = self._test_combine("""
---
combine:
files: script.*.js
where: top
---

Last line""")
assert text == """var a = 1 + 2;
var b = a + 3;
var c = a + 5;
Last line"""
return

def test_combine_bottom(self):
text, _ = self._test_combine("""
---
combine:
files: script.*.js
where: bottom
---

First line
""")
assert text == """First line
var a = 1 + 2;
var b = a + 3;
var c = a + 5;"""
return

def test_combine_remove(self):
_, s = self._test_combine("""
---
combine:
files: script.*.js
remove: yes
---

First line""")
for i in range(1,4):
assert not File(Folder(s.config.deploy_root_path).
child('media/js/script.%d.js' % i)).exists

Loading…
Cancel
Save