Package: lovely.recipe
Filesystem Buildout RecipeCreating Directories>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = data-dir
... find-links = http://download.zope.org/distribution
...
... [data-dir]
... recipe = lovely.recipe:mkdir
... path = ${buildout:directory}/mystuff
... """)
>>> print system(buildout),
Installing data-dir.
data-dir: Creating directory /sample-buildout/mystuff>>> ls(sample_buildout)
-  .installed.cfg
d  bin
-  buildout.cfg
d  develop-eggs
d  eggs
d  mystuff
d  partsIf we change the directory name the old directory (‘mystuff’) is not deleted.>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = data-dir
... find-links = http://download.zope.org/distribution
...
... [data-dir]
... recipe = lovely.recipe:mkdir
... path = ${buildout:directory}/otherdir
... """)
>>> print system(buildout),
Uninstalling data-dir.
Installing data-dir.
data-dir: Creating directory /sample-buildout/otherdir>>> ls(sample_buildout)
-  .installed.cfg
d  bin
-  buildout.cfg
d  develop-eggs
d  eggs
d  mystuff
d  otherdir
d  partsWe can also create a full path.>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = data-dir
... find-links = http://download.zope.org/distribution
...
... [data-dir]
... recipe = lovely.recipe:mkdir
... path = ${buildout:directory}/with/subdir
... """)
>>> print system(buildout),
Uninstalling data-dir.
Installing data-dir.
data-dir: Cannot create /sample-buildout/with/subdir. /sample-buildout/with is not a directory.
While:
  Installing data-dir.
Error: Invalid PathBut we need to activate this function explicitely.>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = data-dir
... find-links = http://download.zope.org/distribution
...
... [data-dir]
... recipe = lovely.recipe:mkdir
... createpath = True
... path = ${buildout:directory}/with/subdir
... """)
>>> print system(buildout),
Installing data-dir.
data-dir: Creating parent directory /sample-buildout/with
data-dir: Creating directory /sample-buildout/with/subdir>>> ls(sample_buildout)
-  .installed.cfg
d  bin
-  buildout.cfg
d  develop-eggs
d  eggs
d  mystuff
d  otherdir
d  parts
d  with
>>> ls(sample_buildout + '/with')
d  subdirThere is no update method so the install method is used upon update
and the directories get recreated.>>> rmdir(sample_buildout + '/with')
>>> print system(buildout),
Updating data-dir.
The recipe for data-dir doesn't define an update method. Using its install method.
data-dir: Creating parent directory /sample-buildout/with
data-dir: Creating directory /sample-buildout/with/subdirWe can change the owner of the created directory if run as root. This is tested
in mkdir-root.txt.If not run as root, setting the owner is an error:>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = data-dir
... find-links = http://download.zope.org/distribution
...
... [data-dir]
... recipe = lovely.recipe:mkdir
... createpath = True
... path = ${buildout:directory}/another/with/subdir
... owner = nobody
... """)
>>> print system(buildout),
While:
  Installing.
  Getting section data-dir.
  Initializing part data-dir.
Error: Only root can change the owner to nobody.It is an error when the user does not exist:>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = data-dir
... find-links = http://download.zope.org/distribution
...
... [data-dir]
... recipe = lovely.recipe:mkdir
... createpath = True
... path = ${buildout:directory}/another/with/subdir
... owner = someuser
... """)
>>> print system(buildout),
While:
  Installing.
  Getting section data-dir.
  Initializing part data-dir.
