Всем добрый день!
На Хабре уже поднималась тема организации работы с внешними пакетами с использованием подмодулей или деревьев в Git. Это показалось хорошим решением, но на деле вылилось в неудобства и запутанность. Тогда я решил перенести всё на python-пакеты. Чем и поделюсь сейчас на примере Django приложения.
Вместо предисловия
Когда делаешь много разных проектов, накапливаются свои модули, расширения, утилиты. Между ними устанавливаются зависимости. И встает вопрос в удобной организации инфраструктуры разработки и развертывания проектов. Чтобы было более наглядно, расскажу применимо к Django проектам.
Создадим Django-приложение и выделим его в python-пакет. Приложение будет отображать новости. В административной части сайта, нам потребуются собственные наработки по юзабилити. По этому укажем в зависимостях пакет app-admintools.
Подготовка
Создадим в Gitosis репозиторий app-news:
gitosis-admin/gitosis.conf
[group apps]
writable = app-news
members = @developers @hosts
отправим изменения:
git pull
инициируем:
git clone git@git.home.com:app-news
Структура нашего пакета
+-app-news/
+-home/
+-news/
+-locale/
+-static/
+-templates/
+-__init__.py
+-models.py
+-urls.py
+-views.py
+-__init__.py
+-MANIFEST.in
+-setup.py
setup.py
from setuptools import setup, find_packages
setup(
name='home.news',
version='0.1',
description='News for Django',
author='Elias',
namespace_packages=['home'], # line 8
packages=find_packages(),
platforms='any',
zip_safe=False,
include_package_data=True,
dependency_links=['git+ssh://git@git.home.com/app-admintools@v0.1#egg=admintools-0.1'], # line 13
install_requires=['admintools==0.1'], # line 14
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
'Framework :: Django',
],
)
Здесь мы объявили использование пространства имен home (стр. 8) и указали зависимости для пакета home.news в наш репозиторий (стр. 13,14).
MANIFEST.in
recursive-include home/*/locale *
recursive-include home/*/static *
recursive-include home/*/templates *
Манифест определяет дополнительные данные, которые нужны пакету.
home/init.py
import pkg_resources
pkg_resources.declare_namespace(__name__)
Регистрируем пространство имен.
Создадим удаленную ветку v0.1 из master:
git push origin master:v0.1
Всё! Пакет готов к установке:
pip install git+ssh://git@git.home.com/app-news@v0.1
или в режиме редактирования:
pip install -e ./app-news
или через setuptools:
python setup.py develop
но в таком случае, не получиться закачать зависимости в виде ссылок на репозитории, так как setuptools не поддерживает такой формат
Подключение пакета
Один способ я описал выше, в виде зависимостей setup.py.
Также удобно хранить зависимости в отдельном файле requirements.txt (например для сайта):
git+ssh://git@git.home.com/app-news@v0.1
и ставить через pip:
pip install -r requirements.txt
Заключение
Идея переложить управление зависимостями на Git оказалась неудобной (использовал подмодули). В первую очередь это проявилось, когда нужно было писать код и отлаживать его сразу в двух проектах, с общими компонентами, которые нужно было синхронизировать. Обычно через коммит. Другая проблема возникала, когда одновременно два разработчика обновляют пакет и ссылку на него. В итоге нетривиальная миграция. И так далее… Но теперь пакет можно поставить в режиме редактирования и править код без синхронизаций. Одновременно остались все прелести доступа к пакетам по ssh-ключам.
Надеюсь статья вам поможет упростить разработку и стать чуть-чуть счастливее :)
Спасибо за внимание, удачи!