使用Python在zc.buildout中编写配置
项目描述
Mr.Scripty
通过在zc.buildout中直接使用Python来快速构建配方的方法
支持选项
该配方支持任意数量的选项,这些选项是Python函数。由于与buildout一起使用的ini解析器不会保留初始空白,因此您的每个方法行应从…开始,后面跟着正常的Python空白。它们看起来像这样
[myscripts] recipe = mr.scripty MAX = 10 function1 = ... x = range(1,int(self.MAX)) ... return ' '.join(x) [myrecipe] recipe = something.recipe argument = ${myscripts:function1}
返回值将作为buildout部分选项中的一个值存储,该值可用于其他buildout部分的替换。返回的内容始终被转换为字符串。
函数与常量
所有大写字母的选项被视为字符串常量,并作为属性添加到Recipe实例中。所有其他选项都将被视为Python函数。
由于每个选项都是一个Python函数或变量,它需要具备可接受的函数标识符(请参阅https://docs.pythonlang.cn/reference/lexical_analysis.html#grammar-token-identifier)。例如,带有连字符的典型buildout选项(如environment-vars)将无效。
由于这些函数实际上是方法,所以局部变量self可用于引用配方实例。self.options、self.buildout和self.name都是可用的。
以_开头的任何选项都不会被评估,因此可以用作私有函数。
初始化、安装和更新
有三个特殊函数,无论它们是否从另一个配方中调用,其值都不会被存储。
init:每次配方被加载时都会调用init。此函数允许您减少可能执行类似工作的多个函数的需求,无需使用虚拟选项来执行任意代码(以及其他用途),如下所示
[myscripts] recipe = mr.scripty init = ... import math ... self.options['pi'] = str(math.pi) ... self.options['e'] = str(math.e) ... self.options['sqrt_two'] = str(math.sqrt(2))
运行buildout后,选项pi、e和sqrt_two都将可用于在myscripts部分中使用,如下所示:${myscripts:sqrt_two}。有关更多信息,请参阅有关调整端口号的示例。
install:如果自上次运行以来参数(函数或常量)已更改或尚未运行过,则调用install。
update:每次(但之后init)都会调用update
这些可以用作快速原地替换创建实际配方的替代方案,并且与http://www.buildout.org/en/latest/docs/tutorial.html?highlight=update#writing-recipes中详细说明的语义相同。
错误和仓库
示例
将Varnish后端转换为HAProxy
假设您想将varnish:backends值转换为可在haproxy内部使用的值
>>> write('buildout.cfg', ... """ ... [buildout] ... parts = scripty echobackends echorepeat ... ... [varnish] ... backends = ... myhost.com:255.255.255.1 ... myhost2.com:125.125.125.1 ... ... [scripty] ... recipe = mr.scripty ... backends = ... ... res = "" ... ... for line in self.buildout['varnish']['backends'].splitlines(): ... ... if ':' not in line: ... ... continue ... ... host, dest = line.strip().split(':') ... ... host = host.split('.')[0] ... ... res += "acl {} url_sub VirtualHostRoot/{}\\n".format(host, dest) ... ... return res ... repeat = ... ... opt_repeatx = int('10') ... ... fun_repeatx = self.repeatx() ... ... return '\\n'.join(["this is line %s"%i for i in range(1,opt_repeatx+1)]) ... repeatx = return '10' ... ... [echobackends] ... recipe = mr.scripty ... install = print(self.buildout['scripty']['backends']); return [] ... ... [echorepeat] ... recipe = mr.scripty ... install = ... ... script = self.buildout['scripty'] ... ... print(script['repeat']) ... ... return [] ... """)
运行buildout后,我们得到
>>> print(system(buildout)) Installing scripty. Installing echobackends. acl myhost url_sub VirtualHostRoot/255.255.255.1 acl myhost2 url_sub VirtualHostRoot/125.125.125.1 Installing echorepeat. this is line 1 this is line 2 this is line 3 this is line 4 this is line 5 this is line 6 this is line 7 this is line 8 this is line 9 this is line 10...
从本例中您会注意到几个问题。属于mr.scripty部分的选项被转换为部分实例的方法,并且可以相互调用。此外,可以通过通过${part:method}或通过代码中的self.buildout[part][method]访问选项来从其他buildout配方中调用每个方法。
偏移端口号
以下示例将使所有ports_base的值可用,并在每个值上添加一个偏移量。此示例演示了特殊的init选项,它允许您运行一个特殊的函数,其中结果不会被存储在buildout的部分中
[ports_base] instance1=8101 instance2=8102 [ports] recipe = mr.scripty OFFSET = 1000 init = ... for key,value in self.buildout['ports_base'].items(): ... self.options[key] = str(int(value)+int(self.OFFSET))
因此,使用 init 可以让我们使用任意代码创建针对 [ports] 节的选项。在上面的例子中,这会将 [ports_base] 下的所有选项处理为向端口添加 OFFSET 值。最终结果是,buildout 的其他部分现在可以引用 ${ports:instance1} 和 ${ports:instance2},它们分别具有 9101 和 9102 的值。
特定架构的不同下载链接
此示例用法演示了如何根据宿主平台是 32 位还是 64 位来更改第三方库的下载链接。请注意,此示例使用 Python 2.6 或更高版本。
[buildout] parts = ... download [scripty] recipe = mr.scripty DOWNLOAD_URL_64 = http://site.com/64bit.tgz DOWNLOAD_URL_32 = http://site.com/32bit.tgz download_url = ... import platform ... is_64bit = any(['64' in x for x in platform.architecture()]) ... return is_64bit and self.DOWNLOAD_URL_64 or self.DOWNLOAD_URL_32 [download] recipe = hexagonit.recipe.download url = ${scripty:download_url}
检查目录是否存在
此示例测试目录列表的存在性,并选择系统上可以找到的第一个目录。在这个特定的例子中,我们检查潜在 JDK 目录列表,因为 Linux 发行版之间的位置不同,以便安装一个依赖于 Java SDK 安装可用的 egg。
[buildout] parts = ... jpype [scripty] recipe = mr.scripty JAVA_PATHS = /usr/lib/jvm/java-6-openjdk /etc/alternatives/java_sdk ${buildout:directory} java = ... import os ... paths = self.JAVA_PATHS.split('\n') ... exists = [os.path.exists(path) for path in paths] ... return paths[exists.index(True)] [java-env] JAVA_HOME = ${scripty:java} [jpype] recipe = zc.recipe.egg:custom egg = JPype find-links = http://aarnet.dl.sourceforge.net/project/jpype/JPype/0.5.4/JPype-0.5.4.1.zip environment = java-env
贡献者
“software@dylanjay.com”,Dylan Jay
变更历史
1.0 (2016-11-16)
支持 Python 3.4。这与 Python 2.6 及之前版本不兼容。[Sylvain Viollon]
与 travis, coveralls 集成 - [abdul.maliyakkal]
改进说明文件 [djay]
1.0b3 (2011-12-14)
更新文档,添加更多示例。[davidjb]
修复缩进问题 [djay]
init 作为特殊函数处理,其结果不存储 [djay]
1.0b2 (2011-03-23)
如果选项全部为大写,允许常量 [djay]
函数返回值转换为字符串或空字符串(如果为 None)[djay]
1.0b1 (2011-03-15)
初始版本 [“Dylan Jay”, djay]
项目详情
mr.scripty-1.0.tar.gz 的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | 50f7a694cdf21c13659e2617593eae318dbeb95fc2f6280aee91c9151908fbf3 |
|
MD5 | a560ff4b20fb6e50ce31b278bb4a541a |
|
BLAKE2b-256 | 28dd4d7d951077aef2d6f8e188977ad8c1ffb2d02da20077319731ca01b9b7bf |