如何让setuptools忽略subversion库存?

时间:2009-07-15 03:00:20

标签: python packaging setuptools egg

使用使用setuptools的setup.py打包Python包时:

from setuptools import setup
...

由以下人员创建的源代码分发:

python setup.py sdist

不仅像往常一样包含MANIFEST.in中指定的文件,而且无偿地包含Subversion在包目录下列出的所有文件控制文件。这非常烦人。它不仅难以对我的包中分发的文件进行任何形式的显式控制,而且意味着当我按照“svn export”而不是“svn checkout”构建我的包时,我的内容包可能会有很大不同,因为没有.svn元数据setuptools会对包含的内容做出不同的选择。

我的问题:如何关闭这种可怕的行为,以便“setuptools”以同样的方式处理我的项目,无论我使用的是Subversion,还是从未听说过的版本控制,或者使用“svn export”创建的裸树“我在项目结束时创建的,以确保它在我的工作目录之外的某个地方干净地构建?

到目前为止,我所做的最好的是一个丑陋的猴子补丁:

from setuptools.command import sdist
del sdist.finders[:]

但这是Python,而不是丛林,所以当然我想要一个更好的解决方案,根本不涉及猴子。我怎样才能通过查看MANIFEST.py中可见的,可预测的规则来驯服setuptools,关闭它的魔力,让它表现得明智?

6 个答案:

答案 0 :(得分:14)

我知道你对此很了解,布兰登,但我会尽力给出一个完整的答案(虽然我不是设置工具),以造福他人。

这里的问题是setuptools本身涉及很多黑魔法,包括使用名为setuptools.file_finders的入口点,你可以在其中添加插件来查找要包含的文件。但是,我完全不知道如何从中插入REMOVE ......

  • 快速解决方法:将svn导出到临时目录并从那里运行setup.py。这意味着你没有svn,所以svn finder找不到要包含的文件。 :)

  • 更长的解决方法:您真的需要setuptools吗? Setuptools有很多功能,所以答案可能是肯定的,但主要是那些功能是depdenencies(因此你的依赖项由easy_install安装),命名空间包(foo.bar)和入口点。实际上也可以在没有setuptools的情况下创建命名空间包。但是,如果你不使用这些,你实际上可能只是使用distutils。

  • 丑陋的解决方法:你在问题中给sdist提供的monkeypatch,它简单地使插件没有任何查找器,并快速退出。

正如你所看到的,这个答案虽然尽我所能,但仍然是令人尴尬的不完整。我实际上无法回答你的问题,但我认为答案是“你做不到”。

答案 1 :(得分:9)

使用以下命令创建MANIFEST.in文件:

recursive-exclude .
# other MANIFEST.in commands go here
# to explicitly include whatever files you want

有关MANIFEST.in语法,请参阅http://docs.python.org/distutils/commandref.html#sdist-cmd

答案 2 :(得分:1)

答案可能在你的setup.py中。你使用find_packages吗?默认情况下,此函数使用VCS(例如subversion,hg,...)。如果您不喜欢它,只需编写一个不同的Python函数,它只收集您想要的东西。

答案 3 :(得分:1)

简单的解决方案,请勿使用setuptools创建源代码发行版,而将该命令降级为distutils:

from distutils.command.sdist import sdist
from setuptools import setup

setup(
    # ... all the usual setup arguments ...
    cmdclass = {'sdist': sdist},
)

答案 4 :(得分:0)

我认为默认的sdist行为是正确的。当您构建分发时,我希望它包含检入Subversion的所有内容。当然,在特殊情况下能够干净地覆盖它会很好。

将sdist与bdist_egg进行比较;我敢打赌只包含明确指定的文件。

我用三个文件做了一个简单的测试,都在svn中。清空dummy.lkj和foobar.py以及setup.py看起来像这样:

import setuptools
setuptools.setup(name='foobar', version='0.1', py_modules=['foobar'])

sdist创建一个包含dummy.lkj的tarball。 bdist_egg创建一个不包含dummy.lkj的蛋。

答案 5 :(得分:-1)

你可能想要这样的东西:

from distutils.core import setup

def packages():
    import os

    packages = []

    for path, dirs, files in os.walk("yourprogram"):
        if ".svn" in dirs:
            dirs.remove(".svn")

        if "__init__.py" in files:
            packages.append(path.replace(os.sep, "."))

    return packages

setup(
    # name, version, description, etc...

    packages = packages(),

    # pacakge_data, data_files, etc...
)