Со временем роста количества проектов, понимаешь как дорого строит их поддержка. Когда проектов мало, то что-то править и дописывать не трудно и почти не раздражает. А вот когда количество проектов переваливает за некоторое критическое число, то становится мучительно сложно что-то менять и обновлять. А особенно, когда эти проекты зависят от некоторой единой базы кода, т.е. грубо говоря от одних библиотек.
Я всегда использую транк джанги, поскольку релизится она не часто, а для примера можете сравнить насколько отличается текущая её версия от последнего релиза. Ага, как-будто вообще разные фреймворки в некоторых местах:)
Ну транк, так транк. Все хорошо, проект пишется какое-то время со свежим транком. Потом к счастью проект релизится и выходит в продакшн. И вот через некоторое время нужно либо что-то дописать, либо что-то исправить. Ну а почему бы и джангу не обновить под шумок и ещё несколько очередных плюшек новых использовать. Не проблема, обновили, код подправили и живем дальше. Но!
Обычно я устанавливаю джангу в общедоступный PYTHONPATH, например /usr/lib/python/site-packages/ и все проекты используют именно этот, один инстанс. И тут ключевое слово все. Когда на одном хосте расположены несколько проектов, то сценарий описанный мною ранее, перестает радовать и практически не возможен.
В чем же дело? Да очень просто, обновишь один проект, а следовательно и джангу, а должен обновить и подогнать под новый срез и все остальные проекты, которые пользуются одним инстансом джанги. Засада, правда?
А как удобно, сделал ln -s в site-packages и джанга установлена. Но не практично!
Причем это касается любой библиотеки, которая имеет не очень стабильный интерфейс и подвержена периодическим изменения. Я лично имею два пакета вспомогательных библиотек, которые постоянно улучшаются и вычищаются параллельно обрастанию джанги всё новыми возможностями. Установлены они в системе по схеме аналогичной джанговской.
Первая же идея - это иметь разные версии джанги для каждого проекта. А где их лучше хранить так чтобы не было конфликта? Да прям в самом проект! Может быть для многих это очевидно и этим пользуются, но я так раньше не делал. Мне казалось, что это не удобно и ведет к рассинхронизации и хаосу. Но есть решение.
Этими же мыслями я поделился и на конференции, и после уже в кулуарной беседе Вячеслав Буханцов рассказал, как они в своей компании решают схожую проблему - они активно применяют svn:externals и "кладут" джангу рядом с проектом, чтобы он цеплял именно "свою" версию. Спасибо Вячеслав за наводку!
Суть заключается в том, что svn может сам подгружать в рабочую копию код из другого репозитория или из другой иерархии каталогов одного. Надо только прописать откуда и куда что класть. Причем очень важной особенностью является возможность указать ревизию "стороннего" кода, которая нужна.
И тут, когда я уже совсем устал от того, что из-за боязни попортить работоспособность кода, я вынужден таскать кучу legacy писанины, которая уже морально устарела, но на которой завязаны проекты, я задался целью разобраться с svn:externals.
После недолгих экспериментов я понял, что использование svn:externals достаточно удобно и решает большинство проблем синхронизации версий различного кода.
Расскажу как получилось у меня.
Что такое свойства svn и как их устанавливать я думаю вызнаете (если нет, то прочтите). Для удобства я создал файл externals в корне джанговского проекта, где описал нужные мне ссылки на библиотеки. Вот:
django -r7210 http://code.djangoproject.com/svn/django/trunk/django
lib1 -r1401 http://path/to/lib1/repo
lib2 -r1390 http://path/to/lib2/repo
Вначале идет имя директории, куда будет выполнен чекаут, далее номер ревизии и путь в репозитории. Потом я этот файл использую для установки свойства svn:externals корня рабочей копии вот так:
$ svn propset svn:externals -F externals .
Далее обычные:
$ svn up && svn commit -m "adding externals property to project"
И мы видим как svn делают чекаут нужных ревизии. В итоге получается что-то вроде такой схемы каталогов:
- project
- app1
- app2
...
- django
- lib1
- lib2
...
- __init__.py
- manage.py
- settings.py
- urls.py
Поскольку директория, где лежит проект идет первой в sys.path, то именно локальные версии джанги и других библиотек будут использованы. Теперь можно это проект размещать где угодно и всегда он будет находится в правильном "своём" окружении.
Ура, теперь я могу окончательно почистить свои библиотеки и свежие проекты уже начинать на актуальной базе.
Для новых проектов, я предпочитаю эту операцию проводить в сомом конце, когда уже на носу выпуск в продакшн и когда я точно знаю, что именно эти версии библиотек используются.
В последствии если требуется изменения, то обновляются номера ревизий на актуальные на данный момент, и проводится операция ещё раз, чтобы svn подгрузил обновления джанги и библиотек.
Этот способ конечно же подходит не только для джанги, а для любого комплексного проекта, который использует сторонние развивающиеся компоненты. Просто для джанги на данный момент это очень актуально, поскольку она очень часто обновляется, и не всегда обратно совместимо.
А вы используете подобную технику в вашем процессе разработки?
11 Комментариев к “svn:externals и django - дружба на век”
-
Dyadya Zed Апрель 20, 2008 в 03:05
-
Александр Кошелев Апрель 20, 2008 в 03:18
-
Муркт Апрель 20, 2008 в 07:51
-
Glader Апрель 20, 2008 в 09:29
-
Муркт Апрель 20, 2008 в 09:31
-
Иван Сагалаев Апрель 20, 2008 в 10:31
-
Dyadya Zed Апрель 20, 2008 в 10:49
-
Александр Кошелев Апрель 20, 2008 в 15:37
-
Александр Кошелев Апрель 20, 2008 в 18:33
-
Стас Апрель 28, 2008 в 12:52
-
scarfacer Май 14, 2008 в 12:52
