IntelliJ 插件验证器
IntelliJ 插件验证器检查基于 IntelliJ 的 IDE 构建和 IntelliJ 平台插件之间的二进制兼容性。
这个工具很有用,因为插件作者通常会指定一个很宽的[since; until] 兼容性范围,但只针对该范围内的特定 IDE 编译插件。
IntelliJ 平台 API 可能会在版本之间偶尔发生变化,因此可能会出现二进制不兼容的情况,导致运行时出现 NoClassDefFoundError
、NoSuchMethodError
和类似的异常。
[!提示] 在大多数情况下,IntelliJ 插件验证器将通过 Gradle IntelliJ 插件的
runPluginVerifier
任务来使用,详见 集成。
插件验证器可以检测到的示例问题:
- 插件引用了 IDE 中不可用的类
com.example.Foo
。如果插件是针对 IDE v1.0 编译的,而类com.example.Foo
在 IDE v2.0 中被移除,就可能发生这种情况。 - 插件引用了 IDE 类中缺失的方法,这会在运行时导致
NoSuchMethodError
。 - Java 规范 | 二进制兼容性 中列出的许多其他二进制不兼容性。
- 缺少插件依赖,例如,当插件
A
依赖于插件B
,但插件B
没有与此 IDE 兼容的构建。这意味着用户无法安装插件A
,因为 IDE 要求安装所有依赖的插件。
目录
安装
从 JetBrains 软件包仓库 或 Maven Central 下载最新可用的 verifier-cli-<version>-all.jar
。
或者,使用 curl
从命令行下载 JAR 归档文件:
curl -L -o verifier-all.jar https://packages.jetbrains.team/maven/p/intellij-plugin-verifier/intellij-plugin-verifier/org/jetbrains/intellij/plugins/verifier-cli/<version>/verifier-cli-<version>-all.jar
<version>
是最新版本,你可以在软件包页面或 GitHub 发布中找到。
你可以使用 GitHub API 获取最新发布信息。
结果的 JSON 响应可以使用 jq
工具解析。
然后,可以将构件 URL 提供给 curl
进行下载。
curl -s https://api.github.com/repos/JetBrains/intellij-plugin-verifier/releases/latest \
| jq -r '.assets[].browser_download_url' \
| xargs curl -L --output verifier-all.jar
选项
插件验证器可以使用命令行运行:
java -jar verifier-all.jar [命令] [选项]
命令是 check-plugin
、check-ide
或 check-trunk-api
之一。
从 1.260 版本开始,插件验证器需要 Java 11。 在此版本之前,需要 Java 8。
结果
所有验证结果都以以下方式打印和保存:
-
结果保存在
<verification-$timestamp>
目录中(可以使用-verification-reports-dir
选项更改)。 此目录下的文件布局如下。单个文件的格式未指定。 基本上,这些文件包含人类可读的句子。<验证报告目录>/ <IDE 版本 #1>/ plugins/ <插件 #1 的 ID/ <插件 #1 的版本>/ <... 报告文件 ...> <插件 #2 的 ID>/ ... <IDE 版本 #2>/ plugins/ ...
文件 描述 存在条件 verification-verdict.txt
人类可读的验证结果。 始终 dependencies.txt
验证期间使用的插件依赖。 插件有效 compatibility-warnings.txt
此插件与 IDE 的兼容性警告。 > 0
compatibility-problems.txt
此插件与 IDE 的兼容性问题。 > 0
deprecated-usages.txt
"使用了已弃用 API" 案例的描述。 > 0
experimental-api-usages.txt
"使用了实验性 API" 案例的描述。 > 0
internal-api-usages.txt
"使用了内部 API" 案例的描述。 > 0
override-only-usages.txt
"错误使用了仅供覆盖的 API" 案例的描述。 > 0
non-extendable-api-usages.txt
"错误使用了不可扩展的 API" 案例的描述。 > 0
plugin-structure-warnings.txt
插件自身问题的描述,与 IDE 兼容性无关。 > 0
invalid-plugin.txt
如果插件无效,则包含无效插件错误的描述。 插件无效 注意! 如果你正在实现与插件验证器的集成,你可以检查相应文件的存在来区分"成功"和"失败"的验证。
-
如果指定了
-teamcity (-tc)
选项,结果将以 TeamCity 测试格式 打印。 要选择展示类型,请指定-tc-grouping (-g)
选项为plugin
(按每个插件分组)或problem_type
(按问题分组)。 -
如果未指定
-teamcity
,结果将打印到控制台。
命令
check-ide
此命令用于针对一组插件检查 IDE 构建。
check-ide
<IDE>
[-runtime-dir | -r <文件>]
[-plugins-to-check-file | -ptcf <文件>]
[-plugins-to-check-all-builds | -p-all < ':' 分隔列表>]
[-plugins-to-check-last-builds | -p-last < ':' 分隔列表>]
[-excluded-plugins-file | -epf <文件> ]
[-team-city | -tc ]
[-tc-grouping | -g ]
[-external-prefixes <':' 分隔列表>]
[-dump-broken-plugin-list | -d]
[-ignored-problems | -ip <文件>]
[-keep-only-problems | -kop <文件>]
<IDE>
可以是本地 IDE 安装路径,也可以是 IDE 模式(见下方 通用选项)
如果没有明确指定插件,则将验证 插件仓库 中所有兼容的插件(选项)。
示例
针对 pluginsToCheck.txt
中列出的所有插件检查 IDEA Ultimate #162.1121.32:
java -jar verifier-all.jar -runtime-dir /home/user/.jdks/corretto-11.0.8 -team-city -tc-grouping problem_type -excluded-plugins-file ignorePlugins.txt -plugins-to-check-file pluginsToCheck.txt -dump-broken-plugin-list actualBroken.txt check-ide /tmp/IU-162.1121.32
针对 Kotlin
和 NodeJs
插件的所有版本以及 PHP
插件的最新版本检查 IDEA Ultimate 162.1121.32:
java -jar verifier-all.jar -runtime-dir /home/user/.jdks/corretto-11.0.8 -plugins-to-check-all-builds org.jetbrains.kotlin:NodeJS -plugins-to-check-last-builds com.jetbrains.php check-ide /tmp/IU-162.1121.32
check-plugin
此命令用于针对一个或多个 IDE 检查一个或多个插件(选项)。
check-plugin
<插件>
<IDE> [<IDE>]*
[-runtime-dir | -r <文件>]
[-team-city | -tc ]
[-tc-grouping | -g ]
[-external-prefixes <':' 分隔列表>]
[-suppress-internal-api-usages no|jetbrains-plugins]
[-mute 逗号分隔的插件问题标识符列表]
<插件>
可以是 <插件路径>
或 '@<文件>'
,文件中包含要验证的插件路径列表,每行一个。
<IDE>
可以是本地 IDE 安装路径,也可以是 IDE 模式(见下方 通用选项)
特定选项
-
-suppress-internal-api-usages
将抑制 JetBrains 插件的内部 API 使用。 JetBrains Marketplace 默认使用此选项。允许的值:
no
:将报告所有内部 API 使用。这是默认值。jetbrains-plugins
:不会报告 JetBrains 插件的内部 API 使用。
-
-mute
将静音(忽略)指定的插件问题。支持的值:
ForbiddenPluginIdPrefix
,TemplateWordInPluginId
,TemplateWordInPluginName
允许使用逗号分隔的插件问题列表,例如:
-mute TemplateWordInPluginId,TemplateWordInPluginName
此开关将静音任何支持的插件问题类型 — 包括与插件描述符相关的插件问题。
通常,上传到 JetBrains Marketplace 的长期存在的插件可能会使用比新插件更宽松的规则进行验证。 此选项用于静音不适用于此类插件的插件问题。
示例
针对 IDEA Ultimate 162.2032.8、163.1024 和 163.7277 检查 Kotlin
插件:
java -jar verifier-all.jar -runtime-dir
验证报告将保存的目录路径。
默认情况下,等于 <当前工作目录>/verification-<时间戳>
。
-
-verification-reports-formats (-vrf)
验证报告的输出格式。 支持的格式有:
plain
(控制台输出)、html
和markdown
默认情况下,启用plain
和html
输出格式。 支持多种输出格式,用逗号分隔。以
-
(破折号)开头的输出格式将被抑制:可以是默认输出格式集或指定的输出格式。示例:
plain,markdown
将启用控制台输出和 Markdown 验证报告。-plain
将禁用控制台输出,但保留默认的 HTML 输出。""
(字面空字符串)将禁用所有验证报告格式。 这实际上会抑制控制台输出,只留下日志消息。
-
-runtime-dir (-r)
包含 Java 运行时 JAR 文件(JDK)的目录路径。 如果未指定,将使用提供的
IDE
参数中的嵌入式 JDK。 如果 IDE 不包含嵌入式 JDK,将使用JAVA_HOME
环境变量来解析 Java 运行时。 -
-external-prefixes (-ex-prefixes)
外部库类的前缀。 插件验证器不会报告这些包的类的"无此类"错误。
-
-plugins-to-check-all-builds (-p-all)
要与 IDE 一起检查的插件 ID。 插件验证器将检查所有兼容的插件构建。
-
-plugins-to-check-last-builds (-p-last)
要与 IDE 一起检查的插件 ID。 插件验证器将只检查最后一个插件构建。
-
-team-city (-tc)
如果要在标准输出上打印兼容 TeamCity 的输出,请指定此标志。
-
-tc-grouping (-g)
对 TeamCity 问题展示进行分组: 可选 'plugin' 按每个插件分组或 'problem_type' 按问题类型分组。
-
-excluded-plugins-file (-epf)
包含排除的插件构建列表的文件。 即使这些更新与 IDE 兼容,验证器也不会验证它们。 包含排除的插件构建列表的文件(例如 '
/lib/resources.jar/brokenPlugins.txt')。 -
-offline
如果插件验证器必须只使用本地下载的插件依赖项,并且必须避免发出 HTTP 请求,请指定此标志。
-
-dump-broken-plugin-list (-d)
用于转储损坏的插件 ID 的文件。 损坏的插件是那些在验证结果中至少包含一个问题的插件。
-
-plugins-to-check-file (-ptcf)
包含要检查的插件列表的文件。 文件的每一行可以是:
plugin_id
(检查插件的所有构建)$plugin_id'
(只检查插件的最后一个构建)
-
-subsystems-to-check (-subsystems)
指定要检查的 IDE 子系统。 可用选项:
all
(默认)、android-only
、without-android
。 -
-ignored-problems (-ip)
包含将在报告中忽略的问题列表的文件。 文件必须包含以下格式的行:
<plugin_xml_id>:<plugin_version>:<problem_description_regexp_pattern>
。plugin_xml_id
和plugin_version
都是可选的。示例:
DevKit:242.19890.14:access to unresolved class org.foo.Foo.*
— 忽略标识符为DevKit
且版本为242.19890.14
的插件中出现的问题。org.jetbrains.kotlin::access to unresolved class org.jetbrains.kotlin.compiler.*
— 忽略 Kotlin 插件所有版本的问题。access to unresolved class org.jetbrains.kotlin.compiler.*
— 忽略所有插件的问题。
-
-keep-only-problems (-kop)
包含将在报告中反映的问题模式的文件。所有其他问题将被忽略。应用于简短的问题描述。 文件必须包含以下形式的行:
<plugin_xml_id_regexp_pattern>:<plugin_version_regexp_pattern>:<problem_description_regexp_pattern>
技术细节
插件验证器使用以下路径进行操作:
<home-directory>
- 所有其他目录的基础目录:- 默认情况下,它是
<USER_HOME>/.pluginVerifier
, - 可以通过
-Dplugin.verifier.home.dir
JVM 参数修改,例如-Dplugin.verifier.home.dir=/tmp/verifier
,
- 默认情况下,它是
<plugins-directory> = <home-directory>/loaded-plugins
- 下载插件的缓存目录,<extracted-directory> = <home-directory>/extracted-plugins
- 用于提取以.zip
归档形式分发的插件的临时目录。
下载插件
要验证的插件和插件的依赖项会被下载到 <plugins-directory>
。
它可以在插件验证器的多次运行之间重复使用:在第一次运行时,所有必要的插件将被下载,而在后续运行中,它们将从缓存中获取。
请注意,不仅会下载要验证的插件,还会下载所有插件的依赖项。
插件从插件仓库下载到 <plugins-directory>/<update-ID>.jar
或 <plugins-directory>/<update-ID>.zip
,具体取决于插件的打包类型。
<update-ID>
是插件版本在插件仓库数据库中的唯一 ID。
例如,Kotlin 1.2.30-release-IJ2018.1-1 的 update-ID
等于 43775
。
限制 <plugins-directory>
的大小
可以限制 <plugins-directory>
的大小,默认为 5 GB。
为此,请指定 JVM 选项 -Dplugin.verifier.cache.dir.max.space=<max-space-MB>
。
当占用空间达到限制时,插件验证器将从缓存中删除最近最少使用的插件。
提取 .zip 格式的插件
在开始验证这些插件之前,以 .zip
归档形式打包的插件会被提取到 <extracted-directory>/<temp-dir>
。
这是为了加速验证过程,因为验证需要进行大量的类文件搜索。
集成
将插件验证器与您的项目集成的最简单方法是使用 Gradle IntelliJ Plugin,它提供了可配置的 runPluginVerifier
任务。
如果您的项目中不使用 Gradle,GitHub Actions Marketplace 中有预定义的第三方操作可用,它们可以自动化插件验证过程。
阅读更多关于可能的集成选项:验证插件兼容性
反馈
请在 YouTrack 上报告问题:https://youtrack.jetbrains.com/issues/MP(MP 代表 Marketplace
)
- 检查是否已存在类似的工单。
- 如果没有,创建一个新问题。
- 输入问题的摘要和描述。
- 选择子系统为插件验证器 - YouTrack 将自动分配负责的开发人员。
- 如果问题是功能请求,您可以选择类型为功能。
感谢您提前报告问题、提供反馈,并使插件验证器变得更好!
Slack
还有一个专门的 Slack 频道可用:#intellij-plugin-verifier。
JetBrains 平台 Slack 社区是一个让您可以与其他插件开发者和 JetBrains 员工讨论插件和扩展开发的地方。