blob: 40ab75836f28f75ee11f677d4d25ecea2a6669e6 [file] [log] [blame]
"""A tool to check consistency of an intellij plugin."""
from pathlib import Path
import argparse
import re
import sys
import xml.etree.ElementTree as ET
import zipfile
from tools.adt.idea.studio import intellij
def check_plugin(plugin_id, files, deps, external_xmls, out):
element = intellij.load_plugin_xml(files, external_xmls)
ids = [id.text for id in element.findall("id")]
if not ids:
# If id is not found, IJ uses name
# https://jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_configuration_file.html
ids = [id.text for id in element.findall("name")]
if len(set(ids)) != 1:
print("Expected exactly one id, but found [%s]" % ",".join(ids))
sys.exit(1)
found_id = ids[0]
if plugin_id and found_id != plugin_id:
print("Expected plugin id to be %s, but found %s" % (plugin_id, found_id))
sys.exit(1)
if element.tag != 'idea-plugin':
print("Expected plugin.xml root item to be 'idea-plugin' but was %s" % element.tag)
sys.exit(1)
if element.attrib.get("allow-bundled-update", "false") != "false" and found_id != "org.jetbrains.kotlin":
print("Bundled plugin update are not allowed for plugin: %s" % found_id)
sys.exit(1)
if deps is not None:
depends_xml = set()
for e in element.findall("depends"):
# We only validate plugin dependencies not module ones
if e.text in [
"com.intellij.modules.java",
"com.intellij.modules.lang",
"com.intellij.modules.platform",
"com.intellij.modules.vcs",
"com.intellij.modules.xdebugger",
"com.intellij.modules.xml",
"com.intellij.modules.androidstudio",
]:
continue
# Ignore optional dependencies, some are against IJ ultimate plugins which we don't have
if e.get("optional") == "true":
continue
depends_xml.add(e.text)
depends_build = set()
for d in deps:
with open(d, "r") as info:
depends_build.add(info.read())
if depends_build != depends_xml:
print("Error while checking plugin dependencies")
for d in depends_build - depends_xml:
print("The build depends on plugin \"%s\", but this dependency is not declared in the plugin.xml." % d)
for d in depends_xml - depends_build:
print("The plugin.xml declares a dependency on \"%s\", but it's not declared in the build." % d)
sys.exit(1)
with open(out, "w") as info:
info.write(found_id)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"--files",
dest="files",
nargs="+",
type=Path,
help="Path to files included in the plugin.")
parser.add_argument(
"--deps",
dest="deps",
default=None,
nargs="*",
help="Ids of the plugins this plugin depends on.")
parser.add_argument(
"--external_xmls",
dest="external_xmls",
default=[],
nargs="*",
help="xmls files that this plugin can include but are not present.")
parser.add_argument(
"--plugin_id",
dest="plugin_id",
help="The expected id of this plugin.")
parser.add_argument(
"--out",
dest="out",
help="Path to a file where to save the plugin information.")
args = parser.parse_args()
check_plugin(args.plugin_id, args.files, args.deps, args.external_xmls, args.out)