{ "info": { "author": "Gary Poster", "author_email": "gary.poster@canonical.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Framework :: Buildout", "Intended Audience :: Developers", "License :: OSI Approved :: Zope Public License", "Operating System :: OS Independent", "Programming Language :: Python", "Topic :: Software Development :: Build Tools" ], "description": "``as.recipe.filetemplate``\n***************************\n\n===========\nBasic Usage\n===========\n\nWith the ``as.recipe.filetemplate`` buildout recipe you can automate\nthe generation of text files from templates. Upon execution, the\nrecipe will read a number of template files, perform variable\nsubstitution and write the result to the corresponding output files.\n\nThe recipe has several features, but it always takes template files with a\n``.in`` suffix, processes the template, and writes out the file to the desired\nlocation with the same file mode, and the same name but without the ``.in``\nsuffix.\n\nFor example, consider this simple template for a text file:\n\n >>> write(sample_buildout, 'helloworld.txt.in',\n ... \"\"\"\n ... Hello ${world}!\n ... \"\"\")\n\nNow let's create a buildout configuration so that we can substitute\nthe values in this file. All we have to do is define a part that uses\nthe ``as.recipe.filetemplate`` recipe. With the ``files`` parameter\nwe specify one or more files that need substitution (separated by\nwhitespace). Then we can add arbitrary parameters to the section.\nThose will be used to fill the variables in the template:\n\n >>> write(sample_buildout, 'buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = message\n ...\n ... [message]\n ... recipe = as.recipe.filetemplate\n ... files = helloworld.txt\n ... world = Philipp\n ... \"\"\")\n\nAfter executing buildout, we can see that ``${world}`` has indeed been\nreplaced by ``Philipp``:\n\n >>> print system(buildout)\n Installing message.\n\n >>> cat(sample_buildout, 'helloworld.txt')\n Hello Philipp!\n\nIf you need to escape the ${...} pattern, you can do so by repeating the dollar\nsign.\n\n >>> update_file(sample_buildout, 'helloworld.txt.in',\n ... \"\"\"\n ... Hello world! The double $${dollar-sign} escapes!\n ... \"\"\")\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n\n >>> cat(sample_buildout, 'helloworld.txt')\n Hello world! The double ${dollar-sign} escapes!\n\nNote that dollar signs alone, without curly braces, are not parsed.\n\n >>> update_file(sample_buildout, 'helloworld.txt.in',\n ... \"\"\"\n ... $Hello $$world! $$$profit!\n ... \"\"\")\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n\n >>> cat(sample_buildout, 'helloworld.txt')\n $Hello $$world! $$$profit!\n\nNote that the output file uses the same permission bits as found on the input\nfile.\n\n >>> import stat\n >>> import os\n >>> input = os.path.join(sample_buildout, 'helloworld.txt.in')\n >>> output = input[:-3]\n >>> os.chmod(input, 0755)\n >>> stat.S_IMODE(os.stat(input).st_mode) == 0755\n True\n >>> stat.S_IMODE(os.stat(output).st_mode) == 0755\n False\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n >>> stat.S_IMODE(os.stat(output).st_mode) == 0755\n True\n\nSource Folders and Globs\n========================\n\nBy default, the recipe looks for a ``.in`` file relative to the buildout root,\nand places it in the same folder relative to the buildout root. However, if\nyou don't want to clutter up the destination folder, you can add a prefix to\nthe source folder. Here is an example.\n\nFirst, we specify a ``source-directory`` in the buildout. You can specify\n``files`` as a filter if desired, but by default it will find any file (ending\nwith \".in\"). You can also specify ``exclude-directories`` option if you want\nto exclude some paths from the ``source-directory`` search path.\n\n >>> write(sample_buildout, 'buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = message\n ...\n ... [message]\n ... recipe = as.recipe.filetemplate\n ... source-directory = template\n ... world = Philipp\n ... \"\"\")\n\nNow we'll make a \"template\" directory, as listed in the buildout configuration\nabove, and populate it for our example.\n\n >>> mkdir(sample_buildout, 'template')\n >>> mkdir(sample_buildout, 'template', 'etc')\n >>> mkdir(sample_buildout, 'template', 'bin')\n >>> write(sample_buildout, 'template', 'etc', 'helloworld.conf.in',\n ... \"\"\"\n ... Hello ${world} from the etc dir!\n ... \"\"\")\n >>> write(sample_buildout, 'template', 'bin', 'helloworld.sh.in',\n ... \"\"\"\n ... Hello ${world} from the bin dir!\n ... \"\"\")\n >>> os.chmod(\n ... os.path.join(\n ... sample_buildout, 'template', 'bin', 'helloworld.sh.in'),\n ... 0711)\n\nNotice that, before running buildout, the ``helloworld.txt`` file is still\naround, we don't have an etc directory, and the bin directory doesn't have our\n``helloworld.sh``.\n\n >>> ls(sample_buildout)\n - .installed.cfg\n d bin\n - buildout.cfg\n d develop-eggs\n d eggs\n - helloworld.txt\n - helloworld.txt.in\n d parts\n d template\n >>> ls(sample_buildout, 'bin')\n - buildout\n\nNow we install. The old \"helloworld.txt\" is gone, and we now see etc. Note\nthat, for the destination, intermediate folders are created if they do not\nexist.\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n >>> ls(sample_buildout)\n - .installed.cfg\n d bin\n - buildout.cfg\n d develop-eggs\n d eggs\n d etc\n - helloworld.txt.in\n d parts\n d template\n\nThe files exist and have the content we expect.\n\n >>> ls(sample_buildout, 'bin')\n - buildout\n - helloworld.sh\n >>> cat(sample_buildout, 'bin', 'helloworld.sh')\n Hello Philipp from the bin dir!\n >>> stat.S_IMODE(os.stat(os.path.join(\n ... sample_buildout, 'bin', 'helloworld.sh')).st_mode) == 0711\n True\n >>> ls(sample_buildout, 'etc')\n - helloworld.conf\n >>> cat(sample_buildout, 'etc', 'helloworld.conf')\n Hello Philipp from the etc dir!\n\nIf you use the ``files`` option along with ``source-directory``, it becomes a\nfilter. Every target file must match at least one of the names in ``files``.\nTherefore, if we only build .sh files, the etc directory will disappear.\n\n >>> write(sample_buildout, 'buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = message\n ...\n ... [message]\n ... recipe = as.recipe.filetemplate\n ... source-directory = template\n ... files = *.sh\n ... world = Philipp\n ... \"\"\")\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n >>> ls(sample_buildout)\n - .installed.cfg\n d bin\n - buildout.cfg\n d develop-eggs\n d eggs\n - helloworld.txt.in\n d parts\n d template\n\n >>> ls(sample_buildout, 'bin')\n - buildout\n - helloworld.sh\n\nAlso note that, if you use a source directory and your ``files`` specify a\ndirectory, the directory must match precisely.\n\nWith the ``exclude-directories`` parameter, we specify one or more directories\n(separated by whitespace) in which the recipe will not look for template\nfiles. The ``exclude-directories`` option should be used along with the\n``source-directory`` option.\nTherefore, if we set ``exclude-directories`` to ``bin``, the\n``bin/helloworld.sh`` file will disappear.\n\n >>> write(sample_buildout, 'buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = message\n ...\n ... [message]\n ... recipe = as.recipe.filetemplate\n ... source-directory = template\n ... exclude-directories = bin\n ... world = Philipp\n ... \"\"\")\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n >>> ls(sample_buildout)\n - .installed.cfg\n d bin\n - buildout.cfg\n d develop-eggs\n d eggs\n d etc\n - helloworld.txt.in\n d parts\n d template\n\n >>> ls(sample_buildout, 'etc')\n - helloworld.conf\n\n >>> ls(sample_buildout, 'bin')\n - buildout\n\n >>> # Clean up for later test.\n >>> import shutil\n >>> shutil.rmtree(os.path.join(sample_buildout, 'template', 'etc'))\n >>> os.remove(os.path.join(\n ... sample_buildout, 'template', 'bin', 'helloworld.sh.in'))\n\n==============\nAdvanced Usage\n==============\n\nSubstituting from Other Sections\n================================\n\nSubstitutions can also come from other sections in the buildout, using the\nstandard buildout syntax, but used in the template. Notice\n``${buildout:parts}`` in the template below.\n\n >>> update_file(sample_buildout, 'helloworld.txt.in',\n ... \"\"\"\n ... Hello ${world}. I used these parts: ${buildout:parts}.\n ... \"\"\")\n >>> write(sample_buildout, 'buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = message\n ...\n ... [message]\n ... recipe = as.recipe.filetemplate\n ... files = helloworld.txt\n ... world = Philipp\n ... \"\"\")\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n\n >>> cat(sample_buildout, 'helloworld.txt')\n Hello Philipp. I used these parts: message.\n\nPath Extensions\n===============\n\nSubstitutions can have path suffixes using the POSIX \"/\" path separator.\nThe template will convert these to the proper path separator for the current\nOS. They also then are part of the value passed to filters, the feature\ndescribed next. Notice ``${buildout:directory/foo/bar.txt}`` in the template\nbelow.\n\n >>> update_file(sample_buildout, 'helloworld.txt.in',\n ... \"\"\"\n ... Here's foo/bar.txt in the buildout:\n ... ${buildout:directory/foo/bar.txt}\n ... \"\"\")\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n\n >>> cat(sample_buildout, 'helloworld.txt') # doctest: +ELLIPSIS\n Here's foo/bar.txt in the buildout:\n /.../sample-buildout/foo/bar.txt\n\nFilters\n=======\n\nYou can use pipes within a substitution to filter the original value. This\nrecipe provides several filters for you to use. The syntax is reminiscent of\n(and inspired by) POSIX pipes and Django template filters. For example,\nif world = Philipp, ``HELLO ${world|upper}!`` would result in ``HELLO\nPHILIPP!``.\n\nA few simple Python string methods are exposed as filters right now:\n\n- capitalize: First letter in string is capitalized.\n- lower: All letters in string are lowercase.\n- title: First letter of each word in string is capitalized.\n- upper: All letters in string are uppercase.\n\nOther filters are important for handling paths if buildout's relative-paths\noption is true. See `Working with Paths`_ for more details.\n\n- path-repr: Converts the path to a Python expression for the path. If\n buildout's relative-paths option is false, this will simply be a repr\n of the absolute path. If relative-paths is true, this will be a\n function call to convert a buildout-relative path to an absolute path;\n it requires that ``${python-relative-path-setup}`` be included earlier\n in the template.\n\n- shell-path: Converts the path to a shell expression for the path. Only\n POSIX is supported at this time. If buildout's relative-paths option\n is false, this will simply be the absolute path. If relative-paths is\n true, this will be an expression to convert a buildout-relative path\n to an absolute path; it requires that ``${shell-relative-path-setup}``\n be included earlier in the template.\n\nCombining the three advanced features described so far, then, if the\nbuildout relative-paths option were false, we were in a POSIX system, and\nthe sample buildout were in the root of the system, the template\nexpression ``${buildout:bin-directory/data/initial.csv|path-repr}``\nwould result in ``'/sample-buildout/bin/data/initial.csv'``.\n\nHere's a real, working example of the string method filters. We'll have\nexamples of the path filters in the `Working with Paths`_ section.\n\n >>> update_file(sample_buildout, 'helloworld.txt.in',\n ... \"\"\"\n ... HELLO ${world|upper}!\n ... hello ${world|lower}.\n ... ${name|title} and the Chocolate Factory\n ... ${sentence|capitalize}\n ... \"\"\")\n\n >>> write(sample_buildout, 'buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = message\n ...\n ... [message]\n ... recipe = as.recipe.filetemplate\n ... files = helloworld.txt\n ... world = Philipp\n ... name = willy wonka\n ... sentence = that is a good book.\n ... \"\"\")\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n\n >>> cat(sample_buildout, 'helloworld.txt') # doctest: +ELLIPSIS\n HELLO PHILIPP!\n hello philipp.\n Willy Wonka and the Chocolate Factory\n That is a good book.\n\nSharing Variables\n=================\n\nThe recipe allows extending one or more sections, to decrease\nrepetition, using the ``extends`` option. For instance, consider the\nfollowing buildout.\n\n >>> write(sample_buildout, 'buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = message\n ...\n ... [template_defaults]\n ... mygreeting = Hi\n ... myaudience = World\n ...\n ... [message]\n ... recipe = as.recipe.filetemplate\n ... files = helloworld.txt\n ... extends = template_defaults\n ...\n ... myaudience = everybody\n ... \"\"\")\n\nThe \"message\" section now has values extended from the \"template_defaults\"\nsection, and overwritten locally. A template of\n``${mygreeting}, ${myaudience}!``...\n\n >>> update_file(sample_buildout, 'helloworld.txt.in',\n ... \"\"\"\n ... ${mygreeting}, ${myaudience}!\n ... \"\"\")\n\n...would thus result in ``Hi, everybody!``.\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n\n >>> cat(sample_buildout, 'helloworld.txt')\n Hi, everybody!\n\nDefining options in Python\n==========================\n\nYou can specify that certain variables should be interpreted as Python using\n``interpreted-options``. This takes zero or more lines. Each line should\nspecify an option. It can define immediately (see ``silly-range`` in\nthe example below) or point to an option to be interepreted, which can\nbe useful if you want to define a multi-line expression (see\n``first-interpreted-option`` and ``message-reversed-is-egassem``).\n\n >>> write(sample_buildout, 'buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = message\n ...\n ... [message]\n ... recipe = as.recipe.filetemplate\n ... files = helloworld.txt\n ... interpreted-options = silly-range = repr(range(5))\n ... first-interpreted-option\n ... message-reversed-is-egassem\n ... first-interpreted-option =\n ... options['interpreted-options'].splitlines()[0].strip()\n ... message-reversed-is-egassem=\n ... ''.join(\n ... reversed(\n ... buildout['buildout']['parts']))\n ... not-interpreted=hello world\n ... \"\"\")\n\n >>> update_file(sample_buildout, 'helloworld.txt.in', \"\"\"\\\n ... ${not-interpreted}!\n ... silly-range: ${silly-range}\n ... first-interpreted-option: ${first-interpreted-option}\n ... message-reversed-is-egassem: ${message-reversed-is-egassem}\n ... \"\"\")\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n\n >>> cat(sample_buildout, 'helloworld.txt') # doctest:+ELLIPSIS\n hello world!\n silly-range: [0, 1, 2, 3, 4]\n first-interpreted-option: silly-range = repr(range(5))\n message-reversed-is-egassem: egassem\n\nWorking with Paths\n==================\n\nWe've already mentioned how to handle buildout's relative-paths option\nin the discussion of filters. This section has some concrete examples\nand discussion of that. It also introduces how to get a set of paths\nfrom specifying dependencies.\n\nHere are concrete examples of the path-repr and shell-path filters.\nWe'll show results when relative-paths is true and when it is false.\n\n------------------------------\nDemonstration of ``path-repr``\n------------------------------\n\nLet's say we want to make a custom Python script in the bin directory.\nIt will print some information from a file in a ``data`` directory\nwithin the buildout root. Here's the template.\n\n >>> write(sample_buildout, 'template', 'bin', 'dosomething.py.in', '''\\\n ... #!${buildout:executable}\n ... ${python-relative-path-setup}\n ... f = open(${buildout:directory/data/info.csv|path-repr})\n ... print f.read()\n ... ''')\n >>> os.chmod(\n ... os.path.join(\n ... sample_buildout, 'template', 'bin', 'dosomething.py.in'),\n ... 0711)\n\nIf we evaluate that template with relative-paths set to false, the results\nshouldn't be too surprising.\n\n >>> write(sample_buildout, 'buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = message\n ...\n ... [message]\n ... recipe = as.recipe.filetemplate\n ... source-directory = template\n ... \"\"\")\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n\n >>> cat(sample_buildout, 'bin', 'dosomething.py') # doctest: +ELLIPSIS\n #!...\n \n f = open('/.../sample-buildout/data/info.csv')\n print f.read()\n\n``${python-relative-path-setup}`` evaluated to an empty string. The path\nis absolute and quoted.\n\nIf we evaluate it with relative-paths set to true, the results are much...\nbigger.\n\n >>> write(sample_buildout, 'buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = message\n ... relative-paths = true\n ...\n ... [message]\n ... recipe = as.recipe.filetemplate\n ... source-directory = template\n ... \"\"\")\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n\n >>> cat(sample_buildout, 'bin', 'dosomething.py') # doctest: +ELLIPSIS\n #!...\n import os, imp\n # Get path to this file.\n if __name__ == '__main__':\n _z3c_recipe_filetemplate_filename = __file__\n else:\n # If this is an imported module, we want the location of the .py\n # file, not the .pyc, because the .py file may have been symlinked.\n _z3c_recipe_filetemplate_filename = imp.find_module(__name__)[1]\n # Get the full, non-symbolic-link directory for this file.\n _z3c_recipe_filetemplate_base = os.path.dirname(\n os.path.abspath(os.path.realpath(_z3c_recipe_filetemplate_filename)))\n # Ascend to buildout root.\n _z3c_recipe_filetemplate_base = os.path.dirname(\n _z3c_recipe_filetemplate_base)\n def _z3c_recipe_filetemplate_path_repr(path):\n \"Return absolute version of buildout-relative path.\"\n return os.path.join(_z3c_recipe_filetemplate_base, path)\n \n f = open(_z3c_recipe_filetemplate_path_repr('data/info.csv'))\n print f.read()\n\nThat's quite a bit of code. You might wonder why we don't just use '..' for\nparent directories. The reason is that we want our scripts to be usable\nfrom any place on the filesystem. If we used '..' to construct paths\nrelative to the generated file, then the paths would only work from\ncertain directories.\n\nSo that's how path-repr works. It can really come in handy if you want\nto support relative paths in buildout. Now let's look at the shell-path\nfilter.\n\n-------------------------------\nDemonstration of ``shell-path``\n-------------------------------\n\nMaybe you want to write some shell scripts. The shell-path filter will help\nyou support buildout relative-paths fairly painlessly.\n\nRight now, only POSIX is supported with the shell-path filter, as mentioned\nbefore.\n\nUsage is very similar to the ``path-repr`` filter. You need to include\n``${shell-relative-path-setup}`` before you use it, just as you include\n``${python-relative-path-setup}`` before using ``path-repr``.\n\nLet's say we want to make a custom shell script in the bin directory.\nIt will print some information from a file in a ``data`` directory\nwithin the buildout root. Here's the template.\n\n >>> write(sample_buildout, 'template', 'bin', 'dosomething.sh.in', '''\\\n ... #!/bin/sh\n ... ${shell-relative-path-setup}\n ... cat ${buildout:directory/data/info.csv|shell-path}\n ... ''')\n >>> os.chmod(\n ... os.path.join(\n ... sample_buildout, 'template', 'bin', 'dosomething.sh.in'),\n ... 0711)\n\nIf relative-paths is set to false (the default), the results are simple.\n\n >>> write(sample_buildout, 'buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = message\n ...\n ... [message]\n ... recipe = as.recipe.filetemplate\n ... source-directory = template\n ... \"\"\")\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n\n >>> cat(sample_buildout, 'bin', 'dosomething.sh') # doctest: +ELLIPSIS\n #!/bin/sh\n \n cat /.../sample-buildout/data/info.csv\n\n``${shell-relative-path-setup}`` evaluated to an empty string. The path\nis absolute.\n\nNow let's look at the larger code when relative-paths is set to true.\n\n >>> write(sample_buildout, 'buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = message\n ... relative-paths = true\n ...\n ... [message]\n ... recipe = as.recipe.filetemplate\n ... source-directory = template\n ... \"\"\")\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n\n >>> cat(sample_buildout, 'bin', 'dosomething.sh') # doctest: +ELLIPSIS\n #!/bin/sh\n # Get full, non-symbolic-link path to this file.\n Z3C_RECIPE_FILETEMPLATE_FILENAME=`\\\n readlink -f \"$0\" 2>/dev/null || \\\n realpath \"$0\" 2>/dev/null || \\\n type -P \"$0\" 2>/dev/null`\n # Get directory of file.\n Z3C_RECIPE_FILETEMPLATE_BASE=`dirname ${Z3C_RECIPE_FILETEMPLATE_FILENAME}`\n # Ascend to buildout root.\n Z3C_RECIPE_FILETEMPLATE_BASE=`dirname ${Z3C_RECIPE_FILETEMPLATE_BASE}`\n \n cat \"$Z3C_RECIPE_FILETEMPLATE_BASE\"/data/info.csv\n\nAs with the Python code, we don't just use '..' for\nparent directories because we want our scripts to be usable\nfrom any place on the filesystem.\n\n----------------------------------\nGetting Arbitrary Dependency Paths\n----------------------------------\n\nYou can specify ``eggs`` and ``extra-paths`` in the recipe. The\nmechanism is the same as the one provided by the zc.recipe.egg, so\npertinent options such as find-links and index are available.\n\nIf you do, the paths for the dependencies will be calculated. They will\nbe available as a list in the namespace of the interpreted options as\n``paths``. Also, three predefined options will be available in the\nrecipe's options for the template.\n\nIf ``paths`` are the paths, ``shell_path`` is the ``shell-path`` filter, and\n``path_repr`` is the ``path-repr`` filter, then the pre-defined options\nwould be defined roughly as given here:\n\n``os-paths`` (for shell scripts)\n ``(os.pathsep).join(shell_path(path) for path in paths)``\n\n``string-paths`` (for Python scripts)\n ``',\\n '.join(path_repr(path) for path in paths)``\n\n``space-paths`` (for shell scripts)\n ``' '.join(shell_path(path) for path in paths)``\n\nTherefore, if you want to support the relative-paths option, you should\ninclude ``${shell-relative-path-setup}`` (for ``os-paths`` and\n``space-paths``) or ``${python-relative-path-setup}`` (for ``string-paths``)\nas appropriate at the top of your template.\n\nLet's consider a simple example.\n\n >>> write(sample_buildout, 'buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = message\n ...\n ... [message]\n ... recipe = as.recipe.filetemplate\n ... files = helloworld.txt\n ... eggs = demo<0.3\n ...\n ... find-links = %(server)s\n ... index = %(server)s/index\n ... \"\"\" % dict(server=link_server))\n\nThe relative-paths option is false, the default.\n\n >>> write(sample_buildout, 'helloworld.txt.in',\n ... \"\"\"\n ... Hello! Here are the paths for the ${eggs} eggs.\n ... OS paths:\n ... ${os-paths}\n ... ---\n ... String paths:\n ... ${string-paths}\n ... ---\n ... Space paths:\n ... ${space-paths}\n ... \"\"\")\n\n >>> print system(buildout)\n Getting distribution for 'demo<0.3'.\n Got demo 0.2.\n Getting distribution for 'demoneeded'.\n Got demoneeded 1.2c1.\n Uninstalling message.\n Installing message.\n\n >>> cat(sample_buildout, 'helloworld.txt') # doctest:+ELLIPSIS\n Hello! Here are the paths for the demo<0.3 eggs.\n OS paths:\n /.../eggs/demo-0.2...egg:/.../eggs/demoneeded-1.2c1...egg\n ---\n String paths:\n '/.../eggs/demo-0.2...egg',\n '/.../eggs/demoneeded-1.2c1...egg'\n ---\n Space paths:\n /.../eggs/demo-0.2...egg /.../eggs/demoneeded-1.2c1...egg\n\nYou can specify extra-paths as well, which will go at the end of the egg\npaths.\n\n >>> write(sample_buildout, 'buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = message\n ...\n ... [message]\n ... recipe = as.recipe.filetemplate\n ... files = helloworld.txt\n ... eggs = demo<0.3\n ... extra-paths = ${buildout:directory}/foo\n ...\n ... find-links = %(server)s\n ... index = %(server)s/index\n ... \"\"\" % dict(server=link_server))\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n\n >>> cat(sample_buildout, 'helloworld.txt') # doctest:+ELLIPSIS\n Hello! Here are the paths for the demo<0.3 eggs.\n OS paths:\n /...demo...:/...demoneeded...:/.../sample-buildout/foo\n ---\n String paths:\n '/...demo...',\n '/...demoneeded...',\n '/.../sample-buildout/foo'\n ---\n Space paths:\n /...demo... /...demoneeded... .../sample-buildout/foo\n\nTo emphasize the effect of the relative-paths option, let's see what it looks\nlike when we set relative-paths to True.\n\n >>> write(sample_buildout, 'buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = message\n ... relative-paths = true\n ...\n ... [message]\n ... recipe = as.recipe.filetemplate\n ... files = helloworld.txt\n ... eggs = demo<0.3\n ... extra-paths = ${buildout:directory}/foo\n ...\n ... find-links = %(server)s\n ... index = %(server)s/index\n ... \"\"\" % dict(server=link_server))\n\n >>> print system(buildout)\n Uninstalling message.\n Installing message.\n\n >>> cat(sample_buildout, 'helloworld.txt') # doctest:+ELLIPSIS\n Hello! Here are the paths for the demo<0.3 eggs.\n OS paths:\n \"$Z3C_RECIPE_FILETEMPLATE_BASE\"/eggs/demo-0.2-py...egg:\"$Z3C_RECIPE_FILETEMPLATE_BASE\"/eggs/demoneeded-1.2c1-py...egg:\"$Z3C_RECIPE_FILETEMPLATE_BASE\"/foo\n ---\n String paths:\n _z3c_recipe_filetemplate_path_repr('eggs/demo-0.2-py...egg'),\n _z3c_recipe_filetemplate_path_repr('eggs/demoneeded-1.2c1-py...egg'),\n _z3c_recipe_filetemplate_path_repr('foo')\n ---\n Space paths:\n \"$Z3C_RECIPE_FILETEMPLATE_BASE\"/eggs/demo-0.2-py...egg \"$Z3C_RECIPE_FILETEMPLATE_BASE\"/eggs/demoneeded-1.2c1-py...egg \"$Z3C_RECIPE_FILETEMPLATE_BASE\"/foo\n\n\nRemember, your script won't really work unless you include\n``${shell-relative-path-setup}`` (for ``os-paths`` and ``space-paths``)\nor ``${python-relative-path-setup}`` (for ``string-paths``) as\nappropriate at the top of your template.\n\nGetting Dependency Paths from ``zc.recipe.egg``\n-----------------------------------------------\n\nYou can get the ``eggs`` and ``extra-paths`` from another section using\nzc.recipe.egg by using the ``extends`` option from the `Sharing Variables`_\nsection above. Then you can use the template options described above to\nbuild your paths in your templates.\n\nGetting Dependency Paths from ``z3c.recipe.scripts``\n----------------------------------------------------\n\nIf, like the Launchpad project, you are using Gary Poster's unreleased\npackage ``z3c.recipe.scripts`` to generate your scripts, and you want to\nhave your scripts use the same Python environment as generated by that\nrecipe, you can just use the path-repr and shell-path filters with standard\nbuildout directories. Here is an example buildout.cfg.\n\n::\n\n [buildout]\n parts = scripts message\n relative-paths = true\n\n [scripts]\n recipe = z3c.recipe.scripts\n eggs = demo<0.3\n\n [message]\n recipe = as.recipe.filetemplate\n files = helloworld.py\n\nThen the template to use this would want to simply put\n``${scripts:parts-directory|path-repr}`` at the beginning of Python's path.\n\nYou can do this for subprocesses with PYTHONPATH.\n\n ${python-relative-path-setup}\n import os\n import subprocess\n env = os.environ.copy()\n env['PYTHONPATH'] = ${scripts:parts-directory|path-repr}\n subprocess.call('myscript', env=env)\n\nThat's it.\n\nSimilarly, here's an approach to making a script that will have the\nright environment. You want to put the parts directory of the\nz3c.recipe.scripts section in the sys.path before site.py is loaded.\nThis is usually handled by z3c.recipe.scripts itself, but sometimes you\nmay want to write Python scripts in your template for some reason.\n\n #!/usr/bin/env python -S\n ${python-relative-path-setup}\n import sys\n sys.path.insert(0, ${scripts:parts-directory|path-repr})\n import site\n # do stuff...\n\nIf you do this for many scripts, put this entire snippet in an option in the\nrecipe and use this snippet as a single substitution in the top of your\nscripts.\n\n\n=======\nChanges\n=======\n\n2.2.0 (2011-09-01)\n==================\n\n--------\nFeatures\n--------\n\n- Add support for excluding some subdirectories of the ``source-directory``\n with the ``exclude-directories`` option. [Bruno Binet]\n\n-----\nFixes\n-----\n\n- Added undeclared but necessary test dependency on `zope.testing` in a\n test extra.\n\n- Added test dependency on `z3c.recipe.scripts` as it is required by newer\n `zc.buildout` versions.\n\n- Using python's `doctest` module instead of deprecated\n `zope.testing.doctest`.\n\n2.1.0 (2010-04-21)\n==================\n\n--------\nFeatures\n--------\n\n- Enable cross-platform paths by allowing an extended syntax for path\n suffixes. Example: If ``${buildout:directory}`` resolves to\n ``/sample_buildout`` on a POSIX system and ``C:\\sample_buildout`` in\n Windows, ``${buildout:directory/foo.txt}`` will resolve to\n ``/sample_buildout/foo.txt`` and ``C:\\sample_buildout\\foo.txt``,\n respectively.\n\n- Add filters via a pipe syntax, reminiscent of UNIX pipes or Django template\n filters. Simple example: if ``${name}`` resolves to ``harry`` then\n ``${name|upper}`` resolves to ``HARRY``. Simple string filters are\n upper, lower, title, and capitalize, just like the Python string\n methods. Also see the next bullet.\n\n- Added support for the buildout relative-paths option. Shell scripts should\n include ``${shell-relative-path-setup}`` before commands with\n buildout-generated paths are executed. Python scripts should use\n ``${python-relative-path-setup}`` similarly. ``${os-paths}`` (shell),\n ``${space-paths}`` (shell), and ``${string-paths}`` (Python) will have\n relative paths if the buildout relative-paths option is used. To convert\n individual absolute paths to relative paths, use the ``path-repr`` filter\n in Python scripts and the ``shell-path`` filter in shell scripts. Path\n suffixes can be combined with these filters, so, if buildout's\n relative-paths option is true, ``${buildout:directory/foo.txt|path-repr}``\n will produce a buildout-relative, platform appropriate path to\n foo.txt. Note that for shell scripts, Windows is not supported at\n this time.\n\n- Support escaping ``${...}`` with ``$${...}`` in templates. This is\n particularly useful for UNIX shell scripts.\n\n-----\nFixes\n-----\n\n- Make tests less susceptible to timing errors.\n\n-------\nChanges\n-------\n\n- ``${os-paths}`` and ``${space-paths}`` no longer filter out .zip paths.\n\n- The entries in ``${string-paths}`` now are separated by newlines. Each\n entry is indented to the level of the initial placement of the marker.\n\n2.0.3 (2009-07-02)\n==================\n\n-----\nFixes\n-----\n\n- Use ``realpath`` helper function from zc.buildout on the buildout\n directory too, such that it goes through the same normalization as\n the path being compared and stands a chance of working on Windows,\n due to possible drive letter case differences.\n\n2.0.2 (2009-05-04)\n==================\n\n-----\nFixes\n-----\n\n- Turns out sorting paths was a bad idea. They are already in a deterministic\n order, AFAICT, because of the order or processing dependencies. Sorting\n them makes them *less* deterministic in practice, across machines.\n\n2.0.1 (2009-04-30)\n==================\n\n-----\nFixes\n-----\n\n- Correct sdist generation to include all necessary files.\n\n- Doc formatting fixes.\n\n- Correct \"Destinations already exist\" message to list destinations without\n ``.in`` suffix.\n\n2.0 (2009-04-30)\n================\n\n--------\nFeatures\n--------\n\n- Store your template files in a separate directory structure, using the\n ``source-directory`` option.\n\n- Specify multiple files automatically with globs.\n\n- Templates can reference other buildout sections using the usual syntax, e.g.\n ${buildout:parts}\n\n- Share options with other sections using the typical ``extends`` option.\n\n- Create destination directories automatically.\n\n- Define option values for templates dynamically in Python with the\n ``interpreted-options`` option.\n\n- Get paths for eggs by specifying ``eggs`` and ``extra-paths``, just like\n zc.recipe.egg script recipe. These are available in template options in\n colon-delimited, space-delimited, and quoted variants. You can also build\n your own using the ``interpreted-options`` feature.\n\n- Templates are not processed if there are no changes to them or the buildout.\n\n1.0 (2007-09-30)\n================\n\nInitial release.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://pypi.python.org/pypi/as.recipe.filetemplate", "keywords": null, "license": "ZPL 2.1", "maintainer": null, "maintainer_email": null, "name": "as.recipe.filetemplate", "package_url": "https://pypi.org/project/as.recipe.filetemplate/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/as.recipe.filetemplate/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://pypi.python.org/pypi/as.recipe.filetemplate" }, "release_url": "https://pypi.org/project/as.recipe.filetemplate/2.2.2/", "requires_dist": null, "requires_python": null, "summary": "zc.buildout recipe for creating files from file templates", "version": "2.2.2" }, "last_serial": 772793, "releases": { "2.2.0": [ { "comment_text": "", "digests": { "md5": "aa10efe8d96c1b40ba9fe06cab4614da", "sha256": "6eb295561c5210174002d987f6a3661abaf5deecf7b31a236cccb5c5eb1f8113" }, "downloads": -1, "filename": "as.recipe.filetemplate-2.2.0-py2.7.egg", "has_sig": false, "md5_digest": "aa10efe8d96c1b40ba9fe06cab4614da", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 27194, "upload_time": "2013-05-03T10:37:36", "url": "https://files.pythonhosted.org/packages/00/bd/4239a09a26397a48bfd6275d8b9a316bf59507e2c0fe529e114f810d09c6/as.recipe.filetemplate-2.2.0-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "d158290712230883860a4637f48b7506", "sha256": "a74d8c9af80002dc84f42dda3830621a26915d3e530da1168193d8e32548e789" }, "downloads": -1, "filename": "as.recipe.filetemplate-2.2.0.tar.gz", "has_sig": false, "md5_digest": "d158290712230883860a4637f48b7506", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25018, "upload_time": "2013-05-03T10:37:40", "url": "https://files.pythonhosted.org/packages/42/2d/8703f43e9e7e8e31a5db6bf03392cf62d6f8207bfbfacca4327c5da4307b/as.recipe.filetemplate-2.2.0.tar.gz" } ], "2.2.1": [ { "comment_text": "", "digests": { "md5": "a7bb2fad4e369b241ce3ae82001d1710", "sha256": "9ea944e40f9d9cb4cc77e8f4382465a18f7a82b369f9e84f9b6a214fd9c4a026" }, "downloads": -1, "filename": "as.recipe.filetemplate-2.2.1-py2.7.egg", "has_sig": false, "md5_digest": "a7bb2fad4e369b241ce3ae82001d1710", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 27198, "upload_time": "2013-05-03T10:45:08", "url": "https://files.pythonhosted.org/packages/f6/b0/9a5a1d1cde816e37281feb16ae209a19cc462849a635e34ddba6e221b2c9/as.recipe.filetemplate-2.2.1-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "60021952e21a00b9beda50219cf3802d", "sha256": "8dcb72113646b3120f6c918ddb6588e1895b9a59fd8564d486cda2fc2d7b8ecb" }, "downloads": -1, "filename": "as.recipe.filetemplate-2.2.1.tar.gz", "has_sig": false, "md5_digest": "60021952e21a00b9beda50219cf3802d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25013, "upload_time": "2013-05-03T10:45:12", "url": "https://files.pythonhosted.org/packages/ff/12/a09e9f27d0773536a99ff8333661cf9c4ca698e9fd5b14a04e57d739e61f/as.recipe.filetemplate-2.2.1.tar.gz" } ], "2.2.2": [ { "comment_text": "", "digests": { "md5": "7eb89927c3dda4010bf4596715a010e2", "sha256": "4413d1d44056604a0ecac5479e791ca1280b7ff2f61b394a5825a2963d596ce2" }, "downloads": -1, "filename": "as.recipe.filetemplate-2.2.2-py2.7.egg", "has_sig": false, "md5_digest": "7eb89927c3dda4010bf4596715a010e2", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 27372, "upload_time": "2013-05-03T12:17:59", "url": "https://files.pythonhosted.org/packages/73/ee/104398159a9324ddcd99c8e504587e547f6823eded24894d0ccd45646c50/as.recipe.filetemplate-2.2.2-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "58275647baf49dcbfb2e76575c5e4ba0", "sha256": "5ed5918c411e3204c055b46206ff59f6045f5fbce2b271df0a4c373a1cc3e701" }, "downloads": -1, "filename": "as.recipe.filetemplate-2.2.2.tar.gz", "has_sig": false, "md5_digest": "58275647baf49dcbfb2e76575c5e4ba0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25090, "upload_time": "2013-05-03T12:18:04", "url": "https://files.pythonhosted.org/packages/c5/48/fdda874be0e2a64adf6d0976b4ab32960d796fb3892c4f6b81da1d5f71b6/as.recipe.filetemplate-2.2.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "7eb89927c3dda4010bf4596715a010e2", "sha256": "4413d1d44056604a0ecac5479e791ca1280b7ff2f61b394a5825a2963d596ce2" }, "downloads": -1, "filename": "as.recipe.filetemplate-2.2.2-py2.7.egg", "has_sig": false, "md5_digest": "7eb89927c3dda4010bf4596715a010e2", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 27372, "upload_time": "2013-05-03T12:17:59", "url": "https://files.pythonhosted.org/packages/73/ee/104398159a9324ddcd99c8e504587e547f6823eded24894d0ccd45646c50/as.recipe.filetemplate-2.2.2-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "58275647baf49dcbfb2e76575c5e4ba0", "sha256": "5ed5918c411e3204c055b46206ff59f6045f5fbce2b271df0a4c373a1cc3e701" }, "downloads": -1, "filename": "as.recipe.filetemplate-2.2.2.tar.gz", "has_sig": false, "md5_digest": "58275647baf49dcbfb2e76575c5e4ba0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25090, "upload_time": "2013-05-03T12:18:04", "url": "https://files.pythonhosted.org/packages/c5/48/fdda874be0e2a64adf6d0976b4ab32960d796fb3892c4f6b81da1d5f71b6/as.recipe.filetemplate-2.2.2.tar.gz" } ] }