88from zipfile import ZipFile
99
1010from dataclasses import dataclass
11+ from packaging .version import Version
1112
1213from hookman import hookman_utils
1314from hookman .exceptions import InvalidDestinationPathError
1819@dataclass (frozen = True )
1920class InstalledPluginInfo :
2021 """
21- Responsible to stores the information about the installed plugin.
22+ Responsible to store the information about an installed plugin.
2223 """
2324 id : str
24- version : str
25+ version : Version
2526
2627class HookSpecs :
2728 """
@@ -107,7 +108,7 @@ def install_plugin(self, plugin_file_path: Path, dest_path: Path) -> InstalledPl
107108
108109 1. The destination Path should be one of the paths informed during the initialization of HookMan (plugins_dirs field).
109110
110- 2. The plugins_dirs cannot have two plugins with the same name.
111+ 2. The plugins_dirs cannot have two plugins with the same name and version .
111112
112113 :param: plugin_file_path:
113114 The Path for the ``.hmplugin``
@@ -127,8 +128,9 @@ def install_plugin(self, plugin_file_path: Path, dest_path: Path) -> InstalledPl
127128
128129 yaml_content = plugin_file_zip .open ("assets/plugin.yaml" ).read ().decode ("utf-8" )
129130
130- plugin_id : str = PluginInfo ._load_yaml_file (yaml_content )["id" ]
131- plugin_version : str = PluginInfo ._load_yaml_file (yaml_content )["version" ]
131+ yaml_data = PluginInfo ._load_yaml_file (yaml_content )
132+ plugin_id : str = yaml_data ["id" ]
133+ plugin_version : str = yaml_data ["version" ]
132134 plugin_id_version = f"{ plugin_id } -{ plugin_version } "
133135
134136 plugins_dirs = [x for x in dest_path .iterdir () if x .is_dir ()]
@@ -139,7 +141,7 @@ def install_plugin(self, plugin_file_path: Path, dest_path: Path) -> InstalledPl
139141 plugin_destination_folder = dest_path / plugin_id_version
140142 plugin_destination_folder .mkdir (parents = True )
141143 plugin_file_zip .extractall (plugin_destination_folder )
142- return InstalledPluginInfo (version = plugin_version , id = plugin_id )
144+ return InstalledPluginInfo (version = Version ( plugin_version ) , id = plugin_id )
143145
144146 def _move_to_trash (self , root_dir , name ):
145147 """
@@ -172,20 +174,29 @@ def _try_clear_trash(self, root_dir):
172174 with suppress (OSError ):
173175 filename .unlink ()
174176
175- def remove_plugin (self , caption : str , version : str ) -> None :
177+ def remove_plugin (self , caption : str , version : Version | None = None ) -> None :
176178 """
177- This method receives the name of the plugin as input, and will remove completely the plugin from ``plugin_dirs``.
179+ This method receives the name and version of plugin as input, and will remove completely the
180+ plugin from ``plugin_dirs``.
178181
179182 :param caption:
180183 Name of the plugin to be removed.
181184
182185 :param version:
183- Version of the plugin to be removed.
186+ Optional parameter used to remove a specific version of plugin. Case it is not specified,
187+ all versions of a given plugin will be removed.
184188 """
185189 for plugin in self .get_plugins_available ():
186- if plugin .id == caption and plugin .version == version :
187- plugin_dir = plugin .yaml_location .parents [1 ]
188- root_dir = plugin_dir .parent
190+ plugin_dir = plugin .yaml_location .parents [1 ]
191+ root_dir = plugin_dir .parent
192+ remove_plugin = False
193+
194+ if version is None and caption in plugin_dir .name :
195+ remove_plugin = True
196+ elif plugin .id == caption and version == plugin .version :
197+ remove_plugin = True
198+
199+ if remove_plugin :
189200 self ._move_to_trash (root_dir , plugin_dir .name )
190201 self ._try_clear_trash (root_dir )
191202 break
0 commit comments