Исключение исходных файлов из встроенного дистрибутива rpm с помощью setuptool

У меня есть типичная структура проекта, которая выглядит следующим образом:

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='[email protected]'
   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   

И My 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 <generated egg file>, мой файл eg.info копируется, но исходные файлы не копируются в /usr/lib/python2.6/site-packages. Я ожидал, что у меня будет каталог с именем Engine.

Может ли кто-нибудь указать, что я делаю неправильно? Заранее спасибо.


person as3rdaccount    schedule 24.07.2014    source источник
comment
@ArunaDev Предполагая, что ваш проект чисто Python (в вашем проекте нет кода C или C++), я бы рекомендовал использовать sdist, а не egg. Я также предполагаю, что вы устанавливаете в той же ОС, что и яйцо. Научитесь использовать pip и по возможности прекратите использовать easy_install. pip обслуживает гораздо лучше. Вы сможете $ pip install <package_file> установить из egg, sdist или других форматов.   -  person Jan Vlcinsky    schedule 25.07.2014
comment
pip не поддерживает яйцо. sdist будет работать, но мы хотим, чтобы некоторый код C был предварительно собран перед передачей клиентам. Также по другим причинам, в которые я не буду вдаваться, мы хотим отправлять только файлы .pyc.   -  person as3rdaccount    schedule 25.07.2014
comment
@ArunaDev Извините, я ошибся с pip и яйцами. Возможно, вам будет удобно использовать формат wheel — это более быстрый способ установки пакета. Но, похоже, он включает исходные файлы Python, поэтому он может не соответствовать вашим критериям. В любом случае, наличие только pyc не такая уж большая победа, как только я по ошибке удалил свои py-файлы и сумел получить пригодный для использования исходный код из pyc-файлов в течение часа поиска в Google, тестирования, декомпиляции и редактирования.   -  person Jan Vlcinsky    schedule 26.07.2014
comment
Да, это не столько причина для простоты декомпиляции... это гораздо проще для поддержки.   -  person as3rdaccount    schedule 26.07.2014


Ответы (1)


Старайтесь, чтобы все было как можно проще.

Быстрая проверка с sdist

Попробуй это:

$ python setup.py sdist

Он должен создать исходный файл дистрибутива для вашего пакета.

Он находится в формате zip, поэтому распакуйте его и проверьте, присутствуют ли внутри все ожидаемые файлы.

Если нет, вам нужно найти причину, по которой ожидаемые файлы отсутствуют в вашем дистрибутиве.

Проверка вещей шаг за шагом (и упрощение)

Вы используете расширение .py?

Может быть глупый вопрос, но в вашем списке файлов я не вижу py-файлов внутри дерева src.

Если у вас там только файлы без расширения .py, то find_packages ничего не найдет.

Где у вас находятся файлы __init__.py?

Дайте нам знать, где находятся файлы:

$ cd src
$ find . -name "*.py"

Если вы пропустите __init__.py, find_packages не найдет весь пакет.

Удалить пакет utils

Зачем оно тебе там?

Лучше установить его из исходного кода, который вы разрабатываете, или переместить его в подкаталог в корне вашего проекта.

Это сделает prune src/utils ненужным в вашем MANIFEST.in.

Поместите в MANIFEST.in только то, что должно быть там

Если вы читаете документ для MANIFEST.in, в нем указано, какие файлы включаются автоматически (все, что указано в аргументах функции setup, поэтому в вашем случае все исходные файлы python возвращаются find_packages).

По этой причине вы должны удалить 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

потерпит неудачу на утверждениях. Это признак того, что некоторые из ожидаемых файлов отсутствуют. Проверь это.

После того, как вы сделаете свой проект простым, вы можете добавить больше деталей (и делать это шаг за шагом, чтобы быть уверенным, что вы ничего не сломаете).

person Jan Vlcinsky    schedule 24.07.2014
comment
Ян Большое спасибо за ответ! Да, в моем каталоге src был файл __init__.py, который я пропустил в рассматриваемом коде. И содержимое sdist действительно содержит модули. assert тоже проходит. Я сделал все изменения, которые вы предложили. Затем я запускаю easy_install python setup.py bdist_egg, но когда на целевом компьютере я запускаю easy_install ‹generated_egg›, ни один из исходных файлов не копируется в /usr/lib/python2.6/site-packages/. Я ожидал каталог «Двигатель», я прав (поскольку это имя проекта, которое я указал)? Есть только директория Engine-1.0.0-py2.7.egg. - person as3rdaccount; 25.07.2014
comment
@ArunavDev Попробуйте $ pip freeze и проверьте, указан ли пакет. Попробуйте pip show Engine, это покажет вам, где установлен пакет. Самое главное, если вы можете импортировать модуль. Создание некоторых директорий - второстепенная тема. Кстати, вы используете virtualenv? Если это так (и это настоятельно рекомендуется), пакеты устанавливаются в каталоги virtulanev, а не в систему. - person Jan Vlcinsky; 25.07.2014
comment
@ArunavDev Кстати, в каталоге src не должно быть пакета __init__.py. __init__.py должен быть только в каталогах, которые являются пакетами, а src должен быть не пакетом, а родительским каталогом каталогов пакетов. - person Jan Vlcinsky; 25.07.2014
comment
Спасибо, январь. Замораживание pip показывает, что Engine == 1.0.0, а pip show Engine показывает расположение файла яйца в пакете сайта. Похоже, файл яйца внутри содержит файл Engine и EGG-INFO. Это побеждает мою конечную цель, поскольку Engine больше не находится в PYTHONPATH по умолчанию. - person as3rdaccount; 25.07.2014