James Gardner: Home > Work > Code > TemplateGenerator > 0.1.0 > Manual

TemplateGenerator v0.1.0 documentation

Manual

TemplateGenerator generates a sinlge Python file with no dependencies which when run, will re-create that directory structure. If you tell it to look out for certain strings in directory names and file contents it can assemble the Python file in such a way that when the directory structure is re-generated, files and directories can be renamed and contents changed according to variables created by a user. It is therefore a very good tool for generating directory structure templates to allow complex directory structures to be dynamically generated from within another program.

Let’s see this in action.

Tutorial

Imagine you have an example Python package called ExamplePackage which is set up in exactly the way you’d like all your packages to be set up. You can use TempalateGenerator to scan that directory and create a single Python file.

Let’s also imagine you want the following variables (which occur either in the file content, the directory names or the filenames) to be configurable when the Python template is executed:

  • ExamplePackage
  • James Gardner

We’ll want the Python template file to be named new_pacakge.py so that when it is executed it creates a new package.

To achieve all this we need to write a script which uses TemplateGenerator to create the new_pacakge.py script. Call this script new_package_tempate_generator.py and add this content:

from templategenerator import gen_template

gen_template(
    'ExamplePackage', 
    replacements = {
        "ExamplePackage": 'PACKAGE',
        "James Gardner": 'AUTHOR_NAME',
    },
)

When the script is run it will print the Python code for the template file to the standard output so you’ll need to redirect it to the new_pacakge.py file. Make sure you have installed TemplateGenerator then run this:

$ ~/env/bin/python new_package_tempate_generator.py > new_pacakge.py

When you run this, TemplateGenerator looks in every file and directory in ExampleSite, reads any file contents to Python strings which it assings to vairiable names it creates after replacing the key identifiers you’ve chosen with their corresponding variable names. It then adds a function called render() which when called will uses the strings it has just created as the basis for the new files to create.

Here’s the contents of new_package.py now:

import os, base64

EXAMPLEPACKAGE___INIT___PY = '''\
print "This is %(PACKAGE)s, a very simple example by %(AUTHOR_NAME)s"
print "of how TemplateGenerator works!"

'''
def render(PACKAGE, AUTHOR_NAME):
    if os.path.exists("%(PACKAGE)s"%dict(PACKAGE=PACKAGE)):
        raise Exception("Directory already exists: "+"%(PACKAGE)s"%dict(PACKAGE=PACKAGE))
    os.mkdir("%(PACKAGE)s"%dict(PACKAGE=PACKAGE))
    if os.path.exists('%(PACKAGE)s/__init__.py'%dict(PACKAGE=PACKAGE)):
        raise Exception('File already exists: '+'%(PACKAGE)s/__init__.py'%dict(PACKAGE=PACKAGE))
    fp = open('%(PACKAGE)s/__init__.py'%dict(PACKAGE=PACKAGE), 'wb')
    fp.write(EXAMPLEPACKAGE___INIT___PY%dict(AUTHOR_NAME=AUTHOR_NAME, PACKAGE=PACKAGE))
    fp.close()

if __name__ == "__main__":
    render(
        PACKAGE='ExamplePackage',
        AUTHOR_NAME='James Gardner',
    )

If you rename your ExamplePackage directory to ExamplePackage.orig you can now run new_package.py without needing to install TemplateGenerator:

python new_package.py

This will re-generate the ExamplePacakge directory exactly as it was to start with. You can check like this:

diff -ur ExamplePackage.orig ExamplePackage

If there is no output they are the same.

Now let’s modify new_pacakge.py to generate a package called IansPackage and change the author to Ian Smith. Edit the final call to render() in new_package.py after if __name__ == '__main__': to look like this:

render(
    PACKAGE='IansPackage',
    AUTHOR_NAME='Ian Smith',
)

If you run this again:

python new_package.py

You’ll see a new package has been created called IansPackage.

diff -ur ExamplePackage IansPackage
--- ExamplePackage/__init__.py      2009-12-23 20:42:13.000000000 +0000
+++ IansPackage/__init__.py 2009-12-23 20:52:02.000000000 +0000
@@ -1,3 +1,3 @@
-print "This is ExamplePackage, a very simple example by James Gardner"
+print "This is IansPackage, a very simple example by Ian Smith"
 print "of how TemplateGenerator works!"

The new_package.py template file has created a directroy structure with the new variable.

Examples

If you want to try the examples from the tutorial above yourself the files are in the example directory of the source distribution. You can change the ExamplePackage directory to something more complicated to explore the functionality.

Advanced options

The gen_template() function takes a number of options to allow you to ignore certain files, handle binary files like images (it base64-encodes the ones you tell it are binary) and more. See the API docs for the options.

Who uses it?

TemplateGenerator was used to create the new_package.py and package_to_repo.py scripts in BuildKit as well as the repo_to_flows.py script in Flows.

Limitations

  • You can’t have very funny characters in paths such as $ or £
  • You can’t specify variables to replace if they form part of other variables you are replacing

Work around these limitations by manually editing the Python file with your customisations after it has been editied.

This is still Alpha software but I’m happy to accept patches.

James Gardner: Home > Work > Code > TemplateGenerator > 0.1.0 > Manual