Error: The user someuser does not exist.Creating FilesThe mkfile recipe creates one or more files with a given path, content and
permissions.Note that the parent directory needs to exist, otherwise a user error
is raised.>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = script
...
... [script]
... recipe = lovely.recipe:mkfile
... path = /x/y/file.sh
... content = hoschi
... mode = 0755
... """)
>>> print system(buildout)
Uninstalling data-dir.
Installing script.
script: Cannot create file /x/y/file.sh. /x/y is not a directory.
While:
  Installing script.
Error: Invalid path>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = script
...
... [script]
... recipe = lovely.recipe:mkfile
... path = file.sh
... content = hoschi
... mode = 0755
... """)
>>> print system(buildout)
Installing script.
script: Writing file /sample-buildout/file.sh
<BLANKLINE>>>> ls(sample_buildout)
-  .installed.cfg
d  bin
-  buildout.cfg
d  develop-eggs
d  eggs
-  file.sh
d  mystuff
d  otherdir
d  parts
d  withThe content is written to the file.>>> cat(sample_buildout, 'file.sh')
hoschiAnd the mode is set.>>> import os, stat
>>> path = os.path.join(sample_buildout, 'file.sh')
>>> oct(stat.S_IMODE(os.stat(path)[stat.ST_MODE]))
'0755'If we change the filename the old file is deleted.>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = script
...
... [script]
... recipe = lovely.recipe:mkfile
... path = newfile.sh
... content = hoschi
... mode = 0755
... """)
>>> print system(buildout)
Uninstalling script.
Installing script.
script: Writing file /sample-buildout/newfile.sh
<BLANKLINE>>>> ls(sample_buildout)
-  .installed.cfg
d  bin
-  buildout.cfg
d  develop-eggs
d  eggs
d  mystuff
-  newfile.sh
d  otherdir
d  parts
d  withWe can also specify to create the path for the file.>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = script
...
... [script]
... recipe = lovely.recipe:mkfile
... createpath = On
... path = subdir/for/file/file.sh
... content = hoschi
... mode = 0755
... """)
>>> print system(buildout)
Uninstalling script.
Installing script.
script: Creating directory /sample-buildout/subdir/for/file
script: Writing file /sample-buildout/subdir/for/file/file.sh>>> ls(sample_buildout + '/subdir/for/file')
-  file.shFile VariationsA common use-case is to have variations of a file, for example if init
scripts have to be created. As an example we create two files with
variations “1” and “2”. These variations can be used in the file path
and in the content of the file via normal string formatting notation.>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = script
...
... [script]
... recipe = lovely.recipe:mkfile
... variations = 1 2
... path = prod_%(variation)s.ini
... content = hoschi variation %(variation)s
... mode = 0755
... """)
>>> print system(buildout)
Uninstalling script.
Installing script.
script: Writing file ...sample-buildout/prod_1.ini
script: Writing file ...sample-buildout/prod_2.ini>>> cat(sample_buildout, 'prod_1.ini')
hoschi variation 1
>>> cat(sample_buildout, 'prod_2.ini')
hoschi variation 2Egg Box Buildout RecipeThis recipe is derivd from zc.recipe.egg, but instead of just creating
paths, it generates a directory structure for each top-level
namespace. It is also possible to automatically zip the generated
directories which is espacially usefull if used in Google Appengine
environments. The recipies path option is filled with the created path
so it can be referenced by other buildout sections which may want to
use the recipe.>>> import os
>>> lovely_recipy_loc = os.path.dirname(os.path.dirname(os.path.dirname(
...     os.path.dirname(os.path.dirname(__file__)))))>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... develop = %(loc)s
... parts = packages
... find-links = %(server)s
... index = %(server)s/index
...
... [packages]
... recipe = lovely.recipe:eggbox
... eggs = demo
...        lovely.recipe
... interpreter = py
... """ % dict(loc=lovely_recipy_loc, server=link_server))>>> print system(buildout)
Develop: '...lovely.recipe'
Getting distribution for 'demo'.
Got demo 0.4c1.
Getting distribution for 'demoneeded'.
Got demoneeded 1.2c1.
Installing packages.
Generated script '...sample-buildout/bin/demo'.
Generated interpreter '...sample-buildout/bin/py'.We now have a zip file for each top-level directory. Note that the
zip-files are ending with .egg for pkg_resources compatibility.>>> ls(sample_buildout + '/parts/packages')
-  easy_install.py.egg
-  eggrecipedemo.py.egg
-  eggrecipedemoneeded.py.egg
-  lovely.egg
-  pkg_resources.py.egg
-  setuptools.egg
-  zc.eggThe generated interpreter now has the demo zip file in the path.>>> cat(sample_buildout + '/bin/py')
#!...
sys.path[0:0] = [
  '/sample-buildout/parts/packages/easy_install.py.egg',
  '/sample-buildout/parts/packages/eggrecipedemo.py.egg',
  '/sample-buildout/parts/packages/eggrecipedemoneeded.py.egg',
  '/sample-buildout/parts/packages/lovely.egg',
  '/sample-buildout/parts/packages/pkg_resources.py.egg',
  '/sample-buildout/parts/packages/setuptools.egg',
  '/sample-buildout/parts/packages/zc.egg',
  ]...It is possible to disable zipping. And also to exclude or include
