Подготовка и публикация модуля 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