Buildout recipe to generate a text file from a template
Project description
Introduction
This recipe can be used to generate textfiles from a (text) template.
Starting with version 1.3 you can also specify a path to the output file and the path will be created, if it does not exist.
A short example:
[buildout] parts = zope.conf [message] recipe = collective.recipe.template input = templates/message.in output = ${buildout:parts-directory}/etc/message mymessage = Hello, World!
In the template you can use the exact same variables as you can use in the buildout configuration. For example an input file can look like this:
My top level directory is ${buildout:directory} Executables are stored in ${buildout:bin-directory}
As an extension to the buildout syntax you can reference variables from the current buildout part directly. For example:
My message is: ${mymessage}
Why another template recipe?
Both iw.recipe.template and inquant.recipe.textfile claim to do the same thing. I have found them to be undocumented and too buggy for real world use, and neither are in a public repository where I could fix them. In addition this implementation leverages the buildout variable substitution code, making it a lot simpler.
Detailed Description
Simple creation of a file out of a template
Lets create a minimal buildout.cfg file:
>>> write('buildout.cfg', ... ''' ... [buildout] ... parts = template ... offline = true ... ... [template] ... recipe = collective.recipe.template ... input = template.in ... output = template ... ''')
We create a template file:
>>> write('template.in', ... '''# ... My template knows about buildout path: ... ${buildout:directory} ... ''')
Now we can run buildout:
>>> print system(join('bin', 'buildout')), Installing template.
The template was indeed created:
>>> cat('template') # My template knows about buildout path: .../sample-buildout
The variable buildout:directory was also substituted by a path.
Using inline input
For very short script it can make sense to put the source directly into buildout.cfg:
>>> write('buildout.cfg', ... ''' ... [buildout] ... parts = template ... offline = true ... ... [template] ... recipe = collective.recipe.template ... input = inline: ... #!/bin/bash ... echo foo ... output = ${buildout:parts-directory}/template ... ''')
Now we can run buildout:
>>> print system(join('bin', 'buildout')), Uninstalling template. Installing template.
The template should have been created:
>>> cat('parts', 'template') #!/bin/bash echo foo
Normally the file mode gets copied from the template, but it can also be specified manually, which especially makes sense in this case:
>>> write('buildout.cfg', ... ''' ... [buildout] ... parts = template ... offline = true ... ... [template] ... recipe = collective.recipe.template ... input = inline: ... #!/bin/bash ... echo foo ... output = ${buildout:parts-directory}/template ... mode = 493 ... ''')
Run buildout again
>>> print system(join('bin', 'buildout')), Uninstalling template. Installing template.
The template should have the specified file mode:
>>> from os import stat >>> from stat import S_IMODE >>> S_IMODE(stat('parts/template').st_mode) 493
Creating a template in a variable path
Lets create a minimal buildout.cfg file. This time the output should happen in a variable path:
>>> write('buildout.cfg', ... ''' ... [buildout] ... parts = template ... offline = true ... ... [template] ... recipe = collective.recipe.template ... input = template.in ... output = ${buildout:parts-directory}/template ... ''')
Now we can run buildout:
>>> print system(join('bin', 'buildout')), Uninstalling template. Installing template.
The template was indeed created:
>>> cat('parts', 'template') # My template knows about buildout path: .../sample-buildout
Creating missing paths
If an output file should be created in a path that does not yet exist, then the missing items will be created for us:
>>> write('buildout.cfg', ... ''' ... [buildout] ... parts = template ... offline = true ... ... [template] ... recipe = collective.recipe.template ... input = template.in ... output = ${buildout:parts-directory}/etc/template ... ''') >>> print system(join('bin', 'buildout')), Uninstalling template. Installing template.
Also creation of several subdirectories is supported:
>>> write('buildout.cfg', ... ''' ... [buildout] ... parts = template ... offline = true ... ... [template] ... recipe = collective.recipe.template ... input = template.in ... output = ${buildout:parts-directory}/foo/bar/template ... ''') >>> print system(join('bin', 'buildout')), Uninstalling template. Installing template. >>> cat('parts', 'foo', 'bar', 'template') # My template knows about buildout path: .../sample-buildout
When changes happen to the output path, then the old path is removed on uninstall. Therefore the etc/ directory created above has vanished now:
>>> ls('parts') d foo
Substituting variables with options of other parts
When substituting variables in a template, dependencies on other buildout parts can occur. Buildout will resolve them by determining the values of those other parts’ options first. To see this, we create a buildout involving a template that uses a variable computed by a part that would not otherwise be built:
>>> write('dummy.py', ... ''' ... class Recipe(object): ... ... def __init__(self, buildout, name, options): ... options['foo'] = 'bar' ... ... def install(self): ... return () ... ... def update(self): ... pass ... ''')>>> write('setup.py', ... ''' ... from setuptools import setup ... ... setup(name='dummyrecipe', ... entry_points = {'zc.buildout': ['default = dummy:Recipe']}) ... ''')>>> write('buildout.cfg', ... ''' ... [buildout] ... develop = . ... parts = template ... offline = true ... ... [template] ... recipe = collective.recipe.template ... input = template.in ... output = template ... ... [other] ... recipe = dummyrecipe ... ''')>>> write('template.in', ... '''# ... My template knows about another buildout part: ... ${other:foo} ... ''')>>> print system(join('bin', 'buildout')), Develop: '/sample-buildout/.' Uninstalling template. Installing other. Installing template.>>> cat('template') # My template knows about another buildout part: bar
Changelog
1.5 - 2010-02-23
Add support for explicitly setting the output file mode. [witsch]
Add support for inline templates. [witsch]
1.4 - 2009-07-29
Fixed the way variables in templates are substituted to allow buildout to determine dependencies on other parts and prepare those correctly. [tlotze]
1.3 - 2009-04-28
Add support for output path creation. You can do:
output = /path/to/target
and intermediate path items will be created if they do not exist. [ulif]
Add tests. [ulif]
1.2 - 2008-12-09
(By accident the 1.1 release was marked as 1.2. So in fact they are the same.)
1.1 - 2008-12-09
Correct handling of multiple variables in a line. Bugreport and patch from Roman Susi. [wichert]
1.0 - 2008-10-16
Copy the mode of the input file to the output file. This makes it possible to create executable scripts. [wichert]
Add missing link in README. [wichert]
1.0rc2 - 2008-07-04
Add a MANIFEST.in with instructions to include docs/, otherwise the package will not install. [wichert]
1.0rc1 - 2008-07-04
Initial release. [wichert]
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Hashes for collective.recipe.template-1.5.zip
Algorithm | Hash digest | |
---|---|---|
SHA256 | d44f94a066460aa0407344c956332db8b27f8338d9cd7281588988f21d29b299 |
|
MD5 | a2e5ee5a6386690629a253fe00485f1a |
|
BLAKE2b-256 | 13aae1954bcd20d4ad49b92ff681d90ae9d14f7fb03e92ea4279a933145fb225 |