保留Python GAE依赖于项目版本控制的最佳实践
在我们公司,我们有一个很不错的系统,用来跟踪我们当前桌面应用开发(C++/Python)中外部包的依赖关系。现在我们开始开发一些纯Python的网页应用,想要寻找一些最佳实践的建议,特别是当只有Python代码,并且这些代码来自可以用easy_install安装的包时。
对于我们的桌面应用,我们有这样的设置:
app_svn_root
- trunk
- src
- doc
- deps -> [svn:external to deps repos with rev num set]
deps_svn_root
- trunk
- setup_env.sh/bat [generated automatically
- dep_project_1 [example: boost, libxml, python, etc]
- vendor_base [svn:external to vendor branch or project repository]
- install_linux_gcc43
- bin
- include
- lib
- install_linux_win32_vc90
- ... [whatever directory structure the project build creates]
当团队中的任何开发者检出应用的代码时,他们会自动获取所有依赖包,并且这些包的版本与代码的修订版本是匹配的。(注意:这里省略了一些内部管理脚本等,但大致思路就是这样。)这对我们来说效果很好。开发者不需要再担心在个人电脑上设置每个包的正确版本,这样也允许同时检出多个开发版本(比如:1.0、1.1、2.0等),还可以让持续集成系统打包依赖并用正确版本的依赖运行单元测试。
现在我们开始着手一些基于Google App Engine的Python项目,我们希望能有类似的功能。我们希望保持开发者能够一次性检出他们所需的所有内容,并确保每个人使用的依赖包是一样的。我们可以继续使用这个确切的结构,但对于一个纯Python项目来说,这似乎有点过于复杂。
最开始我在考虑这样的方案:
- trunk
- gae_apps
- gae_sdk [svn:external to the latest stable GAE code]
- deps
- nose
- nosegae
- pylint
- app1
- templates
- tests
- deps
- webapp2
- console
我遇到的问题是,我想用的所有Python项目(比如nose、nosegae等)都推荐使用easy_install
来下载和安装它们。但这会把它们安装到主系统目录中。我真正想要的是将每个包安装到一个特定的目录中。(注意:我打算在main.py中添加一些代码,以便正确地将所有依赖包添加到sys.path中。)有没有办法做到这一点?这样做是否合理?
在纯Python应用中,如何跟踪依赖关系以支持大型团队的开发,有哪些最佳实践呢?
3 个回答
我在使用zc.buildout,这个工具是为了管理项目的依赖关系而设计的,最初是为Tipfy写的。你可以查看这个链接 https://github.com/runway7/terminal,里面有一个示例的 buildout.cfg
文件。
首先,安装zc.buildout - 你可以在命令行输入
pip install zc.buildout
来安装。然后,在一个空的项目文件夹里创建一个
buildout.cfg
文件,并把示例中的versions.cfg
文件复制过来。记得在buildout.cfg
里自定义GAE的版本。接下来,运行
buildout
,并修复出现的错误。(基本上就是创建一些必要的文件夹结构。)最后,只需把你需要的依赖项添加到
buildout.cfg
文件中的eggs
部分,这样它就会帮你管理这些依赖了。
对我来说,这个方法效果很好。
我也在想,怎么才能在Python项目中自动处理依赖关系,之前我在Java项目中用过Ivy和Maven。
从我了解到的情况来看,Python里没有什么工具能像Maven那样好用,不过zc.buildout看起来非常接近。它使用的和pip/distribute一样的传统distutils setup.py脚本,但在构建项目时提供了更大的灵活性。它不需要你去折腾virtualenv,但仍然能提供一个隔离的构建环境。
接下来,你应该搭建一个本地的Pypi实例,把它当作你所有Python依赖的仓库。
如果你的依赖都是纯Python的,那这样应该能很好地工作。如果你有依赖于本地代码的情况,可能会遇到一些问题。不过有buildout食谱可以帮助你解决这个问题,而且你也可以轻松创建自己的自定义食谱。
如果你是通过互联网拉取依赖,每个开发者在~/.buildout/default.cfg中设置download-cache属性是非常重要的。
你可以使用 virtualenv 和 pip。通过 virtualenv,你可以为你的应用创建一个独立的环境,在这个环境里,所有的包都是用 pip 安装的,而不是直接安装到系统里。这样做的好处是,你可以轻松管理这些包,并且可以生成一个依赖列表,让它们可以自动安装。