Стыдно признаться, но...

Опубликовано 24.04.2008

…я до сегодняшнего вечера не знал, как применить патч к проекту в SVN с использованием командной строки. С того момента, как я начал пользоваться Subversion, меня повсюду окружали графические инерфейсы - TortoiseSVN, встроенный клиент в Eclipse, потом NetBeans. И только сегодня впервые понадобилось пропатчить проект, а интерфейса-то под руками и нет!

А делается все на самом деле просто:

patch -p0 -i /path/to/my/patch.diff

Пишу чтобы больше не забывать :)

P.S. А проект, к которому применяем патч - небезынтересный клон старого доброго Master of Orion: Free Orion. Если вы фанат давно забытой игры - рекомендую взглянуть.

Subversion под Windows - запуск сервиса

Опубликовано 02.07.2007

Вот у меня возникла такая задача: я хочу запустить Subversion под Windows в качестве сервиса (службы), чтобы доступ к локальному репозиторию был постоянно, без запуска сервера вручную. Давайте попробуем это сделать.

В первую очередь, нам нужно поставить свежий дистрибутив Subversion для Windows. Устанавливаем его, например в папку C:\Program Files\Subversion.

После установки Subversion нам необходимо создать папку, в которой будут храниться наши локальные репозитории. Например, это будет папка D:\Repository.

Далее, нам потребуется утилита instsrv.exe. Ее можно скачать вместе с Windows Resource Kit (его искать на хомяке у дяди Гейтса, где конкретно - не скажу) или просто взять отсюда (спасибо WinAll за малый объем архива). Файл надо распаковать и содержимое скопировать в папку C:\Windows\system32

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

instsrv.exe “Subversion Server” “c:\Program Files\Subversion\bin\svnserve.exe”

После выполнения этой команды мы в списке служб можем увидеть новую службу под названием Subversion Server. Запускать ее пока рано, нужно сделать еще немножко телодвижений. Нужно открыть в редакторе реестра (regedit) ветку HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Subversion Server и поправить в ней параметр ImagePath, указав в нем следующее значение:

c:\Program Files\Subversion\bin\svnserve.exe --service -r d:\repository

Ключ --service означает, что программа должна запускаться как сервис, а параметр -r d:\repository дает программе понять, что все запрашиваемые адреса надо обрабатывать относительно директории d:\repository.

Сохраняем значение параметра и запускаем сервис. Если все сделано правильно, сервис должен успешно запуститься.

Далее, заходим в папку d:\repository и создаем репозиторий:

svnadmin create myfirstrepo

Теперь мы можем начинать работу с этим репозиторием используя адрес svn://127.0.0.1/myfirstrepo/

Удачного коммита!

UPD: В комментах MiRacle рассказал как можно создать сервис в Windows XP без загрузки дополнительных утилит. За это спасибо ему большое.

Внешние ресурсы для приложений

Опубликовано 03.06.2007

После перехода перехода с PHP на Ruby on Rails и отказа от изобретения собственных велосипедов, у меня появилась новая страсть, которую необходимо как-то контролировать - встраивание чужих велосипедов в свою систему. При создании Rails-приложений довольно сложно обойтись без использования сторонних библиотек. Сложно не потому, что эти библиотеки обязательны, а потому, что грех не использовать такие замечательные вещи, как acts_as_authenticated, better_nested_set, acts_as_dropdown, rspec и многие другие.

Создатели языка Ruby и фреймворка Rails на славу потрудились над общей схемой использования чужого кода в проектах. В большинстве случаев достаточно просто установить gem на сервере или скопировать необходимый плагин в папку vendor/plugins. Однако, даже при такой упрощенной схеме есть тонкие моменты, которые видны не сразу и могут проявиться в самый неподходящий момент.

