Разработка плагинов — это и радость, и боль. Радует то, что вы можете реализовать его через плагины в соответствии с вашими потребностями, например, разработку плагинов Chrome, которую вы часто видите. Плагины приносят большую пользу родной экологии приложения, и часто особенно отличные плагины даже официально включены или к официальным функциям добавляются функции плагинов. Боль в том, что нужно лезть в документацию, смотреть различную документацию по разработке плагинов, если документация не подробная, то боль удваивается. Самое неприятное для программиста — читать чужие документы и писать свои. Конечно, помимо документации, как новичок, вы еще и наступите на всевозможные ямы.

Тукао первый

Во время Первомая эпидемия была очень скучной, поэтому мне пришла в голову идея написать плагин для обнаружения SCA на Goland. Как компания-разработчик IDE, Jetbrains разработала такие прекрасные и мощные продукты IDE, как семейство корзин IDEA, используя экологию языка Java. Технические возможности, стоящие за этим, должны быть убедительными. IDE — это продуктивность разработки программистов, а Jetbrains — продуктивность продуктивности. В последние несколько дней автор усердно работает над разработкой первого подключаемого модуля обнаружения SCA для Goland. По сравнению с предыдущей разработкой подключаемого модуля Chrome или Burp, сложность разработки подключаемого модуля Jetbrains значительно улучшилась, в основном по следующим причинам:

Документация API слишком упрощена

IntelliJ предоставляет только официальные адреса документации. Это содержит некоторую реализацию API и введение, но это слишком просто. Примера кода для соответствующей реализации во всей статье почти нет, обычно вводятся лишь несколько слов. Например, я надеюсь, что смогу создавать файлы через плагины.Порывшись в официальной документации, я нашел только следующее:

картина

В документации упоминается  PsiDirectory , что  add метод in можно использовать для сохранения  PSI файла, но не сказано, КАК! Что делать тогда, можно только зайти на Github для поиска ключевых слов в коде, а потом парсить чужой код, чтобы посмотреть, как его реализуют другие.Это определенно очень болезненный процесс, особенно если вы смотрите на плагин с плохой реализацией .

сложность API

Из-за мощной экологии IDEA, его API должен учитывать совместимость и множество функций, поэтому многие значения в API непросты для понимания. Он также содержит множество сложных элементов конфигурации, и в то же время необходимо всесторонне рассмотреть форму, в которой реализован плагин.

Слишком "мощный" официальный шаблон

Официальный предоставляет шаблон для создания плагинов. Первое, что нужно признать, это то, что этот шаблон очень мощный, он охватывает весь жизненный цикл разработки плагинов, модульного тестирования, контроля качества, публикации и легко интегрируется с Github. Но как шаблон, содержит ли он слишком много контента? Прочитав README этого шаблона почти три раза, я понял, что он содержит. На самом деле, для новичка этот процесс достаточно болезненный, а у некоторых даже может возникнуть желание отступить, увидев это. Некоторые модули в нем, такие как модуль модульного тестирования и модуль проверки покрытия, могут использоваться как опции и не должны включаться по умолчанию.

Багов немного больше

Не было определено, является ли это ошибкой, но я серьезно сомневаюсь, что это так. Упомянутый выше шаблон реализует ряд задач через Gradle. В  Run Verifications , есть небольшая задача  ./gradlew listProductsReleases, она будет  build генерировать файл в  listProductsReleases.txt файле. И версия в этом файле должна работать для проверки совместимости с IDE. Но в процессе выполнения этой задачи неоднократно возникает следующая ошибка:

картина

Ошибка для этой задачи связана с невозможностью загрузить  GO-2021.1.4 версию IDE. Насколько я понимаю, эта версия должна быть версией, соответствующей Goland, а версия IDEA может ссылаться на официальную страницу со списком версий. Ссылка в отчете об ошибках — это информация о выпуске каждой IDEA.

картина

В информации о выпуске Go я действительно не вижу  2021.1.4 информации о версии, и этот номер версии  listProductsRelases генерируется. И невозможно знать, каков принцип этого поколения. После полдня непрерывных попыток я наконец обнаружил, что эта информация о версии связана с gradle.properties  , pluginSinceBuild и  , pluginUntilBuild наконец, обнаружил, что это было вызвано  pluginSinceBuild = 211 этим элементом конфигурации, и, наконец, изменил номер версии на 212, и  2021.1.4 эта версия не была сгенерирована. Эта конфигурация информации о версии предоставляется официальной конфигурацией шаблона, и некоторые плагины используют ту же конфигурацию на Github, поэтому в настоящее время подозревается, что это вызвано официальной ошибкой.

