[Checkins] SVN: Sandbox/ulif/z3c.recipe.textfile/z3c/ import sources.

Uli Fouquet uli at gnufix.de
Wed Feb 4 08:29:48 EST 2009


Log message for revision 96077:
  import sources.

Changed:
  A   Sandbox/ulif/z3c.recipe.textfile/z3c/
  A   Sandbox/ulif/z3c.recipe.textfile/z3c/__init__.py
  A   Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/
  A   Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/__init__.py
  A   Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/
  A   Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/README.txt
  A   Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/__init__.py
  A   Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/tests/
  A   Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/tests/__init__.py
  A   Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/tests/test_docs.py

-=-
Added: Sandbox/ulif/z3c.recipe.textfile/z3c/__init__.py
===================================================================
--- Sandbox/ulif/z3c.recipe.textfile/z3c/__init__.py	                        (rev 0)
+++ Sandbox/ulif/z3c.recipe.textfile/z3c/__init__.py	2009-02-04 13:29:48 UTC (rev 96077)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)

Added: Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/__init__.py
===================================================================
--- Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/__init__.py	                        (rev 0)
+++ Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/__init__.py	2009-02-04 13:29:48 UTC (rev 96077)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)

Added: Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/README.txt
===================================================================
--- Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/README.txt	                        (rev 0)
+++ Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/README.txt	2009-02-04 13:29:48 UTC (rev 96077)
@@ -0,0 +1,280 @@
+
+Supported options
+=================
+
+The recipe supports the following options:
+
+path
+    The directory, where the generated text files should be
+    placed. Default is the local buildout directory.
+
+<file.name>
+    A textfile to create. Creates a file named ``file.name`` with the
+    option's value as content. Substitutions like
+    ${buildout:directory} are performed in the resulting file.
+
+    To make this happen, the filename must contain a dot and must not
+    end with ``-template``.
+
+    If you define a ``<file.name>`` option, you must not define a
+    ``<file.name>-template`` option.
+
+<file.name>-template 
+    A path to a template. 
+
+    Instead of passing the contents of the file to create as option
+    value, you can also name a template file. 
+
+    Substitutions like ${buildout:directory} are performed in the
+    resulting file.
+
+    This would result in a file ``file.name`` created in the ``path``
+    directory with (substituted) contents read from the template file
+    specified by this option.
+
+You can specify as many ``<file.name>`` and ``<file.name>-template``
+options as you like.
+
+
+Example usage
+=============
+
+Specifying a file to create
+---------------------------
+
+We start by creating a buildout that uses the recipe::
+
+    >>> write('buildout.cfg',
+    ... """
+    ... [buildout]
+    ... parts = conffiles
+    ...
+    ... [conffiles]
+    ... recipe = z3c.recipe.textfile
+    ... myconf.txt = Hello from myconf.txt
+    ... """)
+
+By setting an option ``myconf.txt`` we indicate, that we want to
+create a file ``myconf.txt`` with contents ``Hello from myconf.txt``.
+
+Running the buildout gives us::
+
+    >>> print 'start', system(buildout) # doctest:+ELLIPSIS
+    start...
+    Installing conffiles.
+    conffiles: Creating file myconf.txt
+
+We now have a file ``myconf.txt``::
+
+    >>> ls('.')
+    -  .installed.cfg
+    ...
+    -  myconf.txt
+    ...
+
+The freshly created file indeed provides the contents given above::
+
+    >>> cat('myconf.txt')
+    Hello from myconf.txt
+
+
+Specifying where textfiles should be created
+--------------------------------------------
+
+By default files are created in the local buildout root.
+
+When we give a ``path``-option in our ``buildout.cfg``, the file will
+be created in this location::
+
+    >>> write('buildout.cfg',
+    ... """
+    ... [buildout]
+    ... parts = conffiles
+    ...
+    ... [conffiles]
+    ... recipe = z3c.recipe.textfile
+    ... path = etc
+    ... myconf.txt = Hello from myconf.txt
+    ... """)
+
+    >>> print 'start', system(buildout) # doctest:+ELLIPSIS
+    start...
+    Installing conffiles.
+    conffiles: Creating directory etc
+    conffiles: Creating file myconf.txt
+
+Now also the ``etc/`` directory was created for us::
+
+    >>> ls('etc')
+    -  myconf.txt
+
+The contents of the text file is still the same::
+
+    >>> cat('etc', 'myconf.txt')
+    Hello from myconf.txt
+
+
+Substitutions in generated text files
+-------------------------------------
+
+To make real use of automatically generated text files you can use
+substitutions, so that variables from other recipes can be filled in::
+
+    >>> write('buildout.cfg',
+    ... """
+    ... [buildout]
+    ... parts = conffiles
+    ...
+    ... [conffiles]
+    ... recipe = z3c.recipe.textfile
+    ... myconf.txt = project_root: ${buildout:directory}
+    ... """)
+
+    >>> print 'start', system(buildout) # doctest:+ELLIPSIS
+    start...
+    Installing conffiles.
+    conffiles: Creating file myconf.txt
+
+The term ``${buildout:directory}`` above will be substituted by the
+real path of our buildout environment::
+
+    >>> cat('myconf.txt')
+    project_root: .../sample-buildout
+
+You can use any option that is referencable for buildout. Also options
+defined in our ``[conffiles]`` section (which can be named as you
+like), can be used::
+
+    >>> write('buildout.cfg',
+    ... """
+    ... [buildout]
+    ... parts = conffiles
+    ...
+    ... [conffiles]
+    ... recipe = z3c.recipe.textfile
+    ... somekey = someValue
+    ... myconf.txt = project_root: ${buildout:directory}
+    ...              important_val: ${conffiles:somekey}
+    ... """)
+
+    >>> print 'start', system(buildout) # doctest:+ELLIPSIS
+    start...
+    Installing conffiles.
+    conffiles: Creating file myconf.txt
+
+    >>> cat('myconf.txt')
+    project_root: /sample-buildout
+    important_val: someValue
+
+There will happen no other substitutions than replacing buildout-vars.
+
+This can be handy when using external template files.
+
+
+Using template files
+--------------------
+
+Instead of giving the contents of files to be created directly in
+``buildout.cfg``, you can also create template files, which are parsed
+on buildout runs, references substituted and then written to the
+created files.
+
+We create a template file, this time like an .ini-file::
+
+    >>> write('myconf_template',
+    ... """
+    ... [project_root]
+    ... ${buildout:directory}
+    ...
+    ... [sources]
+    ... ${buildout:directory}/src
+    ...
+    ... """)
+
+If we want a file ``myconf.ini`` to be created out of this template,
+we have to use the syntax ``<file.name>-template``, where
+``<file.name>`` is an arbitrary filename containing at least a dot::
+
+    >>> write('buildout.cfg',
+    ... """
+    ... [buildout]
+    ... parts = conffiles
+    ...
+    ... [conffiles]
+    ... recipe = z3c.recipe.textfile
+    ... somekey = someValue
+    ... myconf.ini-template = myconf_template
+    ... """)
+
+    >>> print 'start', system(buildout) # doctest:+ELLIPSIS
+    start...
+    Installing conffiles.
+    conffiles: Creating file myconf.ini
+
+    >>> cat('myconf.ini')
+    <BLANKLINE>
+    [project_root]
+    /sample-buildout
+    <BLANKLINE>
+    [sources]
+    /sample-buildout/src
+    <BLANKLINE>
+
+
+There is only one way to pass a text file's content
+---------------------------------------------------
+
+If we give two options which would both concern the same file to be
+generated, the recipe refuses to guess.
+
+Here we request to create a file ``myconf.ini`` two times. This is not
+allowed::
+
+    >>> write('buildout.cfg',
+    ... """
+    ... [buildout]
+    ... parts = conffiles
+    ...
+    ... [conffiles]
+    ... recipe = z3c.recipe.textfile
+    ... myconf.ini-template = myconf_template
+    ... myconf.ini = The file contents
+    ... """)
+
+    >>> print system(buildout) # doctest:+ELLIPSIS
+    conffiles: You cannot use both, `myconf.ini` and
+               `myconf.ini-template` in the same recipe.
+    While:
+      Installing.
+      Getting section conffiles.
+      Initializing part conffiles.
+    Error: Duplicate file content definition
+
+
+Template files must exist
+-------------------------
+
+This is obvious. If we name a not existing template file path, this
+won't work::
+
+    >>> write('buildout.cfg',
+    ... """
+    ... [buildout]
+    ... parts = conffiles
+    ...
+    ... [conffiles]
+    ... recipe = z3c.recipe.textfile
+    ... myconf.ini-template = not_existing_template
+    ... """)
+
+    >>> print system(buildout) # doctest:+ELLIPSIS
+    conffiles: No such template file: not_existing_template
+    While:
+      Installing.
+      Getting section conffiles.
+      Initializing part conffiles.
+    Error: No such template file: not_existing_template
+
+
+    >>> # ls('.')
+    >>> cat('.installed.cfg')

