用于从文件模板创建文件的zc.buildout配方
项目描述
基本用法
使用z3c.recipe.filetemplate buildout配方,您可以自动化从模板生成文本文件。在执行时,该配方将读取一些模板文件,执行变量替换,并将结果写入相应的输出文件。
该配方具有多个功能,但它始终处理具有.in后缀的模板文件,处理模板,并将文件以相同的文件模式写入到期望的位置,文件名相同,但不带.in后缀。
例如,考虑以下简单的文本文件模板
>>> write(sample_buildout, 'helloworld.txt.in', ... """ ... Hello ${world}! ... """)
现在我们来创建一个buildout配置,以便我们可以替换文件中的值。我们只需定义一个使用 z3c.recipe.filetemplate 菜单的部分。通过 files 参数,我们指定一个或多个需要替换的文件(用空格分隔)。然后我们可以在该部分中添加任意参数。这些参数将用于填充模板中的变量。
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... parts = message ... ... [message] ... recipe = z3c.recipe.filetemplate ... files = helloworld.txt ... world = Philipp ... """)
执行buildout后,我们可以看到 ${world} 确实被替换成了 Philipp
>>> print system(buildout) Installing message.>>> cat(sample_buildout, 'helloworld.txt') Hello Philipp!
如果您需要转义 ${…} 模式,可以通过重复美元符号来实现。
>>> update_file(sample_buildout, 'helloworld.txt.in', ... """ ... Hello world! The double $${dollar-sign} escapes! ... """)>>> print system(buildout) Uninstalling message. Installing message.>>> cat(sample_buildout, 'helloworld.txt') Hello world! The double ${dollar-sign} escapes!
请注意,单独的美元符号,没有花括号,不会进行解析。
>>> update_file(sample_buildout, 'helloworld.txt.in', ... """ ... $Hello $$world! $$$profit! ... """)>>> print system(buildout) Uninstalling message. Installing message.>>> cat(sample_buildout, 'helloworld.txt') $Hello $$world! $$$profit!
请注意,输出文件使用的权限位与输入文件相同。
>>> import stat >>> import os >>> input = os.path.join(sample_buildout, 'helloworld.txt.in') >>> output = input[:-3] >>> os.chmod(input, 0755) >>> stat.S_IMODE(os.stat(input).st_mode) == 0755 True >>> stat.S_IMODE(os.stat(output).st_mode) == 0755 False >>> print system(buildout) Uninstalling message. Installing message. >>> stat.S_IMODE(os.stat(output).st_mode) == 0755 True
源文件夹和Glob
默认情况下,该菜单在buildout根目录下查找 .in 文件,并将其放置在相同的文件夹中。但是,如果您不想使目标文件夹变得杂乱,您可以为源文件夹添加一个前缀。以下是一个示例。
首先,在buildout中指定一个 source-directory。如果您愿意,可以将 files 作为过滤器指定,但默认情况下它将找到任何文件(以“ .in”结尾)。您还可以指定 exclude-directories 选项,如果您想从 source-directory 搜索路径中排除一些路径。
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... parts = message ... ... [message] ... recipe = z3c.recipe.filetemplate ... source-directory = template ... world = Philipp ... """)
现在我们将创建一个“模板”目录,如上面的buildout配置中列出,并为我们示例填充它。
>>> mkdir(sample_buildout, 'template') >>> mkdir(sample_buildout, 'template', 'etc') >>> mkdir(sample_buildout, 'template', 'bin') >>> write(sample_buildout, 'template', 'etc', 'helloworld.conf.in', ... """ ... Hello ${world} from the etc dir! ... """) >>> write(sample_buildout, 'template', 'bin', 'helloworld.sh.in', ... """ ... Hello ${world} from the bin dir! ... """) >>> os.chmod( ... os.path.join( ... sample_buildout, 'template', 'bin', 'helloworld.sh.in'), ... 0711)
请注意,在运行buildout之前,helloworld.txt 文件仍然存在,我们没有etc目录,bin目录中没有我们的 helloworld.sh。
>>> ls(sample_buildout) - .installed.cfg d bin - buildout.cfg d develop-eggs d eggs - helloworld.txt - helloworld.txt.in d parts d template >>> ls(sample_buildout, 'bin') - buildout
现在我们进行安装。旧的“helloworld.txt”已经消失,我们现在看到etc。请注意,对于目标,如果它们不存在,将创建中间文件夹。
>>> print system(buildout) Uninstalling message. Installing message. >>> ls(sample_buildout) - .installed.cfg d bin - buildout.cfg d develop-eggs d eggs d etc - helloworld.txt.in d parts d template
文件存在,并且包含我们预期的内容。
>>> ls(sample_buildout, 'bin') - buildout - helloworld.sh >>> cat(sample_buildout, 'bin', 'helloworld.sh') Hello Philipp from the bin dir! >>> stat.S_IMODE(os.stat(os.path.join( ... sample_buildout, 'bin', 'helloworld.sh')).st_mode) == 0711 True >>> ls(sample_buildout, 'etc') - helloworld.conf >>> cat(sample_buildout, 'etc', 'helloworld.conf') Hello Philipp from the etc dir!
如果您使用 files 选项以及 source-directory,它将变成一个过滤器。每个目标文件必须至少匹配 files 中的名称之一。因此,如果我们只构建 .sh 文件,etc目录将消失。
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... parts = message ... ... [message] ... recipe = z3c.recipe.filetemplate ... source-directory = template ... files = *.sh ... world = Philipp ... """)>>> print system(buildout) Uninstalling message. Installing message. >>> ls(sample_buildout) - .installed.cfg d bin - buildout.cfg d develop-eggs d eggs - helloworld.txt.in d parts d template>>> ls(sample_buildout, 'bin') - buildout - helloworld.sh
请注意,如果您使用源目录,并且您的 files 指定了一个目录,则该目录必须精确匹配。
使用 exclude-directories 参数,我们指定一个或多个目录(用空格分隔),在该目录中该菜单不会查找模板文件。应与 source-directory 选项一起使用 exclude-directories 选项。因此,如果我们设置 exclude-directories 为 bin,则 bin/helloworld.sh 文件将消失。
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... parts = message ... ... [message] ... recipe = z3c.recipe.filetemplate ... source-directory = template ... exclude-directories = bin ... world = Philipp ... """)>>> print system(buildout) Uninstalling message. Installing message. >>> ls(sample_buildout) - .installed.cfg d bin - buildout.cfg d develop-eggs d eggs d etc - helloworld.txt.in d parts d template>>> ls(sample_buildout, 'etc') - helloworld.conf>>> ls(sample_buildout, 'bin') - buildout>>> # Clean up for later test. >>> import shutil >>> shutil.rmtree(os.path.join(sample_buildout, 'template', 'etc')) >>> os.remove(os.path.join( ... sample_buildout, 'template', 'bin', 'helloworld.sh.in'))
高级用法
从其他部分替换
替换也可以从buildout中的其他部分获取,使用标准的buildout语法,但在模板中使用。注意以下模板中的 ${buildout:parts}。
>>> update_file(sample_buildout, 'helloworld.txt.in', ... """ ... Hello ${world}. I used these parts: ${buildout:parts}. ... """) >>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... parts = message ... ... [message] ... recipe = z3c.recipe.filetemplate ... files = helloworld.txt ... world = Philipp ... """)>>> print system(buildout) Uninstalling message. Installing message.>>> cat(sample_buildout, 'helloworld.txt') Hello Philipp. I used these parts: message.
路径扩展
替换可以使用POSIX“/”路径分隔符具有路径后缀。模板将这些转换为当前OS的正确路径分隔符。它们也是传递给过滤器的值的组成部分,这是下一个要描述的功能。注意以下模板中的 ${buildout:directory/foo/bar.txt}。
>>> update_file(sample_buildout, 'helloworld.txt.in', ... """ ... Here's foo/bar.txt in the buildout: ... ${buildout:directory/foo/bar.txt} ... """)>>> print system(buildout) Uninstalling message. Installing message.>>> cat(sample_buildout, 'helloworld.txt') # doctest: +ELLIPSIS Here's foo/bar.txt in the buildout: /.../sample-buildout/foo/bar.txt
过滤器
您可以在替换中使用管道来过滤原始值。该菜单提供了一些供您使用的过滤器。语法类似于(并受启发于)POSIX管道和Django模板过滤器。例如,如果 world = Philipp,HELLO ${world|upper}! 将会产生 HELLO PHILIPP!。
目前暴露了一些简单的Python字符串方法作为过滤器
首字母大写:字符串中的第一个字母被大写。
小写:字符串中的所有字母都是小写的。
标题:字符串中每个单词的首字母都大写。
大写:字符串中的所有字母都是大写的。
如果buildout的relative-paths选项为true,其他过滤器对于处理路径非常重要。有关更多详细信息,请参阅使用路径。
path-repr:将路径转换为Python表达式。如果buildout的relative-paths选项为false,这将只是一个绝对路径的repr。如果relative-paths为true,这将是一个函数调用,用于将buildout相对路径转换为绝对路径;它要求在模板中更早地包含${python-relative-path-setup}。
shell-path:将路径转换为shell表达式。目前仅支持POSIX。如果buildout的relative-paths选项为false,这将只是一个绝对路径。如果relative-paths为true,这将是一个将buildout相对路径转换为绝对路径的表达式;它要求在模板中更早地包含${shell-relative-path-setup}。
结合到目前为止已描述的三个高级功能,如果buildout relative-paths选项为false,我们在POSIX系统上,并且示例buildout在系统的根目录,模板表达式${buildout:bin-directory/data/initial.csv|path-repr}将导致'/sample-buildout/bin/data/initial.csv'。
以下是一个字符串方法过滤器的实际、有效示例。我们将路径过滤器的示例放在使用路径部分。
>>> update_file(sample_buildout, 'helloworld.txt.in', ... """ ... HELLO ${world|upper}! ... hello ${world|lower}. ... ${name|title} and the Chocolate Factory ... ${sentence|capitalize} ... """)>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... parts = message ... ... [message] ... recipe = z3c.recipe.filetemplate ... files = helloworld.txt ... world = Philipp ... name = willy wonka ... sentence = that is a good book. ... """)>>> print system(buildout) Uninstalling message. Installing message.>>> cat(sample_buildout, 'helloworld.txt') # doctest: +ELLIPSIS HELLO PHILIPP! hello philipp. Willy Wonka and the Chocolate Factory That is a good book.
在Python中定义选项
您可以使用interpreted-options
指定某些变量应作为Python进行解释。这可以是零行或多行。每行应指定一个选项。它可以立即定义(见下面的示例中的silly-range
)或指向要解释的选项,这可以在您想定义多行表达式时很有用(见first-interpreted-option
和message-reversed-is-egassem
)。
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... parts = message ... ... [message] ... recipe = z3c.recipe.filetemplate ... files = helloworld.txt ... interpreted-options = silly-range = repr(range(5)) ... first-interpreted-option ... message-reversed-is-egassem ... first-interpreted-option = ... options['interpreted-options'].splitlines()[0].strip() ... message-reversed-is-egassem= ... ''.join( ... reversed( ... buildout['buildout']['parts'])) ... not-interpreted=hello world ... """)>>> update_file(sample_buildout, 'helloworld.txt.in', """\ ... ${not-interpreted}! ... silly-range: ${silly-range} ... first-interpreted-option: ${first-interpreted-option} ... message-reversed-is-egassem: ${message-reversed-is-egassem} ... """)>>> print system(buildout) Uninstalling message. Installing message.>>> cat(sample_buildout, 'helloworld.txt') # doctest:+ELLIPSIS hello world! silly-range: [0, 1, 2, 3, 4] first-interpreted-option: silly-range = repr(range(5)) message-reversed-is-egassem: egassem
使用路径
我们已经在讨论过滤器时提到了如何处理buildout的relative-paths选项。本节提供了一些具体的示例和讨论。它还介绍了如何通过指定依赖关系来获取一系列路径。
以下是path-repr和shell-path过滤器的具体示例。我们将展示在relative-paths为true和为false时的结果。
path-repr的演示
假设我们想在bin目录中创建一个自定义Python脚本。它将从buildout根目录下的data目录中的一个文件中打印一些信息。这是模板。
>>> write(sample_buildout, 'template', 'bin', 'dosomething.py.in', '''\ ... #!${buildout:executable} ... ${python-relative-path-setup} ... f = open(${buildout:directory/data/info.csv|path-repr}) ... print f.read() ... ''') >>> os.chmod( ... os.path.join( ... sample_buildout, 'template', 'bin', 'dosomething.py.in'), ... 0711)
如果我们将此模板与relative-paths设置为false进行评估,结果不应该令人惊讶。
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... parts = message ... ... [message] ... recipe = z3c.recipe.filetemplate ... source-directory = template ... """)>>> print system(buildout) Uninstalling message. Installing message.>>> cat(sample_buildout, 'bin', 'dosomething.py') # doctest: +ELLIPSIS #!... <BLANKLINE> f = open('/.../sample-buildout/data/info.csv') print f.read()
${python-relative-path-setup}评估为空字符串。路径是绝对的和带引号的。
如果我们使用relative-paths设置为true来评估它,结果将大得多。
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... parts = message ... relative-paths = true ... ... [message] ... recipe = z3c.recipe.filetemplate ... source-directory = template ... """)>>> print system(buildout) Uninstalling message. Installing message.>>> cat(sample_buildout, 'bin', 'dosomething.py') # doctest: +ELLIPSIS #!... import os, imp # Get path to this file. if __name__ == '__main__': _z3c_recipe_filetemplate_filename = __file__ else: # If this is an imported module, we want the location of the .py # file, not the .pyc, because the .py file may have been symlinked. _z3c_recipe_filetemplate_filename = imp.find_module(__name__)[1] # Get the full, non-symbolic-link directory for this file. _z3c_recipe_filetemplate_base = os.path.dirname( os.path.abspath(os.path.realpath(_z3c_recipe_filetemplate_filename))) # Ascend to buildout root. _z3c_recipe_filetemplate_base = os.path.dirname( _z3c_recipe_filetemplate_base) def _z3c_recipe_filetemplate_path_repr(path): "Return absolute version of buildout-relative path." return os.path.join(_z3c_recipe_filetemplate_base, path) <BLANKLINE> f = open(_z3c_recipe_filetemplate_path_repr('data/info.csv')) print f.read()
这是一段相当多的代码。您可能会想知道为什么我们不直接使用‘..’来表示父目录。原因是我们希望我们的脚本可以从文件系统的任何地方使用。如果我们使用‘..’来构建相对于生成的文件的路径,那么这些路径将只能从某些目录中工作。
这就是路径表示法的原理。如果您想在 buildout 中支持相对路径,这会非常有用。现在让我们来看看 shell-path 过滤器。
演示 shell-path
也许您想编写一些 shell 脚本。shell-path 过滤器可以帮助您相对容易地支持 buildout 的相对路径。
目前,shell-path 过滤器只支持 POSIX,如前所述。
用法与 path-repr 过滤器非常相似。在使用它之前,您需要包含 ${shell-relative-path-setup},就像在使用 path-repr 之前包含 ${python-relative-path-setup} 一样。
假设我们想在 bin 目录中创建一个自定义 shell 脚本。它将从 buildout 根目录下的 data 目录中的文件打印一些信息。以下是模板。
>>> write(sample_buildout, 'template', 'bin', 'dosomething.sh.in', '''\ ... #!/bin/sh ... ${shell-relative-path-setup} ... cat ${buildout:directory/data/info.csv|shell-path} ... ''') >>> os.chmod( ... os.path.join( ... sample_buildout, 'template', 'bin', 'dosomething.sh.in'), ... 0711)
如果 relative-paths 设置为 false(默认值),则结果很简单。
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... parts = message ... ... [message] ... recipe = z3c.recipe.filetemplate ... source-directory = template ... """)>>> print system(buildout) Uninstalling message. Installing message.>>> cat(sample_buildout, 'bin', 'dosomething.sh') # doctest: +ELLIPSIS #!/bin/sh <BLANKLINE> cat /.../sample-buildout/data/info.csv
${shell-relative-path-setup} 评估为空字符串。路径是绝对的。
现在让我们看看当 relative-paths 设置为 true 时的较大代码。
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... parts = message ... relative-paths = true ... ... [message] ... recipe = z3c.recipe.filetemplate ... source-directory = template ... """)>>> print system(buildout) Uninstalling message. Installing message.>>> cat(sample_buildout, 'bin', 'dosomething.sh') # doctest: +ELLIPSIS #!/bin/sh # Get full, non-symbolic-link path to this file. Z3C_RECIPE_FILETEMPLATE_FILENAME=`\ readlink -f "$0" 2>/dev/null || \ realpath "$0" 2>/dev/null || \ type -P "$0" 2>/dev/null` # Get directory of file. Z3C_RECIPE_FILETEMPLATE_BASE=`dirname ${Z3C_RECIPE_FILETEMPLATE_FILENAME}` # Ascend to buildout root. Z3C_RECIPE_FILETEMPLATE_BASE=`dirname ${Z3C_RECIPE_FILETEMPLATE_BASE}` <BLANKLINE> cat "$Z3C_RECIPE_FILETEMPLATE_BASE"/data/info.csv
与 Python 代码一样,我们不只用‘..’来表示父目录,因为我们想让我们的脚本可以从文件系统的任何地方使用。
获取任意依赖路径
您可以在配方中指定 eggs 和 extra-paths。该机制与 zc.recipe.egg 提供的机制相同,因此有关 find-links 和 index 等相关选项也是可用的。
如果您这样做,将计算依赖项的路径。它们将以列表的形式在解释选项的命名空间中可用,作为 paths。此外,在模板的选项中还将提供三个预定义选项。
如果 paths 是路径,shell_path 是 shell-path 过滤器,path_repr 是 path-repr 过滤器,则预定义选项大致定义如下
- os-paths(用于 shell 脚本)
(os.pathsep).join(shell_path(path) for path in paths)
- string-paths(用于 Python 脚本)
',\n '.join(path_repr(path) for path in paths)
- space-paths(用于 shell 脚本)
' '.join(shell_path(path) for path in paths)
因此,如果您想支持 relative-paths 选项,则应在模板的顶部相应地包含 ${shell-relative-path-setup}(用于 os-paths 和 space-paths)或 ${python-relative-path-setup}(用于 string-paths)。
让我们考虑一个简单的示例。
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... parts = message ... ... [message] ... recipe = z3c.recipe.filetemplate ... files = helloworld.txt ... eggs = demo<0.3 ... ... find-links = %(server)s ... index = %(server)s/index ... """ % dict(server=link_server))
relative-paths 选项为 false,这是默认值。
>>> write(sample_buildout, 'helloworld.txt.in', ... """ ... Hello! Here are the paths for the ${eggs} eggs. ... OS paths: ... ${os-paths} ... --- ... String paths: ... ${string-paths} ... --- ... Space paths: ... ${space-paths} ... """)>>> print system(buildout) Getting distribution for 'demo<0.3'. Got demo 0.2. Getting distribution for 'demoneeded'. Got demoneeded 1.2c1. Uninstalling message. Installing message.>>> cat(sample_buildout, 'helloworld.txt') # doctest:+ELLIPSIS Hello! Here are the paths for the demo<0.3 eggs. OS paths: /.../eggs/demo-0.2...egg:/.../eggs/demoneeded-1.2c1...egg --- String paths: '/.../eggs/demo-0.2...egg', '/.../eggs/demoneeded-1.2c1...egg' --- Space paths: /.../eggs/demo-0.2...egg /.../eggs/demoneeded-1.2c1...egg
您还可以指定 extra-paths,它将位于 egg 路径的末尾。
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... parts = message ... ... [message] ... recipe = z3c.recipe.filetemplate ... files = helloworld.txt ... eggs = demo<0.3 ... extra-paths = ${buildout:directory}/foo ... ... find-links = %(server)s ... index = %(server)s/index ... """ % dict(server=link_server))>>> print system(buildout) Uninstalling message. Installing message.>>> cat(sample_buildout, 'helloworld.txt') # doctest:+ELLIPSIS Hello! Here are the paths for the demo<0.3 eggs. OS paths: /...demo...:/...demoneeded...:/.../sample-buildout/foo --- String paths: '/...demo...', '/...demoneeded...', '/.../sample-buildout/foo' --- Space paths: /...demo... /...demoneeded... .../sample-buildout/foo
为了强调 relative-paths 选项的影响,让我们看看当我们设置 relative-paths 为 True 时会发生什么。
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... parts = message ... relative-paths = true ... ... [message] ... recipe = z3c.recipe.filetemplate ... files = helloworld.txt ... eggs = demo<0.3 ... extra-paths = ${buildout:directory}/foo ... ... find-links = %(server)s ... index = %(server)s/index ... """ % dict(server=link_server))>>> print system(buildout) Uninstalling message. Installing message.>>> cat(sample_buildout, 'helloworld.txt') # doctest:+ELLIPSIS Hello! Here are the paths for the demo<0.3 eggs. OS paths: "$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 --- String paths: _z3c_recipe_filetemplate_path_repr('eggs/demo-0.2-py...egg'), _z3c_recipe_filetemplate_path_repr('eggs/demoneeded-1.2c1-py...egg'), _z3c_recipe_filetemplate_path_repr('foo') --- Space paths: "$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
请记住,除非您在模板的顶部相应地包含 ${shell-relative-path-setup}(用于 os-paths 和 space-paths)或 ${python-relative-path-setup}(用于 string-paths),否则您的脚本实际上是不会工作的。
从 zc.recipe.egg 获取依赖路径
您可以使用 zc.recipe.egg 在上面的“共享变量”部分中使用的“extends”选项,从另一个部分获取eggs和extra-paths。然后,您可以使用上面描述的模板选项来构建模板中的路径。
从z3c.recipe.scripts获取依赖路径
如果您像Launchpad项目一样,正在使用Gary Poster尚未发布的包z3c.recipe.scripts来生成脚本,并且希望脚本使用该配方生成的相同Python环境,您只需使用标准buildout目录中的path-repr和shell-path过滤器即可。以下是一个示例buildout.cfg。
[buildout] parts = scripts message relative-paths = true [scripts] recipe = z3c.recipe.scripts eggs = demo<0.3 [message] recipe = z3c.recipe.filetemplate files = helloworld.py
然后,使用此模板时,应在Python的路径开头简单地放置${scripts:parts-directory|path-repr}。
您可以使用PYTHONPATH对子进程这样做。
${python-relative-path-setup} import os import subprocess env = os.environ.copy() env[‘PYTHONPATH’] = ${scripts:parts-directory|path-repr} subprocess.call(‘myscript’, env=env)
就是这样。
同样,这里有一个创建正确环境的脚本的方法。您想在site.py加载之前将z3c.recipe.scripts部分的部件目录放在sys.path中。这通常由z3c.recipe.scripts本身处理,但有时您可能出于某些原因要在模板中编写Python脚本。
#!/usr/bin/env python -S ${python-relative-path-setup} import sys sys.path.insert(0, ${scripts:parts-directory|path-repr}) import site # do stuff…
如果您为许多脚本这样做,请将整个片段放入配方中的选项中,并在脚本顶部使用此片段作为单个替换。
更改
2.2.0 (2011-09-01)
功能
添加对使用exclude-directories选项排除source-directory的一些子目录的支持。[Bruno Binet]
修复
在测试额外中添加了对未声明但必需的测试依赖项zope.testing。
添加了对z3c.recipe.scripts的测试依赖项,因为它需要较新的zc.buildout版本。
使用python的doctest模块而不是已弃用的zope.testing.doctest。
2.1.0 (2010-04-21)
功能
通过允许路径后缀的扩展语法启用跨平台路径。例如:如果${buildout:directory}在POSIX系统上解析为/sample_buildout,而在Windows中为C:\sample_buildout,则${buildout:directory/foo.txt}将分别解析为/sample_buildout/foo.txt和C:\sample_buildout\foo.txt。
通过管道语法添加过滤器,类似于UNIX管道或Django模板过滤器。简单示例:如果${name}解析为harry,则${name|upper}解析为HARRY。简单的字符串过滤器是upper、lower、title和capitalize,就像Python字符串方法一样。也请参阅下一项。
添加了对buildout相对路径选项的支持。Shell脚本应在执行具有buildout生成的路径的命令之前包含${shell-relative-path-setup}。Python脚本应类似地使用${python-relative-path-setup}。当使用buildout相对路径选项时,${os-paths}(shell)、${space-paths}(shell)和${string-paths}(Python)将具有相对路径。${path-repr}过滤器用于Python脚本中的单个绝对路径到相对路径的转换,而shell-path过滤器用于shell脚本。路径后缀可以与这些过滤器结合使用,因此,如果buildout的相对路径选项为true,${buildout:directory/foo.txt|path-repr}将生成到foo.txt的buildout相对、平台适当的路径。请注意,对于shell脚本,目前不支持Windows。
在模板中支持使用 $${...} 来转义 ${...},这在 UNIX shell 脚本中特别有用。
修复
使测试更不易受到时间错误的影响。
更改
${os-paths} 和 ${space-paths} 不再过滤出 .zip 路径。
${string-paths} 中的条目现在由换行符分隔。每个条目都缩进到标记初始放置的级别。
2.0.3 (2009-07-02)
修复
在 buildout 目录上使用 zc.buildout 的 realpath 辅助函数,这样它就可以与比较的路径进行相同的归一化,并且由于可能的驱动器字母大小写差异,有可能在 Windows 上工作。
2.0.2 (2009-05-04)
修复
事实证明,对路径进行排序是个坏主意。根据我的了解,由于处理依赖关系的顺序,它们已经处于确定性的顺序,但在实践中,排序使它们在机器之间变得 不那么 确定性。
2.0.1 (2009-04-30)
修复
正确地生成 sdist 以包括所有必要的文件。
文档格式化修复。
将“目标已存在”消息更正为列出不带 .in 后缀的目标。
2.0 (2009-04-30)
功能
使用 source-directory 选项将模板文件存储在单独的目录结构中。
使用 glob 自动指定多个文件。
模板可以使用常规语法引用其他 buildout 部分,例如 ${buildout:parts}
使用典型 extends 选项与其他部分共享选项。
自动创建目标目录。
使用 interpreted-options 选项动态地在 Python 中为模板定义选项值。
通过指定 eggs 和 extra-paths 获取 eggs 的路径,就像 zc.recipe.egg 脚本食谱一样。这些路径以冒号分隔、空格分隔和引号分隔的变体形式可用。您还可以使用 interpreted-options 功能构建自己的路径。
如果没有对模板或 buildout 进行更改,则不会处理模板。
1.0 (2007-09-30)
首次发布。
项目详情
下载文件
下载适合您平台文件的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。
源分布
z3c.recipe.filetemplate-2.2.0.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 9bbc278b7b119051248dabb1e62454d3b250507bc4dc237e27b84b52ec145c70 |
|
MD5 | 0c5b759b81b13021e87347fd0343a627 |
|
BLAKE2b-256 | b19d6aa1d220236c250d69ca595a13d7df7e0d93e3ae4e51d31ddc20390516ae |