8

我有几个共享通用模块的 python 项目。直到现在,我一直在……咳咳……保留公共代码的多个副本并手动同步。但我显然更愿意做其他事情。

现在在我看来,好像 zc.Buildout 可能是我需要的。我想我应该做的是将系统的每个可重用组件放入一个单独的鸡蛋中,然后使用 buildout 将它们组装成项目。

我还认为对于任何特定模块,我应该将单元测试放入单独的包或鸡蛋中,这样我就不会在每个项目中安装组件的单元测试副本。我只想在开发我的库的地方进行单元测试,而不是在刚刚使用它的地方进行单元测试。

所以也许我想要这样的东西

projects
  lib1
    tests
    code
  lib2
    tests
    code
  app1
    tests 
    appcode
  app2
    tests
    appcode

等等

其中 app1 和 app2 都是具有自己的代码和测试的独立应用程序,但也包含并使用 lib1 和 lib2。而 lib1/test、lib1/code、lib2/test、lib2code、app1、app2 是独立的鸡蛋。这听起来对吗?

然而,我现在很困惑。我假设当我开发 app1 时,我希望 buildout 将 lib1、lib2 和 app1 的副本拉到单独的工作目录中,而不是将这些库的副本直接放在 app1 下。但这如何与我的 SVN 源代码控制一起使用?如果工作目录是使用 buildout 动态构建的,它不能是一个实时 SVN 目录,我可以从中将更改检查回存储库吗?

我是否误解了 buildout 的使用方式?我会更好地采用完全不同的方法吗?你如何在项目之间混合源代码控制和模块重用?

更新:感谢目前已回答此问题的两个人。我正在对此进行更多实验。

4

4 回答 4

5

不要将测试与代码分开,您需要将两者紧密结合在一起。测试并没有占用那么多磁盘空间或任何内存!测试对您的图书馆用户非常有指导意义。

对于库包,请在包中包含一个buildout.cfgbootstrap.py文件,以便轻松运行测试。例如,参见plone.reload 包;请注意它如何使用zc.recipe.testrunner部分来创建一个测试脚本,该脚本将自动发现您的测试并运行它们。这样您就可以确保您的库包始终经过测试!

然后,您的应用程序包只需要测试集成和特定于应用程序的代码。同样,将测试包含在包本身中,在处理代码时不要忘记测试。使用zc.recipe.testrunner构建中的部件来发现和运行这些部件。

最后但同样重要的是,使用mr.developer来管理你的包。使用 mr.developer,您可以签出包作为您的工作,或者如果您不需要处理代码,则可以依赖已发布的版本。一个较大的项目将有许多依赖项,其中许多不需要您调整代码。使用 mr.developer,您可以随意提取源代码并将它们变成开发鸡蛋,直到您发布该代码并且您可以再次取消结帐。

要查看此类项目构建的实际示例,只需查看Plone 核心开发构建

sources.cfg文件包含各种包的 SCM 位置的长列表,但通常使用鸡蛋的发布版本,直到您明确激活您计划使用的包。checkouts.cfg列出所有默认签出的包;这些软件包的更改将成为 Plone 下一版本的一部分,但尚未发布。如果你在 Plone 上工作,你会想要这些,因为你不能忽略这些变化。并testing.cfg列出了如果你想测试 Plone,你需要测试的所有包,一个很大的列表。

请注意,Plone 的来源来自很多地方。一旦你开始使用 buildout 和 mr.developer 来管理你的包,你就可以从任何地方自由地拉取你的源代码。

于 2011-10-01T14:15:43.133 回答
2

我已经非常有效地使用了以下结构。在 SVN 中。

Lib1/
   branches/
   tags/
   trunk/
     lib1/
     tests/
     setup.py
Lib2
   branches/
   tags/
   trunk/
     lib2/
     tests/
     setup.py
App1
   branches/
   tags/
   trunk/
     app1/
     tests/
     setup.py
App2
   branches/
   tags/
   trunk/
     app2/
     tests/
     setup.py

然后,我将创建我的开发工作区(我使用 eclipse/pydev),如下所示,从主干或分支签出。

Lib1/
   lib1/
   tests/
   setup.py
Lib2/
   lib2/
   tests/
   setup.py
App1/
   app1/
   tests/
   setup.py
App2/
   app2/
   tests/
   setup.py

然后,我将使用 Eclipse 项目依赖项设置 python 路径,它与 Eclipse 代码完成配合得很好。setup.py 也可以,但不能很好地支持多个工作区。

对于部署,我使用以下结构创建单个 zip。

App1/
   lib1-1.1.0-py2.5.egg/
   lib2-1.1.0-py2.5.egg/
   app1/
   sitecustomize.py

App2/
   lib1-1.2.0-py2.5.egg/
   lib2-1.2.0-py2.5.egg/
   app2/
   sitecustomize.py

我不使用安装程序安装,因为我想支持应用程序的多个版本,而且我对运行时环境有一些控制,所以我不会将 python 与我的部署打包,但如果在部署包中添加 Python 应该很容易它是必需的。

于 2008-10-12T04:37:08.237 回答
2

这就是您拥有站点模块的原因。它将内部设置sys.path为包含来自的所有包和模块

  • lib/site-packages-- 包括目录、鸡蛋和.pth文件。
  • PYTHONPATH

这样,您的库就只有一个工作副本。

有无限的方法可以利用它。这里有两个。

  1. 在每个库中,编写一个setup.py正确部署您的库的代码。当您进行更改时,您svn up将收集更改并python setup.py install部署每个应用程序共享的一个工作副本。

  2. 在每个应用程序中,要么取决于PYTHONPATH环境变量中的内容。确保projects/lib1projects/lib2赢得了PYTHONPATH. 然后,每个应用程序共享各个库的一个工作副本。

于 2008-10-11T19:22:32.053 回答
1

我认为每个应用程序和库都是一个鸡蛋,并使用已经给出的示例之一在 SVN 中进行布局。真的,VCS 的结局应该不是问题。

然后,为了测试每个应用程序/库或组合,我会设置一个 virtualenv 并通过 setup.py develop 或实际安装它来安装每个包。Virtualenvwrapper 也是管理这些环境的有用工具,因为您可以简单地执行以下操作:

mkvirtualenv lib1-dev

然后后来:

workon lib1-dev

Virtualenv 使用 PYTHONPATH 来更好地控制已安装的软件包。同样,您可以使用 create 环境:

virtualenv --no-site-packages some-env

它会忽略对您实际系统站点包的任何引用。这很有帮助,因为您不仅可以测试您的库/应用程序,还可以验证您在安装时具有正确的依赖关系。

于 2009-01-07T19:38:52.057 回答