Added: Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/__init__.py
===================================================================
--- Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/__init__.py	                        (rev 0)
+++ Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/__init__.py	2009-02-04 13:29:48 UTC (rev 96077)
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+"""Recipe recipe"""
+
+import logging, os, zc.buildout
+
+class Recipe(object):
+    """zc.buildout recipe"""
+
+    def __init__(self, buildout, name, options):
+        self.buildout, self.name, self.options = buildout, name, options
+
+        # Normalize paths and check that their parent
+        # directories exist:
+        paths = []
+        if options.get('path') is None:
+            options['path'] = ''
+        for path in options['path'].split():
+            path = os.path.join(buildout['buildout']['directory'], path)
+            if not os.path.isdir(os.path.dirname(path)):
+                logging.getLogger(self.name).error(
+                    'Cannot create %s. %s is not a directory.',
+                    options['path'], os.path.dirname(options['path']))
+                raise zc.buildout.UserError('Invalid Path')
+            paths.append(path)
+        options['path'] = ' '.join(paths)
+        for filename in self.options.keys():
+            if not '.' in filename:
+                continue
+            if filename.endswith('-template'):
+                non_template_option = filename.rsplit('-', 2)[0]
+                if non_template_option in self.options.keys():
+                    logging.getLogger(self.name).error(
+                        'You cannot use both, `%s` and `%s` in '
+                        'the same recipe.' % (
+                            non_template_option, filename))
+                    raise zc.buildout.UserError(
+                        'Duplicate file content definition')
+                
+
+                # Read file contents from template...
+                template = self.options[filename]
+                if not os.path.exists(template):
+                    logging.getLogger(self.name).error(
+                        'No such template file: %s' %
+                        template)
+                    raise zc.buildout.UserError(
+                        'No such template file: %s' %template )
+
+        
+    def install(self):
+        """Installer"""
+        paths = self.options['path'].split()
+        for path in paths:
+            logging.getLogger(self.name).info(
+                'Creating directory %s', os.path.basename(path))
+            os.mkdir(path)
+        self.options.created(paths)
+        for filename in self.options.keys():
+            if not '.' in filename:
+                continue
+            if filename.endswith('-template'):
+                # Read file contents from template...
+                template = self.options[filename]
+                filename = filename.rsplit('-', 2)[0]
+                if not os.path.exists(template):
+                    logging.getLogger(self.name).error(
+                        'No such template file: %s' %
+                        template)
+                    raise zc.buildout.UserError(
+                        'No such template file: %s' %template )
+                logging.getLogger(self.name).info(
+                    'Creating file %s', filename)
+                raw = open(template, 'rb').read()
+                try:
+                    content = self.options._sub(raw, None)
+                except:
+                    pass
+
+                self.writeFile(self.options['path'], filename,
+                               content)
+                continue
+
+                
+            logging.getLogger(self.name).info(
+                'Creating file %s', filename)
+            self.writeFile(self.options['path'], filename,
+                           self.options[filename])
+            # The file will be removed when buildout reinstalls...
+            paths.append(os.path.join(self.options['path'], filename))
+            
+        return paths
+       
+
+    update = install
+
+    def writeFile(self, path, filename, contents):
+        fullpath = os.path.join(path, filename)
+        open(fullpath, 'wb').write(contents)
+        return fullpath

