Как распространять файлы в Python SDDist, которые не отслеживаются VCS?

Я хотел бы найти правильный способ включить файлы в Python SDDist, которые не отслеживаются Git.

контекст

.mo файлы из моего проекта не отслеживаются git (как и некоторые другие .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, если шаблон не указан. См. Определение файлов для распространения.

(Ссылка не очень помогает).

Я не хочу включать *.mo файлы в MANIFEST.in поскольку они не отслеживаются мерзавцем. И чек-манифесту не нравится такая ситуация, он жалуется на то, что 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, необходимо (как объяснено в части "context" ниже) иметь recursive-include project0 *.txt в MANIFEST.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

Итак, есть ли правильный способ справиться с этой ситуацией?

1 ответ

Насколько я понимаю вашу проблему, вы хотели бы добавить файлы, которые будут распространяться в репозитории git, но вы не хотите отслеживать их изменения.

Это можно сделать с помощью четырех простых шагов:

Шаг 0: Сначала убедитесь, что вы внутри содержимого path/a_file.txt Файл соответствует содержимому, которое вы хотите распространять. Насколько я знаю, он не может быть пустым, поэтому, если вы просто хотите, чтобы этот файл существовал, добавьте в него символ новой строки / пробела.

Шаг 1: Добавьте файлы в git, используя git 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 не будет работать, так как мерзавец будет (force) добавить его в индекс, а также отслеживать изменения.

Другие вопросы по тегам