Библиотека сайта rus-linux.net
Архитектура Mercurial
Глава 12 из книги "Архитектура приложений с открытым исходным кодом", том 1.
Оригинал: "Mercurial".
Автор: Dirkjan Ochtman
Перевод: Vlad http://vlad8.com/
12.5. Расширяемость
Одним из факторов, который делает Mercurial очень мощным, является возможность написания расширений под него. Так как Python является языком, начать писать на котором довольно просто, а API Mercurial по большей части хорошо спроектирован (хотя и не всегда полностью документирован), некоторые люди начали писать на Python в первый раз именно потому, что они захотели написать расширение для Mercurial.
12.5.1. Написание расширений
Расширения включаются путем добавления строки в один из конфигурационных файлов, которые Mercurial читает при загрузке. Есть несколько способов добавить функционал:
- добавление новой команды;
- создание оболочки для существующей команды;
- создание оболочки для используемого репозитория;
- обертка любой функции в Mercurial;
- добавление новых типов репозитория.
Добавление новых команд может быть выполнено просто путем добавления хэшированной таблицы под названием cmdtable в модуль расширения. Он будет подгружен загрузчиком расширений, который добавит новую команду в таблицу команд, используемую при обработке команд. Аналогично, расширения могут определять функции uisetup и reposetup, которые вызываются в коде диспетчера, после того как созданы объекты пользовательского интерфейса и репозитория. Типичным способом является использования функции reposetup для оборачивания репозитория в подкласс репозитория, предоставляемый расширением. Это позволяет расширению модифицировать базовое поведение. Например, одно расширение, которое я написал, подцепляет uisetup и устанавливает свойство конфигурации ui.username в зависимости от данных доступа SSH, доступных из окружения.
Более серьезные расширения могут быть написаны для добавления типов репозиториев. Например, проект hgsubversion (не включенный в Mercurial) регистрирует тип репозитория Subversion. Это делает возможным клонирование репозитория Subversion, как будто это репозиторий Mercurial. Существует даже возможность обратной отправки данных в репозиторий Subversion, хотя в определенных случаях возможны проблемы из-за различий в двух системах. Пользовательский интерфейс, с другой стороны, полностью прозрачен.
Для тех кто хочет глубоко изменить Mercurial, в мире динамических языков существует такая вещь как «monkeypatching». Так как код расширений выполняется в том же адресном пространстве, что им Mercurial, а Python — это достаточно гибкий язык с широкими рефлективными возможностями, возможно (и достаточно легко) модифицировать любой класс или функцию, определенную в Mercurial. Хотя это может привести к довольно уродливым хакам, это действительно мощный механизм. Например, расширение highlight (представлено в hgext) модифицирует встроенный веб-сервер, чтобы добавить подсветку синтаксиса на страницы браузера репозитория, что позволяет вам просматривать содержимое файлов.
Есть еще один способ расширения функциональности Mercurial, гораздо более простой: алиасы. Любой конфигурационный файл может определять алиас в качестве нового имени для существующей команды с определенным набором заданных опций. Это также дает возможность давать более короткие названия любой команде. Последние версии Mercurial также включают возможность вызова команд шелла через алиасы, так что вы можете создавать сложные команды не используя ничего, кроме шелл-скриптов.
12.5.2. Перехватчики
Системы контроля версий давно предоставляли механизм перехватчиков в качестве способа взаимодействия событий этих систем с окружающим миром. Обычной практикой является отправка уведомляющего сообщения в систему постоянной интеграции или обновление рабочей копии на веб-сервере таким образом, чтобы изменения стали видимы во всем мире. Конечно, такие возможности присутствуют и у Mercurial.
В действительности, здесь также присутствуют два варианта. Один больше похож на традиционные перехватчики в других системах контроля версий, он вызывает скрипты в шелле. Другой более интересен, потом что позволяет пользователям вызывать Python-овские перехватчики, указывая модуль Python и имя функции из этого модуля для вызова. Это не только быстрее, потому что работает в том же процессе, но при этом также используются объекты repo и ui, то есть вы можете легко создавать более сложное взаимодействие внутри системы контроля версий.
Перехватчики в Mercurial могут быть разделена на предкомандые, посткомандные, управляющие и дополнительные. Первые две категории просто определяются путем указания ключей pre-команда или post-команда в секции перехватчиков в конфигурационном файле. Для двух других типов есть предопределенный набор событий. Различие в управляющих перехватчиках состоит в том, что они запускаются прямо перед тем, как что-то происходит, и могут не позволить этому событию выполняться дальше. Они обычно используются для валидации изменений каким-либо образом на центральном сервере; по причине распределенной природы Mercurial такие проверки не могут быть выполнены во время коммита изменений. Например, проект Python использует перехватчик, для проверки применения некоторых аспектов стиля кода — если изменение добавляет код, который имеет не разрешенный стиль, он будет отвергнут центральным репозиторием.
Еще один интересный способ использования перехватчиков — это pushlog, который используется в Mozilla и некоторых других компаниях. Pushlog записывает каждое добавление кода (так как при этом может содержаться любое число изменений) и записывает, кто инициировал это добавление и когда, то есть создается своего рода отчетность по использованию репозитория.
Продолжение статьи: Выводы.