В одном из наших проектов используется около десятка сторонних библиотек, включая Edge Rails, подключенных через svn:externals. Для тех кто слабо знаком с тонкостями работы Subversion, я поясню: такая схема подключения означает, что в локальном репозитории хранится только код приложения, а сторонние библиотеки упоминаются исключительно в виде ссылок на сторонние репозитории. При скачивании последней актуальной версии кода приложения SVN-клиент автоматически подключается к внешним репозиториям библиотек и скачивает оттуда последнюю актуальную версию.

В принципе, схема достаточно удобная - в своем репозитории вы храните только свой собственный код, весь сторонний код вы берете непосредственно у его производителя. Однако, стоит задуматься о возможных проблемах. Например, сайт создателя замечательной библиотеки, которую вы везде и всюду используете в своем приложении, неожиданно падает на пару дней (такое периодически бывает с RubyForge, в моем случае именно он был последней каплей). Или, например, автор решает добавить в библиотеку классную фичу, которая не стыкуется с вашим кодом. И вы не можете обновить код приложения т.к. завязаны на чужой код, не можете развертывать свое приложение на сервере, у вас связаны руки-ноги. Что делать? О таких вещах лучше подумать заранее.

А вариант предвосхищения подобных проблем, на самом деле, только один - хранить код необходимых библиотек у себя. Однако, казалось бы очевидный метод “спихать все в репозиторий приложения” - не самый лучший, особенно если у вас несколько приложений, использующих одни и те же библиотеки. Излишний бардак вам не нужен, его можно избежать.

Немножко порывшись в книжках и статьях по Subversion, я откопал замечательный способ - отдельный локальный репозиторий под внешние библиотеки. Делается это так:

  1. Создаем репозиторий, например с именем vendor, на том же сервере, где вы храните основной репозиторий приложения.
  2. В репозитории создаем папки под каждую из сторонних библиотек:

    -+-vendor
     |-acts_as_dropdown
     |-netter_nested_set
     |-rails
    
  3. Выкачиваем необходимые версии библиотек на свой локальный компьютер через svn checkout

  4. В репозитории в папках библиотек создаем папки с названиями, соотвествующими номерам текущих ревизий выкачаных библиотек (можно посмотреть с помощью команды svn info в папке библиотеки):

    -+-vendor
     |-acts_as_dropdown
     |  +-12
     |-better_nested_set
     |  +-127
     |-rails
        +-8557
    
  5. Импортируем код из локальных папок в репозиторий в соответствующие папки с номерами версий

  6. Делаем ветки от папок с номерами версий в папку current для каждой библиотеки:

    -+-vendor
     |-acts_as_dropdown
     |  +-12
     |  +-current
     |-better_nested_set
     |  +-127
     |  +-current
     |-rails
        +-8557
        +-current
    

Собственно, это все. С этого момента уже можно начинать использовать локальный репозиторий в своих целях. Для этого нужно в проектах поменять ссылки svn:externals с внешних репозиториев на соответствующие папки current локального репозитория. При следующем обновлении библиотеки будут тянуться уже из локального репозитория.

Если вам потребуется обновить какую-то библиотеку до последней актуальной версии, то достаточно обновить локальные папки с библиотеками командой svn update (или заново выкачать эти библиотеки через svn checkout) и повторить пункты 4-6:

    -+-vendor
     |-acts_as_dropdown
     |  +-12
     |  +-15
     |  +-current
     |-better_nested_set
     |  +-127
     |  +-131
     |  +-current
     |-rails
        +-8557
        +-8560
        +-current

На мой взгляд, схема более чем удобная. Как итог мы получаем сразу ворох выгод:

  1. Держим все библиотеки в своем кармане и не зависим от сторонних источников
  2. Можем обновлять версии библиотек одновременно во всех проектах используя папки current в качестве основных источников
  3. Можем использовать строго определенную версию библиотеки, ссылаясь на папку, соответствующую нужному номеру версии
  4. Можем модернизировать исходный код библиотек и использовать его независимо от того, принимает автор патчи к своим библиотекам или нет

Удачного чекаута!

Полезные ссылки: