Подготовка и публикация модуля Django ===================================== Этот материал рассчитан на тех, кто уже написал свой модуль для Django и хочет, чтобы его труд оценили. Я бы хотел пояснить, зачем нужно готовить пакет для python. Как написано на сайте redsolutioncms.org, :: мы столкнулись с тем, что какая-нибудь наша библиотека уходит за ненадобностью, потому что OpenSource сообщество сделално подобную вещь хоть позже нас, но лучше Итак, для чего вам нужно опубликовать свой модуль: * Чтобы снискать славы в OpenSource-сообществе; * грамотно опубликованный модуль заведомо имеет хорошую организацию кода, снабжен тестами и документацией; * оформляя свой модуль, вы показываете уважение в первую очередь вашим коллегам, которым предстоит работать с вашим кодом, а так же всем разработчикам, которым ваш код может быть полезен; * наконец, самому приятно, если твой код выглядит красиво и ухожено. Требования к модулям -------------------- Насчёт организации кода `сказано `_ `много `_ `слов `_. При публикации каждый сам решает, на что обратить больше внимания, на что меньше, а что вообще обойти. Я опишу технологию выпуска модулей в нашей компании, которая, судя по практике, имеет право считаться удобной :) 1. Зависимости ``````````````` Все зависимости от других должны быть прописаны в setup.py, зависимость от самой Django мы не прописываем, чтобы при установке её не скачивал easy_install. 2. Интернационализация `````````````````````` В модуле не должно содержаться ни строчки по-русски. В идеале не должно быть комментариев и текстов коммита не на английском. Мы стараемся в общем придерживаться этого идеала. Ко всем модулям создается русская локаль, так что сразу заметно, если что-то не переведено. 3. Тесты ````````` Наше слабое место. Тем не менее я категорически настаиваю на наличии тестов у сколь бы то ни было сложных модулей. Существует множество удобных фреймворков для тестов (от Selenium до webtest), пользуйетсь ими на здоровье! 4. Документация ``````````````` Каждый наш модуль содержит, как минимум, описание в README. Если модуль требует бОльшей документации, то её необходимо предоставить пользователю. 5. Контроль версий `````````````````` Мы долго размышляли о том, как публиковать версии того или иного модуля. Мы используем трехзначную систему именования версий: :: [0].[мажорный релиз].[минорный релиз] Вместо нуля первой цифрой станет 1, когда мы посчитаем модуль стабильным и неизменным. В `гите `_ мы делаем так: для мажорных версий созданы ветки, а для минорных - тэги. Это сделано для того, чтобы при использовании одной и той же мажорной версии модуля можно было получить багфиксы в минорных версиях. Чем мажорные от минорных отличаются спрашиваете? Между двумя мажорными версиями сохраняется API и структура БД. Минорные версии могут добавлять новые возможности и исправлять ошибки. Стандарт оформления ------------------- Мы стараемся оформлять модули по одному алгоритму: В корень проекта добавляются в обязательном порядке файлы: * **MANIFEST.in** - файл для подключения медиа-файлов в проект. * **README.rst** - файл с кратким описанием и примерами применения модуля в формате `RST `_ * **README -> README.rst** симлинк. Именно такой. Дело в том, что гитхаб не понимает симлинки, а хочется видеть документацию на гитхабе и на PYPI * **DESCRIPTION** - такое описание модуля, чтобы человек не в теме понял для чего нужен этот модуль * **setup.py** - файл установщика Помимо этого, в __init__.py файле модуля должна быть переменная __version__, которая содержит номер текущей версии модуля. Например :: __version__ = '0.1.0' Текст README проверяйте на валидность http://www.tele3.cz/jbar/rest/rest.html, иначе на Python Package Index форматирование не будет отображаться, документация будет в текстовом формате. Пример MANIFEST.in `````````````````` Файл MANIFEST.in нужен для того, чтобы в egg-пакет вошли медиа-файлы (шаблоны, стили, js-скрипты) :: recursive-include chunks * include README README.rst DESCRIPTION INSTALL.txt exclude *.orig *.pyc Пример setup.py ``````````````` setup.py по сути, самый главный файл при публикации модуля. Он определяет всю мета-информацию о пакете, разработчике, лицензии, файлах и т.п. в модуле .. code-block:: python # -*- coding: utf-8 -*- import os from setuptools import setup, find_packages # Utility function to read the README file. # Used for the long_description. It's nice, because now 1) we have a top level # README file and 2) it's easier to type in the README file than to put a raw # string in below ... def read(fname): try: return open(os.path.join(os.path.dirname(__file__), fname)).read() except IOError: return '' setup( name="redsolutioncms.django-myapp", version=__import__('myapp').__version__, description=read('DESCRIPTION'), license="GPL", keywords="django tag1 tag2", author="John Doe", author_email="author_email@example.com", maintainer='John Doe', maintainer_email='maintainer_email@example.com', url="http://github.com/redsolution/myapp", classifiers=[ 'Development Status :: 3 - Alpha', 'Intended Audience :: Developers', 'License :: GPL', 'Framework :: Django', 'Environment :: Web Environment', 'Natural Language :: Russian', 'Natural Language :: English', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', ], packages=find_packages(exclude=['example', 'example.*']), install_requires=[], include_package_data=True, zip_safe=False, long_description=read('README'), entry_points={ 'redsolutioncms': ['myapp = myapp.redsolution_setup', ], } ) Следует привести комментарии к некоторым строкам. Во-первых, данный ``setup.py`` подразумевает, что файлы ``README`` и ``DESCRIPTION`` существуют. Если это не так - опсание будет пустое. Более того, версия будет пустая, если в ``__init__.py`` не будет переменной ``__version__``. Строка ``packages=find_packages(exclude=['example', 'example.*']),`` говорит о том, что если в модуле есть папка ``example``, и она является питоновским модулем, то её нужно исключить из пакета - представьте, если дюжина модулей будет импортировать один и тот же модуль ``example``. Параметр ``entry_points`` нужен для интеграции с Redsolution CMS, об этом в статье про интеграцию. Полная спецификация по параметрам `приведена `_ на сайте разработчика setuptools. На самом деле, я наблюдаю тенденцию отчуждения от модуля setuptools в пользу того же `distribute `_, однако мы остановили выбор на стабильной и проверенной библиотеке. Публикация ---------- Опубликовать модуль на PYPI очень легко. В первую очередь, вам нужен будет аккаунт на PYPI. Затем, зайдите в папку проекта и наберите :: python setup.py register