Added: Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/tests/__init__.py
===================================================================
--- Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/tests/__init__.py	                        (rev 0)
+++ Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/tests/__init__.py	2009-02-04 13:29:48 UTC (rev 96077)
@@ -0,0 +1 @@
+# package

Added: Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/tests/test_docs.py
===================================================================
--- Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/tests/test_docs.py	                        (rev 0)
+++ Sandbox/ulif/z3c.recipe.textfile/z3c/recipe/textfile/tests/test_docs.py	2009-02-04 13:29:48 UTC (rev 96077)
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+"""
+Doctest runner for 'z3c.recipe.textfile'.
+"""
+__docformat__ = 'restructuredtext'
+
+import unittest
+import zc.buildout.tests
+import zc.buildout.testing
+
+from zope.testing import doctest, renormalizing
+
+optionflags =  (doctest.ELLIPSIS |
+                doctest.NORMALIZE_WHITESPACE |
+                doctest.REPORT_ONLY_FIRST_FAILURE)
+
+def setUp(test):
+    zc.buildout.testing.buildoutSetUp(test)
+
+    # Install the recipe in develop mode
+    zc.buildout.testing.install_develop('z3c.recipe.textfile', test)
+
+    # Install any other recipes that should be available in the tests
+    #zc.buildout.testing.install('collective.recipe.foobar', test)
+
+def test_suite():
+    suite = unittest.TestSuite((
+            doctest.DocFileSuite(
+                '../README.txt',
+                setUp=setUp,
+                tearDown=zc.buildout.testing.buildoutTearDown,
+                optionflags=optionflags,
+                checker=renormalizing.RENormalizing([
+                        # If want to clean up the doctest output you
+                        # can register additional regexp normalizers
+                        # here. The format is a two-tuple with the RE
+                        # as the first item and the replacement as the
+                        # second item, e.g.
+                        # (re.compile('my-[rR]eg[eE]ps'), 'my-regexps')
+                        zc.buildout.testing.normalize_path,
+                        ]),
+                ),
+            ))
+    return suite
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')



More information about the Checkins mailing list