Makina Corpus赞助的zc.buildout食谱,用于编译和安装软件或Python包,并生成脚本或配置文件。
项目描述
介绍
此egg具有以下入口点
egg:安装Python egg / 包 'setuptoolisables'
重写另一个buildout食谱构建器的理由是
支持下载内容
不依赖于easy_install依赖系统
支持egg和其他分发的即时补丁。
支持构建系统每个阶段的多个钩子。
强大的离线模式
我们喜欢PyPI,但提供了一种无需检查索引即可扫描egg的模式
支持格式错误或未索引的分发。换句话说,我们提供了一个URL,食谱构建它,仅此而已。
支持自动minitage依赖项和rpath链接。
您可以在以下minitage资源中浏览代码
您可以使用buildout.minitagificator轻松迁移您的buldouts
Makina Corpus赞助的软件
minitage.recipe.egg
摘要
此食谱旨在安装egg和Python软件
它深受zc.recipe.eggs*的启发,并试图完全替换它,同时保持API兼容性。
您可以使用它与buildout.minitagificator扩展一起使用,该扩展对zc.buildout进行猴子补丁以使用minitage配方。
该配方具有强大的离线模式。
我们可以做到zc.recipe.egg做不到的事情,要么完全做不到,要么不是我们想要的方式
不要依赖easy_install来检测和安装依赖项,这可能导致版本不兼容
处理并保留egg的额外依赖项
根据egg的名称生成具有特定版本号的特定egg,并将其埋在buildout的“versions”中
在构建时使minitage环境进入环境,如果有的话,使编译步骤变得简单,如果您已声明并构建了必要的依赖项。
能够安装未索引的任何东西,只需指定安装的URL即可,这甚至可以是来自任何存储库的自动检出。
您有挂钩来玩配方,如果它不完全符合您的需求,您可以在构建的任何点挂钩特定的egg。
检查索引上的md5,这些索引在URL上附加md5片段,以验证包的完整性
如果您需要生成脚本,只需使用minitage.recipe:scripts配方即可,它是这个配方的专用配方。其用法类似,只是有更多选项。
特定选项
请参阅以下选项: http://pypi.python.org/pypi/minitage.recipe.common#options-shared-by-all-the-recipes
urls
有关设置它们的更多信息,请参阅共享选项。这是指定不在pypi上索引的分布以及find-links舞蹈无法工作的情况。这也是指定从svn安装内容的情况。
urls = http://foo.tld/my_super_egg|svn|666 # checkout and install this egg from svn at revision 666
目录位可用于设置要切换到的子目录以找到setup.py,例如
urls = http://foo.tld/my_super_egg|svn|666|subdirectory # checkout and install this egg from svn at revision 666 and will cd to subdirectory to do the setup.py dance
eggs
安装而不指定版本规范的egg需求列表。
Plone lxml
EGGNAME-no-activate / EGGNAME-VERSION-no-activate:在静态分发模式下,强制不激活分发(仅构建)
EGGNAME-force-rebuild / EGGNAME-VERSION-force-rebuild:在静态分发模式下,强制重新构建egg
urls=http://pil.tar.gz PIL-force-rebuild=true
- EGGNAME-patch-options
用于此egg的补丁二进制文件
- EGGNAME-patch-binary
在应用此egg的补丁时提供给补丁程序的选项
- EGGNAME-patches
在安装时应用特定egg名称的特定补丁
Django-patches = ${buildout:directory}/foo.patch
- EGGNAME-UNAME-patches
与前面相同,但仅在UNAME指定特定的OS(linux|freebsd|darwin)上执行。在安装时应用特定egg名称的特定补丁
Django-linux-patches = ${buildout:directory}/foo.patch
- EGGNAME-VERSION-patches
仅在特定版本上应用补丁
- EGGNAME-VERSION-UNAME-patches
仅在特定版本上应用补丁
- versions
默认为buildout:versions。用于固定已安装egg的版本的versions部分。默认为buildout的版本
- index
自定义egg索引(非pypi/simple)。默认为buildout的版本
- install-previous-version
安装egg的先前版本(在错误上递归安装)
- find-links
我们可以找到egg的附加链接。默认为buildout的版本
- extra-paths
在生成的脚本或构建时包含的额外路径。
- relative-paths
如果设置为true,则egg路径将相对于脚本路径生成。这允许buildout在移动时不会破坏egg路径。此选项可以在脚本部分或buildout部分中设置。
指定要使用的python的两种方式
- python
要从其中获取Python可执行文件的节名称。如果没有指定,则使用buildout python选项。Python可执行文件位于指定节的可执行选项中。默认为buildout的版本
- executable
要使用的Python可执行文件的路径。
hooks
挂钩的形式是/path/to/hook:CALLABLE
myhook=${buildout:directory}/toto.py:foo
在哪里有toto.py
def foo(options, buildout): return 'Hourray'
完整的可能挂钩列表
- post-download-hook
在每次下载后执行的挂钩
- post-checkout-hook
在每次检出后执行的挂钩
- EGGNAME-pre-setup-hook
在运行 setup.py 舞蹈之前执行的钩子
- EGGNAME-post-setup-hook
在运行 setup.py 舞蹈之后执行的钩子
BDIST EGGS 选项
您可以有全局和每个分发版的 bdist_ext 选项。
(EGGNAME-)define
要定义的 C 预处理器变量名的逗号分隔列表。
(EGGNAME-)undef
要取消定义的 C 预处理器变量名的逗号分隔列表。
(EGGNAME-)link-objects
要链接的对象的名称。由于 distutils 的限制以及选项名称,只能指定一个链接对象。
(EGGNAME-)debug
编译/链接时包含调试信息
(EGGNAME-)force
强制构建所有内容(忽略文件时间戳)
(EGGNAME-)compiler
指定编译器类型
(EGGNAME-)swig
swig 可执行文件的路径
(EGGNAME-)swig-cpp
使 SWIG 创建 C++ 文件(默认为 C)
(EGGNAME-)swig-opts
SWIG 命令行选项列表
(EGGNAME-)bdistext-OPTIONNAME
将在 setup.cfg 的 bdist_egg 中添加一个条目,如下所示
OPTIONNAME = foo
补丁
当您对一个 egg 使用补丁时,其版本将变为
Django-1.0-final -> Django-1.0-final-ZMinitagePatched-$PatchesNamesComputation$此名称包含一些 Z* 以在其他相同版本的 egg 上具有优先级。(请参阅 setuptools 命名方案)
在创建 egg 之后,buildout 将备份并修补以指向此版本
因此,您可以在公共 egg 缓存中,为您的特定项目保留此 egg,并为其他人保留经典版本。这很有趣,例如,对于 zope RelStorage 补丁应用于 ZODB 代码。
详细文档
从索引或查找链接安装egg,这是安装Python包的经典方式
我们需要指定一个 find-links 条目,以便配方可以找到我们的“foo” egg,因为它不在 pypi 上。由于我们想展示配方的更新功能,我们将首先安装最旧的 foo 版本。
>>> globals().update(layer['globs'])
让我们创建一个 buildout 配置文件和一个基本 egg,该 egg 未在 pypi 上发布
>>> makedist() >>> makedist(version="2.0") >>> makedist(name="foo3", version="2.0") >>> makedist(name="foo4", version="2.0") >>> makedist(name="foo4", version="3.0") >>> data = """ ... [versions] ... foo=1.0 ... [buildout] ... eggs-directory =${buildout:directory}/eggs ... download-cache=${buildout:directory} ... index=%(index)s ... parts = ... part ... [part] ... recipe=minitage.recipe.egg ... find-links=%(index)s ... eggs=foo ... """% bsettings >>> touch('buildout.cfg', data=data) >>> clean() >>> sh('bin/buildout -vvvvv install part') bin/... Installing part. minitage.recipe: Installing python egg(s)... minitage.recipe: Downloading http://...:.../foo-1.0.tar.gz in .../eggs/foo-1.0.tar.gz minitage.recipe: Unpacking in ... Processing foo-1.0.tar.gz... minitage.recipe: Installed foo 1.0 (.../eggs/foo-1.0-p....egg)...
静态分布dev+static网址
您也可以直接从 URL 安装。我们将使用它来检查缓存中已存在的分发文件。
>>> bsettings["foo3url"] = "%sfoo3-2.0.tar.gz" % (bsettings["index"]) >>> bsettings["foo4url"] = "%sfoo4-2.0.tar.gz" % (bsettings["index"]) >>> bsettings["foo43url"] = "%sfoo4-3.0.tar.gz" % (bsettings["index"]) >>> data = """ ... [versions] ... mr.developer=0.15 ... [buildout] ... eggs-directory =${buildout:directory}/eggs ... versions = versions ... download-cache=${buildout:directory} ... parts = ... part ... index=%(index)s ... [part] ... recipe = minitage.recipe.egg ... eggs=mr.developer ... [a] ... recipe=minitage.recipe.egg ... urls= ... %(foo3url)s ... %(foo4url)s ... """ % bsettings >>> touch('buildout.cfg', data=data) >>> sh('bin/buildout -vvvvvv install a') #doctest +REPORT_NDIFF b... Installing a... minitage.recipe: Download archive from http://.../foo...-2.0.tar.gz... minitage.recipe: Installed foo... minitage.recipe: Pinning custom egg version in buildout, trying to write the configuration minitage.recipe: CREATING buildout backup in ... ...
由于我们从 URL 安装,我们必须固定版本,以确保使用此 egg,即使我们在索引或 find-links 上有一些其他类似的 egg。查看已固定的版本以使用您下载的内容
>>> cat('buildout.cfg') # doctest: +REPORT_NDIFF <BLANKLINE> [versions] mr.developer=0.15 foo... = 2.0 foo... = 2.0 [buildout] eggs-directory =${buildout:directory}/eggs versions = versions download-cache=${buildout:directory} parts = part index... [part] recipe = minitage.recipe.egg eggs=mr.developer [a] recipe=minitage.recipe.egg urls= .../foo3-2.0.tar.gz .../foo4-2.0.tar.gz...
如果我们尝试通过 URL 安装较新版本,即使版本已固定,它也会正常工作。
>>> data = """ ... [versions] ... mr.developer=0.15 ... [buildout] ... versions = versions ... download-cache=${buildout:directory} ... eggs-directory =${buildout:directory}/eggs ... parts = ... part ... index=%(index)s ... [part] ... recipe = minitage.recipe.egg ... eggs=mr.developer ... [a] ... recipe=minitage.recipe.egg ... urls= ... %(foo43url)s ... """ % bsettings >>> touch('buildout.cfg', data=data) >>> sh('bin/buildout -vvvvv install a') b... >>> cat('buildout.cfg') # doctest: +REPORT_NDIFF <BLANKLINE> [versions]... foo4 = 3.0...
如果我们尝试重新构建 egg,我们无法做到,因为已构建了相同的 egg。这是为了避免在每次启动 buildout 时触发重新构建,并删除缓存中已存在的良好版本。
>>> sh('bin/buildout -ovvvvv install a') b... minitage.recipe: If you want to rebuild, please do 'rm -rf .../eggs/foo...
离线和最新模式
我们有方法让 buildout 不下载在索引上找到的最新版本,并且对我们已经本地拥有的内容非常保守。
让我们创建一个 buildout 配置文件和一个基本 egg,该 egg 未在 pypi 上发布,并安装它
>>> globals().update(layer['globs']) >>> makedist() >>> makedist(version='2.0') >>> data = """ ... [versions] ... foo=1.0 ... [buildout] ... eggs-directory =${buildout:directory}/eggs ... download-cache=${buildout:directory} ... index=%(index)s ... parts = ... part ... [part] ... recipe=minitage.recipe.egg ... find-links=%(index)s ... eggs=foo ... """%bsettings >>> touch('buildout.cfg', data=data) >>> clean() >>> sh('bin/buildout -vvvvv install part') bin/... Installing part. minitage.recipe: Installing python egg(s)... minitage.recipe: Downloading http://...:.../foo-1.0.tar.gz in .../minitage/eggs/foo-1.0.tar.gz minitage.recipe: Unpacking in ... Processing foo-1.0.tar.gz... minitage.recipe: Installed foo 1.0 (.../eggs/foo-1.0-p....egg)...
现在,我们已经是 1.0。删除版本位,但选择不安装最新版本将使 buildout 不安装 foo-2.0 版本。
>>> data = """\ ... [versions] ... [buildout] ... download-cache=${buildout:directory} ... eggs-directory =${buildout:directory}/eggs ... parts = ... part ... versions = versions ... index=%(index)s ... [t] ... recipe=minitage.recipe.egg ... find-links=%(index)s ... eggs=foo ... """%bsettings >>> touch('buildout.cfg', data=data) >>> sh('bin/buildout -Nvvvvv install t') b... minitage.recipe: Installing python egg(s). minitage.recipe: Picked: foo = 1.0 minitage.recipe: All egg dependencies seem to be installed!...
在离线模式下也是如此。
>>> sh('bin/buildout -ovvvvv install t') b... minitage.recipe: Picked: foo = 1.0 minitage.recipe: All egg dependencies seem to be installed!...
但是,然后,切换到在线/最新模式将触发 2.0 egg 的安装。
>>> sh('bin/buildout -nvvvvv install t') b... minitage.recipe: Picked: foo = 2.0 minitage.recipe: All egg dependencies seem to be installed!...
文件 URL 在离线模式下工作。
>>> data = """ ... [buildout] ... download-cache=${buildout:directory} ... eggs-directory =${buildout:directory}/eggs ... index=%(index)s ... parts = ... part ... [part] ... recipe=minitage.recipe.egg ... urls=file://${buildout:directory}/foo-2.0.tar.gz ... """ % bsettings >>> clean() >>> touch('buildout.cfg', data=data) >>> sh('bin/buildout -vvvvv install part') b... >>> [egg for egg in os.listdir('eggs') if 'foo' in egg] ['foo-2.0-py...egg'] >>> sh('bin/buildout -o install part') b... >>> [egg for egg in os.listdir('eggs') if 'foo' in egg] ['foo-2.0-py...egg']
使用补丁安装egg
我们需要指定一个 find-links 条目,以便配方可以找到我们的“foo” egg,因为它不在 pypi 上。由于我们想展示配方的更新功能,我们将首先安装最旧的 foo 版本。
让我们创建一个 buildout 安装
>>> globals().update(layer['globs']) >>> makedist() >>> makedist(version='2.0') >>> touch('patch', data=""" ... --- foo.old/toto.py 2013-03-30 20:42:04.575613999 +0100 ... +++ foo/toto.py 2013-03-30 20:42:10.603721734 +0100 ... @@ -1,3 +1,7 @@ ... ... def f(): ... print "foo" ... + ... + ... + ... + ... ... """)
修补很容易,只需将您的补丁放在 YouEgg-patches 中即可。
>>> data = """ ... [versions] ... foo=1.0 ... [buildout] ... download-cache=${buildout:directory} ... eggs-directory =${buildout:directory}/eggs ... parts = part ... index=%(index)s ... [part] ... recipe=minitage.recipe.egg ... find-links=%(index)s ... foo-patches = ${buildout:directory}/patch ... eggs=foo ... """%bsettings >>> touch('buildout.cfg', data=data) >>> sh('bin/buildout install part') b... can't find file to patch at input line 4 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- | |--- foo.old/toto.py 2013-03-30 20:42:04.575613999 +0100 |+++ foo/toto.py 2013-03-30 20:42:10.603721734 +0100 -------------------------- No file to patch. Skipping patch. ... minitage.recipe: Message was: ('Failed', 'patch -t -Np0 < ...patch')...
Oops,补丁级别 ! 。
>>> data = """\ ... [versions] ... foo=1.0 ... [buildout] ... download-cache=${buildout:directory} ... eggs-directory =${buildout:directory}/eggs ... parts = part ... index=%(index)s ... [part] ... recipe=minitage.recipe.egg ... find-links=%(index)s ... eggs=foo ... foo-patches = ${buildout:directory}/patch ... foo-patch-options = -Np1 ... """%bsettings >>> touch('buildout.cfg', data=data) >>> sh('bin/buildout -vvvvv install part') b... minitage.recipe: Running patch -t -Np1 < .../patch patching file toto.py... minitage.recipe: Installed foo 1.0-ZMinitagePatched-Patch...
现在我们已经有了它,尝试重新安装。
>>> sh('bin/buildout -vvvvv install part') bin/buildout... minitage.recipe: We have the distribution that satisfies 'foo==1.0-ZMinitagePatched-Patch'. minitage.recipe: Pinning custom egg version in buildout, trying to write the configuration minitage.recipe: Version already pinned, nothing has been wroten...
在所有情况下,我们的 buildout 都已修补。
>>> cat('buildout.cfg') [versions] foo...=...1.0-ZMinitagePatched-Patch...
使用自定义build_ext_options安装egg
>>> globals().update(layer['globs']) >>> makedist(version='2.0', setup=""" ... ... import os ... if os.path.exists('setup.cfg'): ... print 'setup.cfg:' ... print '---------------' ... print open('setup.cfg').read() ... """)
只需将您想要的 bdist_ext 选项添加到 buildout 中即可
>>> data = """ ... [versions] ... [buildout] ... download-cache=${buildout:directory} ... eggs-directory =${buildout:directory}/eggs ... parts = ... part ... index=%(index)s ... [part] ... recipe=minitage.recipe.egg ... find-links=%(index)s ... define=Foo=1,Bar=2 ... bdistext-foo = bar ... bdistext-bar = titi ... foo-bdistext-foo = tutu ... foo-swig-cpp = toto ... eggs=foo ... """% bsettings >>> touch('buildout.cfg', data=data) >>> sh('bin/buildout -vvvvv install part') b... minitage.recipe: Using bdist_ext option: define = Foo=1,Bar=2 minitage.recipe: Using bdist_ext option: bar = titi minitage.recipe: Using bdist_ext option: foo = bar... minitage.recipe: foo: Using bdist_ext option: swig-cpp = toto minitage.recipe: foo: Using bdist_ext option: foo = tutu... setup.cfg: --------------- [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 <BLANKLINE> [build_ext] foo = tutu bar = titi swig-cpp = toto define = Foo=1,Bar=2... setup.cfg: --------------- [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 <BLANKLINE> [build_ext] foo = tutu bar = titi swig-cpp = toto define = Foo=1,Bar=2... minitage.recipe: All egg dependencies seem to be installed!...
支持Distribute
>>> globals().update(layer['globs'])
如果我们处于 distribute 模式,则表示 distribute 已安装且在 sys.path 上可用。如果是这样,我们将检测到这一点,并且如果任何要求需要 setuptools,我们将只安装 distribute,而不是 setuptools。即使版本已固定。
>>> data = """ ... [buildout] ... versions = versions ... eggs-directory =${buildout:directory}/eggs ... index=%(index)s ... parts = part ... s ... [part] ... recipe=minitage.recipe.egg ... eggs = virtualenv ... [s] ... recipe=minitage.recipe.scripts ... eggs = virtualenv ... [versions] ... """ % bsettings >>> touch('buildout.cfg', data=data)
使用 distribute 运行 buildout 以查看它是否已被选中。
>>> sh('bin/buildout -vvvvvv install part s') bin/buildout... minitage.recipe: Using distribute!...
变更日志
1.107 (2013-06-26)
修复先前的补丁
1.106 (2013-06-26)
尝试首先使用干净的 pythonpath(仅 setuptools)安装
1.105 (2013-06-22)
处理最后一个 setuptools
1.104 (2013-06-02)
为静态分发重建强制模式
1.103 (2013-06-02)
再次,修复
1.102 (2013-06-02)
再次,修复
1.101 (2013-06-02)
修复从URL安装中的竞态条件
1.100 (2013-06-02)
修复从URL安装
1.99 (2013-04-02)
QA发布(pep8,覆盖率,新的测试层和持续集成)
1.97 (2013-03-29)
支持在默认缓存目录中查找发行版
离线错误修复,正确从所有下载缓存加载源发行版
1.96 (2013-02-23)
避免循环错误(buildout2再次)[kiorky]
1.94 (2013-02-19)
buildout2兼容性再次修复
1.93 (2013-02-13)
buildout2兼容性
1.92 (2012-08-28)
修复一些边界情况中的额外处理
1.91 (2012-06-08)
更简洁的输出
1.90 (2012-06-08)
更简洁的输出
1.89 (2012-06-08)
修复一些依赖树错误 [kiorky]
1.88
与buildout.dumppickledversion的兼容性
1.82
与allow-picked-version == False有更好的兼容性
1.81
处理版本块中的注释
1.76 - 1.77
一些distribute/setuptools修复
修复测试
更好的错误输出
1.75
更好地处理下载问题
1.73 - 1.74:
- 跨平台构建修复
它允许在OSX上做很多事情
- (主要是在平坦编译的Python上运行buildout
并使用针对i386编译的Python)
1.72
修复当你在buildout.cfg中修复版本而某人在setup.py中修复时出现的conflicterror,它只显示一个大的警告
1.71
再次更好地支持distribute。
1.62
修复特定的dir changepath
修改如何计算环境变量
- 当你的egg缓存与buildout不在同一分区时修复丑陋的错误
当从沙箱重命名时,它会造成跨设备引用错误
zip egg错误修复
在即时修补时,让sdist优先于eggs。
修复与python2.4和urlparse(tuple)的兼容性错误
添加bdist_ext选项支持,如zc.recipe.egg:custom
使用发行版文件标识符使recipe更酷
将测试拆分为多个文件
1.38
装饰器辅助函数
1.37
修复当修补失败时的异常映射
1.36
修复开发eggs的测试
1.35
从minitage.recipe拆分出来