如何在未经VCS跟踪的Python sdist中分发文件?

zez*_*llo 14 python git python-3.x sdist

我想找到在python sdist中包含未被git跟踪的文件的正确方法.

上下文

.mo我的项目中的文件不会被跟踪git(就像其他一些.txt需要在安装时创建的文件一样).

setup.py在安装时写了一个小函数来创建它们,我打电话给setup():

setup(
    .
    .
    .
    data_files=create_extra_files(),
    include_package_data=True,
    .
    .
    .
)
Run Code Online (Sandbox Code Playgroud)

请注意它们应该属于,data_dir因为文档说:

data_files选项可用于指定模块分发所需的其他文件:配置文件,消息目录,数据文件,以及不适合以前类别的任何内容.

所以,这适用于python3 setup.py install(bdist也是).该.mo文件生成并存储在正确的地方.

但是如果我想要它可以使用sdist,那么我必须将它们包含在MANIFEST.in(例如recursive-include mathmaker *.mo)中.文档确实说:

在3.1版中更改:如果未提供模板,则所有与data_files匹配的文件都将添加到MANIFEST文件中 .请参阅指定要分发的文件.

(链接没有多大帮助).

我不愿意包含*.mo文件,MANIFEST.in因为它们没有被git跟踪.而check-manifest不喜欢这种情况,它抱怨这个事实lists of files in version control and sdist do not match!

那么,有没有办法解决这种丑陋的情况?

重现这种情况的步骤

环境和项目

为避免污染您的环境,请在您选择的目录中创建并激活专用虚拟环境(python3.4 +):

$ pyvenv-3.4 v0
$ source v0/bin/activate
(v0) $
Run Code Online (Sandbox Code Playgroud)

project0目录中重现以下树:

.
??? .gitignore
??? MANIFEST.in
??? README.rst
??? setup.py
??? project0
    ??? __init__.py
    ??? main.py
    ??? data
        ??? dummy_versioned.po
Run Code Online (Sandbox Code Playgroud)

其中README.rst,__init__.pydummy_versioned.po是空的.

其他文件的内容:

  • .gitignore:

    build/
    dist/
    *.egg-info
    project0/data/*.txt
    *~
    
    Run Code Online (Sandbox Code Playgroud)
  • MANIFEST.in:

    recursive-include project0 *.po
    recursive-include project0 *.txt
    
    Run Code Online (Sandbox Code Playgroud)
  • 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())
    
    Run Code Online (Sandbox Code Playgroud)
  • 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'],
        }
    )
    
    Run Code Online (Sandbox Code Playgroud)

开始本地git回购:

(v0) $ git init
(v0) $ git add .
Run Code Online (Sandbox Code Playgroud)

安装check-manifest:

(v0) $ pip3 install check-manifest
Run Code Online (Sandbox Code Playgroud)

安装并测试

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
Run Code Online (Sandbox Code Playgroud)

如果你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
.
.
.
Run Code Online (Sandbox Code Playgroud)

请注意,有列入sdist这个文件,它看起来必需的(如下面的"背景"部分解释)拥有recursive-include project0 *.txtMANIFEST.in.你会删除这一行,不再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
Run Code Online (Sandbox Code Playgroud)

那么,有没有一种正确的方法来处理这种情况?

pen*_*tix 2

据我了解您的问题,您希望添加要与 git 存储库一起分发的文件,但您不想跟踪它们的更改。

这可以通过以下四个简单步骤来完成:

步骤 0: 首先确保文件中的内容path/a_file.txt与您要分发的内容匹配。据我所知它不能为空,所以如果您只是希望该文件存在,请向其中添加换行符/空格字符。

第 1 步: 使用以下命令将文件添加到 gitgit add path/a_file.txt

步骤 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其添加到索引并跟踪更改