如果你曾经是java开发者并开始写python,那么你一定十分怀念maven的依赖管理和自动构建功能。你可能已经接触过easy_install, pip, virtualenv等工具,但这些工具并不能完全解决问题。而zc.buildout恰好是你需要的答案。buildout不但能够像setuptools一样自动更新或下载安装依赖包,而且还能够像virtualenv一样,构建一个封闭的开发环境。
zc.buildout是一个基于python的构建(build)系统,通过一个配置文件,可以从多个部分创建、组装并部署你的应用,即使应用包含了非python的组成部分,buildout也能够胜任。
buildout最早由Zope团队的Jim Fulton创建,后来被很多python项目和社区使用并获得了极高的评价。比如Django的创建者Jacob Kaplan-Moss评价说,buildout是部署应用的一种非常文明的方式。另一个比较夸张的评价来自《Python For Unix and Linux》的合著者Noah Gift,由于xxx的原因(你懂的)就不翻译了,原文如下:
"While not directly aiming to solve world peace, it perhaps will play a role in the future, as people will be less angry about application deployment and will have more time for making love and music."
使用zc.buildout创建项目
使用zc.buildout创建项目非常容易。首先安装zc.buildout(可以使用easy_install或pip),
然后在项目文件夹中运行buildout init:
$ mkdir newproject
$ cd newproject/
$ buildout init
Creating '.../newproject/buildout.cfg'.
Creating directory '.../newproject/bin'.
Creating directory '.../newproject/parts'.
Creating directory '.../newproject/eggs'.
Creating directory '.../newproject/develop-eggs'.
Generated script '.../newproject/bin/buildout'.
其中,buildout.cfg是配置文件,类似于maven的pom文件,而bin/buildout是build脚本。
当共享代码的时候,只有buildout.cfg需要加入版本控制。checkout之后,只需要运行buildout bootstrap,就可以再次生成这些文件夹和文件。
当然,作为一个文明人,你不必要求其他人也安装zc.buildout,只需要下载bootstrap.py(也可以用buildout bootstrap生成)并将这个文件也加入版本控制。这样,其他人可以通过运行bootstrap.py生成需要的文件。
整个过程如果出现DistributionNotFound之类的错误,一般是由于不干净的环境造成的,通过virtualenv创建全新的环境通常可以解决。
buildout配置
先看一下buildout.cfg的一个例子:
[buildout]
develop = .
parts =
xprompt
test
[xprompt]
recipe = zc.recipe.egg:scripts
eggs = xanalogica.tumbler
interpreter = xprompt
[test]
recipe = zc.recipe.testrunner
eggs = xanalogica.tumbler
buildout.cfg使用ini格式。其中[buildout]是必须的节。在本节中,可以定义:
develop = .
指定一个或多个要开发的模块,将会被build成develop-eggs下面的egg。每个develop目录下都需要有一个setup.py文件。
对于单个模块的应用,可以用“.”指定使用当前目录,对于多模块应用,可以分别指定各个模块的文件夹。
parts =
xprompt
test
每个buildout可能需要很多个部件(part),parts指定了哪些部件需要build。如果一个部件依赖其他的部件,则被依赖的部件会被首先build。这里面指定了两个部件:xprompt和test。每个part中还可以用parts指定自己的子部件。
recipe = zc.recipe.egg:scripts
每个部件必须指定一个recipe,recipe定义了如何组装该部件。zc.buildout提供了很多recipe,同时作为buildout的发源地,这里也提供了很多recipe。你也可以开发自己的recipe。
每个recipe会定义一些参数,需要在part所在的节中指定这些参数的值。
eggs = xanalogica.tumbler
指定每个部件依赖的模块。
上面的例子中使用的zc.recipe.testrunner是一个常用的recipe,其功能是使用zope.testing.testrunner框架创建进行测试。将会对该节中指定的所有eggs进行测试。可以参考http://www.python.org/pypi/zc.recipe.testrunner 。
buildout.cfg中还可以指定很多其他的配置选项,比如通过interpreter指定python的版本,通过${section_name:param_name}引用已有的配置项等。详细的配置说明可以看这里。