Commit 776b21d6 authored by Vincent Pelletier's avatar Vincent Pelletier

recipe.template.jinja2: Add render-once support.

To be used for zope's inituser file, for example.
parent dbb27169
......@@ -116,6 +116,9 @@ Optional:
Mode, in octal representation (no need for 0-prefix) to set output file to.
This is applied before storing anything in output file.
``once``
Path of a marker file to prevents rendering altogether.
``extensions``
Jinja2 extensions to enable when rendering the template,
whitespace-separated. By default, none is loaded.
......@@ -525,3 +528,62 @@ Let's just use ``buildout.cfg`` using this egg::
>>> cat('foo')
foobar
Avoiding file re-creation
~~~~~~~~~~~~~~~~~~~~~~~~~
Normally, each time the section is installed/updated the file gets
re-generated. This may be undesirable in some cases.
``once`` allows specifying a marker file, which when present prevents template
rendering.
>>> import os
>>> write('buildout.cfg',
... '''
... [buildout]
... parts = template
...
... [template]
... recipe = slapos.recipe.template:jinja2
... template = inline:dummy
... rendered = foo_once
... once = foo_flag
... ''')
>>> print system(join('bin', 'buildout')),
Uninstalling template.
Installing template.
Template was rendered::
>>> cat('foo_once')
dummy
And canary exists::
>>> os.path.exists('foo_flag')
True
Remove rendered file and re-render::
>>> import os
>>> os.unlink('foo_once')
>>> open('buildout.cfg', 'a').writelines(['extra = useless'])
>>> print system(join('bin', 'buildout')),
Uninstalling template.
Installing template.
Template was not rendered::
>>> os.path.exists('foo_once')
False
Removing the canary allows template to be re-rendered::
>>> os.unlink('foo_flag')
>>> open('buildout.cfg', 'a').writelines(['moreextra = still useless'])
>>> print system(join('bin', 'buildout')),
Uninstalling template.
Installing template.
>>> cat('foo_once')
dummy
......@@ -209,8 +209,11 @@ class Recipe(object):
self.template = env.template_class.from_code(env,
env.compile(source, filename=template),
env.make_globals(None), None)
self.once = options.get('once')
def install(self):
if self.once and os.path.exists(self.once):
return
# Unlink any existing file, so umask is always applied.
try:
os.unlink(self.rendered)
......@@ -228,6 +231,9 @@ class Recipe(object):
self.mode), 'w') as out:
out.write(self.template.render(**self.context)
.encode(self.encoding))
if self.once:
open(self.once, 'w').close()
return
return self.rendered
update = install
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment