[Checkins] SVN: hurry.resource/trunk/src/hurry/resource/ Helper code for generating code for resources.
Martijn Faassen
faassen at infrae.com
Wed Sep 24 12:50:16 EDT 2008
Log message for revision 91446:
Helper code for generating code for resources.
Changed:
U hurry.resource/trunk/src/hurry/resource/README.txt
U hurry.resource/trunk/src/hurry/resource/__init__.py
U hurry.resource/trunk/src/hurry/resource/core.py
-=-
Modified: hurry.resource/trunk/src/hurry/resource/README.txt
===================================================================
--- hurry.resource/trunk/src/hurry/resource/README.txt 2008-09-24 16:06:44 UTC (rev 91445)
+++ hurry.resource/trunk/src/hurry/resource/README.txt 2008-09-24 16:50:15 UTC (rev 91446)
@@ -452,6 +452,35 @@
<script type="text/javascript" src="http://localhost/static/foo/a.js"></script>
<script type="text/javascript" src="http://localhost/static/foo/c.js"></script>
+Generating resource code
+------------------------
+
+Sometimes it is useful to generate code that expresses a complex
+resource dependency structure. One example of that is in
+``hurry.yui``. We can use this to render a list of resources::
+
+ >>> from hurry.resource import generate_code
+ >>> print generate_code([a1, a2, a3, a4, a5])
+ from hurry.resource import Library, ResourceInclusion
+ <BLANKLINE>
+ foo = Library('foo')
+ <BLANKLINE>
+ a1 = ResourceInclusion(foo, 'a1.js')
+ a2 = ResourceInclusion(foo, 'a2.js', depends=[a1])
+ a3 = ResourceInclusion(foo, 'a3.js', depends=[a2])
+ a4 = ResourceInclusion(foo, 'a4.js', depends=[a1])
+ a5 = ResourceInclusion(foo, 'a5.js', depends=[a4, a3])
+
+Let's look at an example with modes and rollups::
+
+ >>> print generate_code([b4, b5])
+ from hurry.resource import Library, ResourceInclusion
+ <BLANKLINE>
+ foo = Library('foo')
+ <BLANKLINE>
+ b4 = ResourceInclusion(foo, 'b4.js', rollups=['giant.js'], debug=ResourceInclusion(foo, 'b4-debug.js', rollups=['giant-debug.js']))
+ b5 = ResourceInclusion(foo, 'b5.js', rollups=['giant.js'], debug=ResourceInclusion(foo, 'b5-debug.js', rollups=['giant-debug.js']))
+
Sorting inclusions by dependency
--------------------------------
Modified: hurry.resource/trunk/src/hurry/resource/__init__.py
===================================================================
--- hurry.resource/trunk/src/hurry/resource/__init__.py 2008-09-24 16:06:44 UTC (rev 91445)
+++ hurry.resource/trunk/src/hurry/resource/__init__.py 2008-09-24 16:50:15 UTC (rev 91446)
@@ -1,2 +1,3 @@
from hurry.resource.core import (Library, ResourceInclusion, NeededInclusions,
- sort_inclusions_topological)
+ sort_inclusions_topological,
+ generate_code)
Modified: hurry.resource/trunk/src/hurry/resource/core.py
===================================================================
--- hurry.resource/trunk/src/hurry/resource/core.py 2008-09-24 16:06:44 UTC (rev 91445)
+++ hurry.resource/trunk/src/hurry/resource/core.py 2008-09-24 16:50:15 UTC (rev 91446)
@@ -45,14 +45,14 @@
self.library = library
self.relpath = relpath
+ assert not isinstance(depends, basestring)
+ depends = depends or []
+ self.depends = normalize_inclusions(library, depends)
+
assert not isinstance(rollups, basestring)
rollups = rollups or []
self.rollups = normalize_inclusions(library, rollups)
- assert not isinstance(depends, basestring)
- depends = depends or []
- self.depends = normalize_inclusions(library, depends)
-
normalized_modes = {}
for mode_name, inclusion in kw.items():
normalized_modes[mode_name] = normalize_inclusion(
@@ -233,3 +233,91 @@
"Unknown resource extension %s for resource inclusion: %s" %
(inclusion.ext(), repr(inclusion)))
return renderer(url)
+
+def generate_code(inclusions):
+ # libraries with the same name are the same libraries
+ libraries = {}
+ for inclusion in inclusions:
+ libraries[inclusion.library.name] = inclusion.library
+ libraries = sorted(libraries.values())
+
+ result = []
+ # import on top
+ result.append("from hurry.resource import Library, ResourceInclusion")
+ result.append("")
+ # define libraries
+ for library in libraries:
+ result.append("%s = Library('%s')" % (library.name, library.name))
+ result.append("")
+
+ # figure out inclusion names, try to base on filename
+ used_names = set()
+ inclusion_to_name = {}
+ inclusions = sort_inclusions_by_extension(
+ sort_inclusions_topological(inclusions))
+ for inclusion in inclusions:
+ name = generate_inclusion_name(inclusion, used_names)
+ inclusion_to_name[inclusion.key()] = name
+
+ # now generate inclusion code
+ for inclusion in inclusions:
+ s = "%s = ResourceInclusion(%s, '%s'" % (
+ inclusion_to_name[inclusion.key()],
+ inclusion.library.name,
+ inclusion.relpath)
+ if inclusion.depends:
+ depends_s = ', depends=[%s]' % ', '.join(
+ [inclusion_to_name[d.key()] for d in inclusion.depends])
+ s += depends_s
+ if inclusion.rollups:
+ s += ', ' + _generate_inline_rollups(inclusion)
+ if inclusion.modes:
+ items = []
+ for mode_name, mode in inclusion.modes.items():
+ items.append((mode_name,
+ generate_inline_inclusion(mode, inclusion)))
+ items = sorted(items)
+ modes_s = ', %s' % ', '.join(["%s=%s" % (name, mode) for
+ (name, mode) in items])
+ s += modes_s
+ s += ')'
+ result.append(s)
+ return '\n'.join(result)
+
+def generate_inline_inclusion(inclusion, associated_inclusion):
+ if (inclusion.library.name == associated_inclusion.library.name and
+ not inclusion.rollups):
+ return "'%s'" % inclusion.relpath
+ else:
+ s = "ResourceInclusion(%s, '%s'" % (inclusion.library.name,
+ inclusion.relpath)
+ if inclusion.rollups:
+ s += ', ' + _generate_inline_rollups(inclusion)
+ s += ')'
+ return s
+
+def _generate_inline_rollups(inclusion):
+ return 'rollups=[%s]' % ', '.join(
+ [generate_inline_inclusion(r, inclusion)
+ for r in inclusion.rollups])
+
+def generate_inclusion_name(inclusion, used_names):
+ rest, fullname = os.path.split(inclusion.relpath)
+ name, ext = os.path.splitext(fullname)
+ if name not in used_names:
+ used_names.add(name)
+ return name
+ name = name + ext
+ name = name.replace('.', '_')
+ if name not in used_names:
+ used_names.add(name)
+ return name
+ i = 0
+ while True:
+ name = name + str(i)
+ if name not in used_names:
+ used_names.add(name)
+ return name
+ assert False, "Not possible to generate a unique name!"
+
+
More information about the Checkins
mailing list