Теперь это официально подтверждено как ошибка. Тем не менее, влияние этой ошибки по-прежнему относительно велико, потому что подключаемый модуль должен быть проверен на совместимость перед его выпуском, но в настоящее время он не может пройти проверку совместимости с последней версией Goland, в результате чего подключаемый модуль -в невозможности использования в последней версии.

Позже я столкнулся с очень странным багом, сначала оказалось, что  map его нельзя получить в коде. Повозившись какое-то время, я обнаружил, что  Run Plugin плагин не каждый раз перекомпилировался. Следствием этого является то, что после изменения кода измененный код не вступает в силу. Эта проблема также была определена как ошибка в gradle-intellij-plugin. На данный момент в этом шаблоне плагина есть две ошибки, На самом деле  changelog , есть еще небольшая ошибка, но она не будет упомянута, потому что она не особо влияет на использование.

картинаКонечно, Jetrains YYDS, несмотря на вышеперечисленные недостатки, не скрывает своих недостатков.Функции экологических плагинов IDEA по-прежнему очень мощные. Более того, пройдя через яму, официальный шаблон предоставляет вам различные удобства, позволяя вам пользоваться комплексным обслуживанием от разработки до выпуска. Ниже начинается настоящее путешествие по разработке этого плагина Goland.

СКА

Лу Синь однажды сказал, что хорошие программисты обязательно будут читать исходный код других людей. Как известное изречение Ньютона, стоять на плечах гигантов — одно и то же. В процессе разработки плагинов, несомненно, необходимо учиться тому, как разрабатываются другие плагины. Официальный проект предоставляет образец, но реализованные в нем функции очень просты.

https://github.com/JetBrains/intellij-образцы

Для разрешения зависимостей проекта Go вам необходимо  go.mod проанализировать файл, чтобы получить его. Взяв в качестве примера гобустер, его  go.mod определение выглядит следующим образом:

module github.com/OJ/gobuster/v3

require (
github.com/google/uuid v1.2.0
github.com/spf13/cobra v1.1.3
golang.org/x/sys v0.0.0-20210426080607-c94f62235c83 // indirect
golang.org/x/term v0.0.0-20210422114643-f5beecf764ed
)

go 1.16

require Контент, определенный в, представляет собой зависимости проекта и их соответствующие версии. Таким образом, подход плагинов заключается в разрешении зависимостей и соответствующих версий. Запрашивая  https://deps.dev/ , есть ли уязвимость в системе безопасности версии соответствующего компонента. Другая часть заключается в анализе результатов и отображении результатов. Первоначальная идея заключалась  в том, JPanel чтобы отобразить его насквозь, но оказалось, что это более трудоемко. Позже был сгенерирован файл отчета в формате уценки. Эффект отображения выглядит следующим образом:

# github.com/madneal/gshark  v0.2
## GO-2020-0048
## Overview
Source: OSVID: GO-2020-0048Aliases: CVE-2020-25614## Desciption
[`LoadURL`] does not check the Content-Type of loaded resources,which can cause a panic due to nil pointer deference if the loadedresource is not XML. If user supplied URLs are loaded, this may beused as a denial of service vector.## Impact
Severity: UNKNOWNReferences:

* https://github.com/antchfx/xmlquery/commit/5648b2f39e8d5d3fc903c45a4f1274829df71821 * https://github.com/antchfx/xmlquery/issues/39 * https://go.googlesource.com/vulndb/+/refs/heads/master/reports/GO-2020-0048.yaml * https://storage.googleapis.com/go-vulndb/byID/GO-2020-0048.json

Разработка плагина

Принцип обнаружения SCA в основном описан выше, а более сложной частью разработки плагинов является инженерная часть разработки плагинов. intellij-platform-plugin-template — это шаблон для разработки плагинов. Через подключаемый модуль  README вы можете понять содержание этого подключаемого модуля.Этот шаблон также включает в себя настройку, разработку, модульное тестирование, реформу тестового общего доступа, CI и процессы выпуска. Use this template С помощью этого шаблона вы можете создавать собственные проекты прямо из Github  . Язык разработки по умолчанию для шаблонов — kotlin, также можно выбрать Java. Но нет сомнений, что это хорошая возможность выучить новый язык, так что продолжайте использовать kotlin.

