跳转到主要内容

用于从文件模板创建文件的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-directoriesbin,则 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.

共享变量

该配方允许使用extends选项扩展一个或多个部分,以减少重复。例如,考虑以下buildout。

>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = message
...
... [template_defaults]
... mygreeting = Hi
... myaudience = World
...
... [message]
... recipe = z3c.recipe.filetemplate
... files = helloworld.txt
... extends = template_defaults
...
... myaudience = everybody
... """)

“message”部分现在从“template_defaults”部分扩展了值,并在本地覆盖。一个模板为${mygreeting}, ${myaudience}!...

>>> update_file(sample_buildout, 'helloworld.txt.in',
... """
... ${mygreeting}, ${myaudience}!
... """)

...因此将产生Hi, everybody!

>>> print system(buildout)
Uninstalling message.
Installing message.
>>> cat(sample_buildout, 'helloworld.txt')
Hi, everybody!

在Python中定义选项

您可以使用interpreted-options指定某些变量应作为Python进行解释。这可以是零行或多行。每行应指定一个选项。它可以立即定义(见下面的示例中的silly-range)或指向要解释的选项,这可以在您想定义多行表达式时很有用(见first-interpreted-optionmessage-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 代码一样,我们不只用‘..’来表示父目录,因为我们想让我们的脚本可以从文件系统的任何地方使用。

获取任意依赖路径

您可以在配方中指定 eggsextra-paths。该机制与 zc.recipe.egg 提供的机制相同,因此有关 find-links 和 index 等相关选项也是可用的。

如果您这样做,将计算依赖项的路径。它们将以列表的形式在解释选项的命名空间中可用,作为 paths。此外,在模板的选项中还将提供三个预定义选项。

如果 paths 是路径,shell_pathshell-path 过滤器,path_reprpath-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-pathsspace-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-pathsspace-paths)或 ${python-relative-path-setup}(用于 string-paths),否则您的脚本实际上是不会工作的。

zc.recipe.egg 获取依赖路径

您可以使用 zc.recipe.egg 在上面的“共享变量”部分中使用的“extends”选项,从另一个部分获取eggsextra-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.txtC:\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 中为模板定义选项值。

  • 通过指定 eggsextra-paths 获取 eggs 的路径,就像 zc.recipe.egg 脚本食谱一样。这些路径以冒号分隔、空格分隔和引号分隔的变体形式可用。您还可以使用 interpreted-options 功能构建自己的路径。

  • 如果没有对模板或 buildout 进行更改,则不会处理模板。

1.0 (2007-09-30)

首次发布。

项目详情


下载文件

下载适合您平台文件的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源分布

z3c.recipe.filetemplate-2.2.0.tar.gz (36.4 kB 查看哈希值)

上传时间

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面