使用setuptool排除源文件在构建的rpm发行版中
我有一个典型的项目结构,长得像这样:
EngineEmulator
src
ship
engine
emulator
mapping
tests
emulator
mapping
utils
common
doc
....
tools
....
setup.py
MANIFEST.in
setup.cfg
README.rst
我的setup.py文件内容如下:
from setuptools import setup, find_packages
setup(
name='Engine',
version=1.0.0,
description='Engine Project',
package_dir={'': 'src'},
packages=find_packages(
'src',
exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
install_requires =['pycrypto',
'kombu >=1.1.3'],
author='Demo',
author_email='demo@eliza.net'
license='MIT',
classifiers=[
'Topic :: Demo Engine',
'Development Status:: 3 - Iteration',
'Programming Language :: Python -2.6'
]
)
我的setup.cfg文件内容如下:
[egg_info]
tag_build = .dev
tag_svn_revision = 1
[rotate]
#keep last 15 eggs, clean up order
match = .egg
keep = 15
还有我的MANIFEST.in文件内容如下:
include README.rst
recursive-include src/ship/Engine
prune src/utils
prune src/ship/tests
prune tools/
当我运行 python setup.py bdist_egg
和 python setup.py bdist_rpm
时,会生成一个egg文件和两个rpm文件(noarch.rpm和src.rpm)。
在我的目标机器上,当我运行 easy_install <生成的egg文件>
时,我的eg.info文件被复制过去了,但源文件没有被复制到/usr/lib/python2.6/site-packages目录下。我原本以为会有一个叫做Engine的文件夹。
有没有人能指出我哪里做错了?提前谢谢大家。
1 个回答
尽量保持事情简单。
用 sdist
快速检查
试试这个:
$ python setup.py sdist
这会为你的包创建一个源代码分发文件。
这个文件是zip格式的,所以解压后检查一下,里面是否有你预期的所有文件。
如果没有,你需要找出为什么预期的文件在你的分发中缺失。
一步一步检查(并简化)
你有使用 .py
后缀吗?
这可能是个傻问题,但在你的文件列表中,我没有看到任何 src
目录下的py文件。
如果那里只有没有 .py
后缀的文件,find_packages
就找不到任何东西。
你的 __init__.py
文件放在哪里?
告诉我们这些文件在哪里:
$ cd src
$ find . -name "*.py"
如果缺少 __init__.py
,find_packages
就找不到整个包。
移除 utils
包
你为什么要把它放在那里?
最好把它安装在你开发的源代码之外,或者把它移动到项目根目录的子目录中。
这样就不需要在你的 MANIFEST.in
中使用 prune src/utils
了。
在 MANIFEST.in 中只放必要的文件
如果你读过 MANIFEST.in
的文档,它会说明哪些文件会自动包含(所有在 setup
函数参数中提到的文件,也就是你情况下所有由 find_packages
返回的python源文件)。
因此,你应该移除 recursive-include src/shop/Engine
,因为它应该已经被 setup
调用包含了。
移除 prune
行。
src/utils
不应该在你的源代码树中 - 这只会搞乱事情。tools
不需要包含,所以不需要去除它。src/ship/tests
可以保留,如果你把这些文件放在分发中也没关系。
确认找到的包
确保你的设置能正确获取 packages
的名称。
为此,你可以提前调用 find_package
,并确认它包含你预期的内容。
(暂时)移除 setup.cfg
这样可以让事情更简单。
建议的项目重组
你的文件结构应该类似于以下方式:
src/ship/__init__.py
src/ship/engine/__init__.py
src/ship/engine/emulator/__init__.py
src/ship/engine/emulator/module.py
src/ship/engine/emulator/module2.py
src/ship/engine/mapping/other.py
src/ship/engine/mapping/another.py
src/ship/tests/__init__.py
src/ship/tests/emulator/__init__.py
src/ship/tests/emulator/test_module.py
src/ship/tests/emulator/test_module2.py
src/ship/tests/mapping/__init__.py
src/ship/tests/mapping/test_other.py
src/ship/tests/mapping/test_another.py
doc
doc/index.rst
tools
tools/knife.py
setup.py
MANIFEST.in
README.rst
setup.py
from setuptools import setup, find_packages
packages=find_packages("src")
assert "ship.engine" in packages
assert "ship.engine.emulator" in packages
assert "ship.engine.mapping" in packages
#etc
install_requires =['pycrypto', 'kombu>=1.1.3'] #watch the spaces around `>=`, shall not be there
setup(
name="Engine",
package_dir={'': 'src'},
packages=packages,
install_requires=install_requires
)
MANIFEST.in
include README.rst
结论
可能会发生,运行
$ python setup.py sdist
会在断言时失败。这是一个信号,说明一些预期的文件缺失。检查一下。
在你让项目以简单的方式运行后,可以逐步添加更多细节(确保你不会破坏什么)。