картина

Основная часть реализации подключаемого модуля функции заключается в запуске действия путем определения нового действия. В основном он основан на  PSI API для получения  go.mod файлов для обнаружения SCA.

var modFiles = FilenameIndex.getFilesByName(project, "go.mod", GlobalSearchScope.projectScope(project))

Затем перейдите  directory к созданию файла отчета.

var psiFileFactory = PsiFileFactory.getInstance(project)
val createFileFromText = psiFileFactory.createFileFromText("sca.md", result)
var directory = modFile.containingDirectory
directory.add(createFileFromText)

action Определение находится в  plugin.xml файле, может быть добавлено  action и добавлено в строку меню.

<actions>
<group id="Myplugin.CheckMenu" text="SCA Checker" description="Software component analysis">
<add-to-group group-id="MainMenu" anchor="last"></add-to-group>
<action class="com.github.madneal.secdog.DependencyCheck" id="Myplugin.Checker" text="SCA Check"></action>
</group>
</actions>

В  .run папке можно увидеть следующие задачи:

картина

Run Plugin Он часто используется в задачах разработки.После запуска задачи будет создана среда IDE для запуска, а также ее можно напрямую использовать для отладки. Процесс отладки тоже очень удобен, просто ломая точку. Для определения задачи обратитесь к определению задачи в gradle-intellij-plugin. buildPlugin В  build папке создается соответствующий zip-файл плагина.

Элементы конфигурации в gradle.properties также играют важную роль. Элемент конфигурации по умолчанию в шаблоне —  platformType = IC, для Goland его нужно изменить на  GO. И это   более  pluginSinceBuild важный   элемент конфигурации.pluginUntilBuildRun Verifictions

Кроме того  .github , стоит поговорить и о рабочем процессе. В  template-cleanup.yml , я получаю сообщение об ошибке:

картина

Это задание в основном используется для замены элементов конфигурации по умолчанию в предыдущем шаблоне.На самом деле эта проблема в основном связана с настройками в Действиях на складе.Конфигурация по умолчанию не разрешает права на запись.

картина

После завершения задания имя пакета и имя плагина репозитория будут соответствующим образом изменены. В то же время, если вы хотите публиковать плагины через Github, вам необходимо настроить следующие элементы конфигурации.

картина

На данный момент процесс разработки и выпуска плагинов в основном завершен, а последующий процесс выпуска относительно прост. Шаблоны также предоставляют возможность публиковать и обновлять через Release  CHANGELOG.md .

Плагины можно устанавливать через маркет приложений или zip-файлы в релизах. Использование подключаемого модуля можно запустить, щелкнув  SCA Checker в  строке меню SCA Check , или напрямую  action вызвать для запуска. По установке и использованию плагина можно обратиться к этому обучающему видео.

картина

картина

Подвести итог

Нет никаких сомнений в том, что процесс разработки этого плагина все еще мучителен, и в процессе разработки плагина возникали различные проблемы. Текущий статус плагина все еще очень предварительный, и в будущем будет проводиться дальнейшая оптимизация функций плагина, и даже расширяться объем функций, охватываемых плагином, например, охват вопросов безопасности кода в Голанг.

Использованная литература:

  • https://developerlife.com/2021/03/13/ij-idea-plugin-advanced/#generate-psi-elements-from-text

  • https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html#intellij-platform-based-products-of-recent-ide-versions

  • https://data.services.jetbrains.com/products?code=DG%2CPS%2CDL%2CMPS%2CMPSIIP%2CRDCPPP%2CWS%2CAC%2CIIC%2CIIE%2CGO%2CCL%2CPCD%2CPCC%2CRD%2CPCE%2CIIU% 2CRM%2CPCP&fields=code%2Cname%2Creleases.downloads%2Creleases.version%2Creleases.build%2Creleases.type

  • https://github.com/JetBrains/intellij-платформа-плагин-шаблон

  • https://github.com/JetBrains/gradle-intellij-плагин

  • https://plugins.jetbrains.com/intellij-platform-explorer/extensions