patterns of files. So for example we can strip down the uneeded
setuptools egg. We can also create a script.>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... develop = %(loc)s
... parts = packages test
... find-links = %(server)s
... index = %(server)s/index
...
... [packages]
... zip = False
... recipe = lovely.recipe:eggbox
... eggs = demo
...        lovely.recipe
... excludes = ^setuptools/.*
...            ^easy_install.*
...            ^pkg_resources.*
...
... [test]
... recipe = zc.recipe.egg:scripts
... eggs = lovely.recipe
... extra-paths = ${packages:path}
... interpreter = py
... """ % dict(loc=lovely_recipy_loc, server=link_server))
>>> print system(buildout),
Develop: '/Users/bd/sandbox/lovely.recipe'
Uninstalling packages.
Installing packages.
Generated script '/sample-buildout/bin/demo'.
Installing test.
Generated interpreter '/sample-buildout/bin/py'.Note that we still have the same directory structure as the zipped
version with a directory for each top-level namespace.  The ‘lovely’
directory is not in he packages directory because it is a develop egg
and we have set zipped to false, therefore it is only added to the
python path.>>> ls(sample_buildout + '/parts/packages')
d  eggrecipedemo.py
d  eggrecipedemoneeded.py
d  zc>>> print system(join(sample_buildout, 'bin', 'py') + \
...        ' -c "import lovely.recipe; print lovely.recipe.__file__"')
/.../src/lovely/recipe/__init__.py...The test section uses the path of our packages section. Note that due,
to the development path of lovely.recipe this path is actually
included twice because the script recipe does not check duplicates.>>> cat(sample_buildout + '/bin/py')
#!...
sys.path[0:0] = [
  '/...lovely.recipe/src',
  ...
  '/.../lovely.recipe/src',
  '/sample-buildout/parts/packages/eggrecipedemo.py',
  '/sample-buildout/parts/packages/eggrecipedemoneeded.py',
  '/sample-buildout/parts/packages/zc',
  ]...i18n Tools RecipeThis recipe allows to create i18n tools to extract and merge po files.Creating The Tools>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = i18n
... index = http://download.zope.org/zope3.4
... offline = true
...
... [i18n]
... recipe = lovely.recipe:i18n
... package = lovely.recipe
... domain = recipe
... location = src/somewhere
... output = locales
... maker = z3c.csvvocabulary.csvStrings
... """)
>>> print system(buildout),
Installing i18n.
i18n: setting up i18n tools
Generated script 'bin/i18nextract'.
Generated script 'bin/i18nmergeall'.
Generated script 'bin/i18nstats'.>>> import os
>>> ls(os.path.join(sample_buildout, 'bin'))
-  buildout
-  i18nextract
-  i18nmergeall
-  i18nstatsThe i18n Extractor>>> cat('bin', 'i18nextract')
#!...
<BLANKLINE>
import sys
sys.path[0:0] = [
...
  ]
<BLANKLINE>
import lovely.recipe.i18n.i18nextract
<BLANKLINE>
if __name__ == '__main__':
    lovely.recipe.i18n.i18nextract.main(['i18nextract', '-d', 'recipe', '-s', '/sample-buildout/parts/i18n/configure.zcml', '-p', 'src/somewhere', '-o', 'locales', '-m', 'z3c.csvvocabulary.csvStrings'])We have a configure.zcml created.>>> cat('parts', 'i18n', 'configure.zcml')
<configure xmlns='http://namespaces.zope.org/zope'>
  <include package="lovely.recipe" />
