plugin development for intelli j platform
DESCRIPTION
TRANSCRIPT
Разработка плагиновна базе IntelliJ Platform
Николай Чашников[email protected]
Continuous Integration
● сборка плагина● запуск тестов● установка и обновление плагина в IDE
Структура дистрибутива плагинаsamplePlugin.zip
samplePluginlib
samplePlugin.jarplugin classesMETA-INF
plugin.xmlpluginLib.jar...
Сборка плагина вне IDE
● IntelliJ IDEA Project runner (TeamCity)● Ant (Build | Generate Ant Build)● ...
Настройка проекта для сборки на TeamCity
создание артефакта для плагина (File | Project Structure | Artifacts)
Build Configuration на TeamCity
● настройка VCS● настройка внешних зависимостей (IDEA
SDK)○ получение через VCS○ копирование на build agent○ получение из стороннего репозитория
(отдельный build step)
Автоматические тестирование
● честные unit tests● функциональные тесты в формате unit
tests○ тестируют поведение○ загружают IntelliJ Platform (без UI)○ время работы достаточно велико○ не меняются при изменении реализации
Запуск тестов на TeamCity
● через Ant, Maven,...● через IntelliJ IDEA Project runner:
○ создать shared run configuration в IDEA○ положить соответствующий файл в VCS○ добавить название run configuration в настройках
IDEA Project runner
Возможности TeamCity
● автоматический запуск тестов● просмотр результатов, история● назначение ответственного за падение
тестов● проверка изменений до коммита в VCS
(Remote Run)
Установка плагина в IDE
● из репозитория plugins.jetbrains.com● с диска (Settings | Plugins | Install plugin
from disk)● из собственного репозитория
Собственый репозиторий плагиновFile | Settings | Plugins | Browse Repositories | Manage Repositories,добавить ссылку на plugins.xml.
plugins.xml:<plugins><plugin id="samplePlugin" url="PluginZipFileUrl.zip" version="1.0"/>
</plugins>
Архитектура IntelliJ Platform
Компоненты, сервисы, точки расширения
Система компонентов
● экземпляры объектов хранятся в иерархии контейнеров PicoContainer
● иерархия состоит из трёх уровней○ Application○ Project○ Module
● регистрируются в plugin.xml
Получение экземпляра компонента
● метод getInstance(), getInstance(project), getInstance(module)
● dependency injection через параметры конструктора (другие компоненты данного уровня или более высоких уровней)
Компоненты● наследуются от ApplicationComponent,
ProjectComponent, ModuleComponent● регистрируются в <application-components>, <project-
components>,... в plugin.xml● загружаются при старте IDE (загрузке проекта,
загрузке модуля)
init use dispose
● не накладывают ограничений на наследование
● регистрируются в <applicationService>, <projectService>, <moduleService>
● загружаются при первом обращении (ServiceManager.getService())
● если реализован интерфейс Disposable, метод dispose вызовется при закрытии IDE (проекта, модуля)
Сервисы
Точки расширения
● регистрируются в <extensionPoints>● полное имя - <plugin id>.<extension name>● предполагают несколько реализаций● для доступа к расширениям создаётся
константа ExtensionPointName
Точки расширения
● бывают двух видов:○ beanClass - дают возможность задавать
атрибуты расширения прямо в xml○ interface - в расширении указывается только
ссылка на класс, реализующий интерфейс● могут быть уровня проекта или модуля
(атрибут area), по умолчанию уровня application
Расширения
● регистрируются в <extensions>○ для расширений вида beanClass заполняются
атрибуты○ для расширений вида interface указывается
полное имя класса в атрибуте implementation● загружаются при первом обращении
(ExtensionPointName.getExtensions())
Плагины и их зависимости
Plugin classpath
● jar файлы плагина (*.jar в директории ‘lib’)● jar файлы плагинов, от которых он
зависит● jar файлы IDEA (*.jar в директории
<IDEA_HOME>/lib )
Зависимости плагина
Определяются через <depends> в plugin.xml
Опциональные зависимости
Задаются тэгом<depends optional=”true”
config-file=”fileName.xml”>в plugin.xmlКомпоненты из файла fileName.xml загружаются только в случае, если указанный плагин доступен
Работа с фреймворками
Конфигурирование фреймворка
● конфигурирование не требуется● специальная библиотека (SDK)● на уровне модуля● на уровне проекта
Фреймворк без конфигурации● не требуется явных действий “добавить фреймворк”● экшены (completion, inspections,...) определяют
наличие фреймворка по аннотациям, наличию класса в зависимостях модуля (JavaPsiFacade.findClass(...,module.getModuleWithDependenciesAndLibrariesScope()),...
Фреймворк-библиотека
● задаётся при помощи LibraryType● можно хранить дополнительные
настройки прямо в библиотеке● настройки редактируются в библиотеке в
диалоге Project Structure
Фреймворк в настройками в модуле
● задаётся при помощи Facet (extension FacetType)
● настройки редактируются в диалоге Project Structure
Фреймворк с настройками в проекте
● настройки хранятся в project service● редактируются в диалоге Settings
(extension projectConfigurable)
Подключение фреймворка
● extension frameworkSupport (класс FrameworkSupportProvider)
● опция появляется в диалоге “New Project/Module Wizard” и в диалоге “Add Framework Support” (popup menu в Project View)
Ссылки
Исходный код плагина с примерами:https://github.com/chashnikov/intellij-sample-plugin