# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-## Copyright 2021,2024 Canonical Ltd.## This program is free software; you can redistribute it and/or# modify it under the terms of the GNU Lesser General Public# License version 3 as published by the Free Software Foundation.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU# Lesser General Public License for more details.## You should have received a copy of the GNU Lesser General Public License# along with this program. If not, see <http://www.gnu.org/licenses/>."""Definitions and helpers to handle plugins."""importcopyfromtypingimportTYPE_CHECKING,Anyfrom.ant_pluginimportAntPluginfrom.autotools_pluginimportAutotoolsPluginfrom.baseimportPluginfrom.cmake_pluginimportCMakePluginfrom.dotnet_pluginimportDotnetPluginfrom.dump_pluginimportDumpPluginfrom.go_pluginimportGoPluginfrom.go_use_pluginimportGoUsePluginfrom.make_pluginimportMakePluginfrom.maven_pluginimportMavenPluginfrom.meson_pluginimportMesonPluginfrom.nil_pluginimportNilPluginfrom.npm_pluginimportNpmPluginfrom.poetry_pluginimportPoetryPluginfrom.propertiesimportPluginPropertiesfrom.python_pluginimportPythonPluginfrom.qmake_pluginimportQmakePluginfrom.rust_pluginimportRustPluginfrom.scons_pluginimportSConsPluginfrom.uv_pluginimportUvPluginifTYPE_CHECKING:# import module to avoid circular imports in sphinx doc generationfromcraft_partsimportinfos,partsPluginType=type[Plugin]# Plugin registry by plugin API version_BUILTIN_PLUGINS:dict[str,PluginType]={"ant":AntPlugin,"autotools":AutotoolsPlugin,"cmake":CMakePlugin,"dotnet":DotnetPlugin,"dump":DumpPlugin,"go":GoPlugin,"go-use":GoUsePlugin,"make":MakePlugin,"maven":MavenPlugin,"meson":MesonPlugin,"nil":NilPlugin,"npm":NpmPlugin,"poetry":PoetryPlugin,"python":PythonPlugin,"qmake":QmakePlugin,"rust":RustPlugin,"scons":SConsPlugin,"uv":UvPlugin,}_PLUGINS=copy.deepcopy(_BUILTIN_PLUGINS)
[docs]defget_plugin(*,part:"parts.Part",part_info:"infos.PartInfo",properties:PluginProperties,)->Plugin:"""Obtain a plugin instance for the specified part. :param part: The part requesting the plugin. :param part_info: The part information data. :param properties: The plugin properties. :return: The plugin instance. """plugin_name=part.plugin_nameifpart.plugin_nameelsepart.nameplugin_class=get_plugin_class(plugin_name)returnplugin_class(properties=properties,part_info=part_info)
[docs]defget_plugin_class(name:str)->PluginType:"""Obtain a plugin class given the name. :param name: The plugin name. :return: The plugin class. :raise ValueError: If the plugin name is invalid. """ifnamenotin_PLUGINS:raiseValueError(f"plugin not registered: {name!r}")return_PLUGINS[name]
[docs]defget_registered_plugins()->dict[str,PluginType]:"""Return the list of currently registered plugins."""returncopy.deepcopy(_PLUGINS)
[docs]defregister(plugins:dict[str,PluginType])->None:"""Register part handler plugins. :param plugins: a dictionary where the keys are plugin names and values are plugin classes. Valid plugins must subclass class:`Plugin`. """_PLUGINS.update(plugins)
[docs]defunregister(*plugins:str)->None:"""Unregister plugins by name."""forplugininplugins:_PLUGINS.pop(plugin,None)
[docs]defunregister_all()->None:"""Unregister all user-registered plugins."""global_PLUGINS# noqa: PLW0603_PLUGINS=copy.deepcopy(_BUILTIN_PLUGINS)
[docs]defextract_part_properties(data:dict[str,Any],*,plugin_name:str)->dict[str,Any]:"""Get common part properties without plugin-specific entries. :param data: A dictionary containing all part properties. :param plugin_name: The name of the plugin. :return: A dictionary containing only common part properties. """prefix=f"{plugin_name}-"return{k:vfork,vindata.items()ifnotk.startswith(prefix)}