我想找到一种正确的方法,将未被git跟踪的文件包含在python sdist中。
上下文
git
不会跟踪我项目中的.mo
文件(就像其他一些需要在安装时创建的.txt
文件一样)。
我在setup.py
中编写了一个小函数,用于在安装时创建它们,并在setup()
:中调用
setup(
.
.
.
data_files=create_extra_files(),
include_package_data=True,
.
.
.
)
注意,它们应该属于data_dir
,因为文档上写着:
data_files选项可用于指定所需的其他文件按模块分布:配置文件、消息目录,数据文件,任何不属于以前类别的文件。
因此,这与python3 setup.py install
(以及bdist
)配合良好。生成.mo
文件并将其存储在正确的位置。
但是,如果我希望它与sdist
一起工作,那么我必须将它们包括在MANIFEST.in
中(例如recursive-include mathmaker *.mo
)。文件确实表明:
在3.1版中更改:所有与data_files匹配的文件都将添加到MANIFEST文件中如果没有提供模板。请参见指定要分发的文件。
(链接没有多大帮助)。
我不愿意在MANIFEST.in
中包含*.mo
文件,因为它们不受git跟踪。检查清单不喜欢这种情况,它抱怨lists of files in version control and sdist do not match!
那么,有办法解决这种丑陋的局面吗?
重现情况的步骤
环境与项目
为了避免污染您的环境,请在您选择的目录中创建并激活一个专用的虚拟环境(python3.4+):
$ pyvenv-3.4 v0
$ source v0/bin/activate
(v0) $
在project0
目录中再现以下树:
.
├── .gitignore
├── MANIFEST.in
├── README.rst
├── setup.py
└── project0
├── __init__.py
├── main.py
└── data
└── dummy_versioned.po
其中README.rst
、__init__.py
和dummy_versioned.po
为空。
其他文件的内容:
.gitignore
:build/ dist/ *.egg-info project0/data/*.txt *~
MANIFEST.in
:recursive-include project0 *.po recursive-include project0 *.txt
main.py
:#!/usr/bin/env python3 # -*- coding: utf-8 -*- def entry_point(): with open('project0/data/a_file.txt', mode='rt') as f: print(f.read())
setup.py
:#!/usr/bin/env python3 # -*- coding: utf-8 -*- import platform from setuptools import setup, find_packages def create_files(): txt_file_path = 'project0/data/a_file.txt' with open(txt_file_path, mode='w+') as f: f.write("Some dummy platform information: " + platform.platform()) return [('project0/data', [txt_file_path])] setup( name='project0', version='0.0.1', author='J. Doe', author_email='j.doe@someprovider.com', url='http://myproject.url', packages=find_packages(), data_files=create_files(), include_package_data=True, entry_points={ 'console_scripts': ['myscript0 = project0.main:entry_point'], } )
启动本地git
回购:
(v0) $ git init
(v0) $ git add .
安装check-manifest
:
(v0) $ pip3 install check-manifest
安装和测试
install
作品:
(v0) $ python3 setup.py install
.
.
.
copying project0/data/a_file.txt -> build/lib/project0/data
.
.
.
Finished processing dependencies for project0==0.0.1
(v0) $ myscript0
Some dummy platform information: Linux-3.16.0-29-generic-x86_64-with-Ubuntu-14.04-trusty
如果是rm project0/data/a_file.txt
,那么myscript0
就不再工作了,但重新安装它,它就会像预期的那样再次工作。
构建sdist还包括a_file.txt
:
(v0) $ python3 setup.py sdist
.
.
.
hard linking project0/data/a_file.txt -> project0-0.0.1/project0/data
.
.
.
请注意,要将此文件包含在sdist中,似乎有必要(如下面的"上下文"部分所述)在MANIFEST.in
中包含recursive-include project0 *.txt
。你会删除这一行吗,python3 setup.py sdist
不会再提到a_file.txt
了(不要忘记删除任何以前的build/
或dist/
目录来观察这一点)。
结论
因此,一切都按原样运行,但存在这样的差异:a_file.txt
不被git
跟踪,而是被包含在MANIFEST.in
中。
check-manifest
告诉很清楚:
lists of files in version control and sdist do not match!
missing from VCS:
project0/data/a_file.txt
那么,有没有合适的方法来处理这种情况呢?
就我遇到的问题而言,您希望添加要与git存储库一起分发的文件,但不希望跟踪它们的更改
这可以通过以下四个简单步骤来完成:
步骤0:首先确保path/a_file.txt
文件中的内容与要分发的内容相匹配。据我所知,它不可能是空的,所以如果你只是想让这个文件存在,就给它添加一个换行符/空格字符
步骤1:使用git add path/a_file.txt
将文件添加到git
步骤2:提交文件(git commit path/a_file.txt
)
第3步:更新git的索引并告诉git它应该进一步忽略对文件的更改git update-index --assume-unchanged path/a_file.txt
如果您想对该文件进行一些更改,而这些更改应该再次被跟踪,您可以简单地使用--no-assume-unchanged
标志来设置它在git的索引中处于活动状态,然后提交更改。
请注意创建一个.gitignore
文件告诉git忽略文件(在克隆存储库的所有计算机上)并使用git add --force path/a_file.txt
是无效的,因为git将(force
)将其添加到索引中,同时跟踪更改。