</configure>i18n Merge>>> cat('bin', 'i18nmergeall')
#!...
<BLANKLINE>
import sys
sys.path[0:0] = [
...
  ]
<BLANKLINE>
import lovely.recipe.i18n.i18nmergeall
<BLANKLINE>
if __name__ == '__main__':
    lovely.recipe.i18n.i18nmergeall.main(['i18nmergeall', '-l', 'src/somewhere/locales'])i18n Stats>>> cat('bin', 'i18nstats')
#!...
<BLANKLINE>
import sys
sys.path[0:0] = [
...
  ]
<BLANKLINE>
import lovely.recipe.i18n.i18nstats
<BLANKLINE>
if __name__ == '__main__':
    lovely.recipe.i18n.i18nstats.main(['i18nstats', '-l', 'src/somewhere/locales'])Tool NamesThe created tools are named after the section name. If the section for the
recipe is named ‘translation’ then the tools are named ‘translationextract’
and ‘translationmergeall’.>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... index = http://download.zope.org/zope3.4
... parts = translation
...
... offline = true
...
... [translation]
... recipe = lovely.recipe:i18n
... package = lovely.recipe
... domain = recipe
... location = src/somewhere
... output = locales
... maker = z3c.csvvocabulary.csvStrings
... """)
>>> print system(buildout),
Uninstalling i18n.
Installing translation.
translation: setting up i18n tools
Generated script 'bin/translationextract'.
Generated script 'bin/translationmergeall'.
Generated script 'bin/translationstats'.Adding a custom configure.zcmlThe created configure.zcml includes the package an assumes that the package
contains a configure.zcml. If this is not the case or if additional package
includes are needed then the zcml parameter can be used to define the content
of the generated configure.zcml.>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = i18n
...
... offline = true
...
... [i18n]
... recipe = lovely.recipe:i18n
... package = lovely.recipe
... domain = recipe
... location = src/somewhere
... output = locales
... maker = z3c.csvvocabulary.csvStrings
... zcml =
...    <include package='zope.component' file='meta.zcml' />
...    <include package='lovely.recipe' />
...
... """)>>> print system(buildout),
Uninstalling translation.
Installing i18n.
i18n: setting up i18n tools
Generated script 'bin/i18nextract'.
Generated script 'bin/i18nmergeall'.
Generated script 'bin/i18nstats'.>>> cat('bin', 'i18nextract')
#!...
<BLANKLINE>
import sys
sys.path[0:0] = [
...
  ]
<BLANKLINE>
import lovely.recipe.i18n.i18nextract
<BLANKLINE>
if __name__ == '__main__':
    lovely.recipe.i18n.i18nextract.main(['i18nextract', '-d', 'recipe', '-s', '/sample-buildout/parts/i18n/configure.zcml', '-p', 'src/somewhere', '-o', 'locales', '-m', 'z3c.csvvocabulary.csvStrings'])And the generated configure-zcml contains our extra code.>>> cat('parts', 'i18n', 'configure.zcml')
<configure xmlns='http://namespaces.zope.org/zope'
           xmlns:meta="http://namespaces.zope.org/meta"
           >
<BLANKLINE>
<BLANKLINE>
<include package='zope.component' file='meta.zcml' />
<include package='lovely.recipe' />
<BLANKLINE>
</configure>Importchecker RecipeThis recipe creates an importchecker instance in the bin directory.Creating The Script>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = checker
...
... offline = true
...
... [checker]
... recipe = lovely.recipe:importchecker
... path = src/lovely
... """)
>>> print system(buildout),
Installing checker.
checker: setting up importchecker
Generated script 'bin/importchecker'.>>> import os
>>> ls(os.path.join(sample_buildout, 'bin'))
-  buildout
-  importchecker>>> cat('bin', 'importchecker')
#!...
<BLANKLINE>
import sys
sys.path[0:0] = [
  ...
  ]
<BLANKLINE>
import lovely.recipe.importchecker.importchecker
<BLANKLINE>
if __name__ == '__main__':
    lovely.recipe.importchecker.importchecker.main(['importchecker', 'src/lovely'])