55import os
66import sys
77import tempfile
8+ from dataclasses import dataclass
9+ from enum import Enum , auto
810from importlib .metadata import PackageNotFoundError , version
911from pathlib import Path
1012from types import ModuleType
@@ -32,6 +34,17 @@ class PluginError(Exception):
3234 pass
3335
3436
37+ class ParamStrategy (Enum ):
38+ POSITIONAL = auto ()
39+ NAMED = auto ()
40+
41+
42+ @dataclass
43+ class Params :
44+ params : list | dict
45+ type : ParamStrategy
46+
47+
3548hook_registry : set [Callable [..., Any ]] = set ()
3649imported_modules : dict [str , ModuleType ] = {}
3750
@@ -103,24 +116,40 @@ def toggle(plugin: str):
103116@plugin .command ()
104117@click .argument ("plugin_name" , type = str , default = "" )
105118@click .argument ("function_name" , type = str , default = "" )
106- @click .option ("--params" , type = str , default = "" )
107- @click .option ("--json-input" , type = str , default = "" )
108- def run (plugin_name : str , function_name : str , params : str , json_input : str ):
109- """Explore and run plugins"""
119+ @click .option (
120+ "--params" , type = str , default = "" , help = "Paramter data to be fed to the plugin function"
121+ )
122+ def run (plugin_name : str , function_name : str , params : str ):
123+ """Explore and run plugins
124+
125+ Use `--params` to pass a JSON list for positional arguments or a JSON object for named arguments.
126+
127+ Like this:
128+
129+ Positional - '["first element", 2, 3.0]'
130+
131+ Named - '{"first": "first_element", "second": 2, "third": 3.0}'
132+ """
110133 show_explainer = False
111134
112135 plugin_dir = _get_plugin_directory ()
113136 if plugin_dir is None :
114137 direct_user_to_plugin_directory_and_exit ()
115138
116139 plugins = get_plugins_with_status (plugin_dir )
140+ plugin_was_found = False
117141 for plugin_path , status in plugins :
142+ if plugin_path .stem == plugin_name :
143+ plugin_was_found = True
118144 if plugin_path .stem == plugin_name and not status :
119145 click .secho (f"The plugin '{ plugin_path .stem } ' is not enabled" , fg = "yellow" )
120146 click .secho ("Please toggle it on to use it." )
121147 sys .exit (0 )
148+ if plugin_name and not plugin_was_found :
149+ click .secho (f"The plugin '{ plugin_name } ' was not found." , fg = "yellow" )
150+ sys .exit (0 )
122151
123- if plugin_name == "" and sys . stdin . isatty () :
152+ if plugin_name == "" :
124153 show_explainer = True
125154 plugin_names = [
126155 plugin_name .stem for plugin_name , status in get_plugins_with_status () if status
@@ -132,7 +161,7 @@ def run(plugin_name: str, function_name: str, params: str, json_input: str):
132161 sys .exit (0 )
133162 plugin_name = plugin_answer .get ("plugin" )
134163
135- if function_name == "" and sys . stdin . isatty () :
164+ if function_name == "" :
136165 show_explainer = True
137166 module = imported_modules .get (f"plugins.{ plugin_name } " )
138167 funcs = [
@@ -152,20 +181,7 @@ def run(plugin_name: str, function_name: str, params: str, json_input: str):
152181 if not func :
153182 sys .exit (0 )
154183
155- if params :
156- print (params )
157- params = json .loads (params )
158- try :
159- return_value = func (* params )
160- if return_value is not None :
161- jsonified = json .dumps (return_value )
162- print (f"'{ jsonified } '" )
163- sys .exit (0 )
164- except Exception as e :
165- click .secho (f"Exception: { e } " , fg = "yellow" )
166- sys .exit (1 )
167-
168- if not json_input and not params :
184+ if not params :
169185 params = {}
170186 sig = inspect .signature (func )
171187 for name , param in sig .parameters .items ():
@@ -207,18 +223,35 @@ def run(plugin_name: str, function_name: str, params: str, json_input: str):
207223 f"\n warnet plugin run { plugin_name } { function_name } --json-input '{ json .dumps (params )} '" ,
208224 fg = "green" ,
209225 )
210-
211226 else :
212- params = json .loads (json_input )
227+ params = json .loads (params )
213228
214- try :
215- return_value = func (** params )
216- if return_value is not None :
217- jsonified = json .dumps (return_value )
218- print (f"'{ jsonified } '" )
219- except Exception as e :
220- click .secho (f"Exception: { e } " , fg = "yellow" )
221- sys .exit (1 )
229+ execute_function_with_params (func , params )
230+
231+
232+ def execute_function_with_params (func : Callable [..., Any ], params : dict | list ):
233+ match params :
234+ case dict ():
235+ try :
236+ return_value = func (** params )
237+ if return_value is not None :
238+ jsonified = json .dumps (return_value )
239+ print (f"'{ jsonified } '" )
240+ except Exception as e :
241+ click .secho (f"Exception: { e } " , fg = "yellow" )
242+ sys .exit (1 )
243+ case list ():
244+ try :
245+ return_value = func (* params )
246+ if return_value is not None :
247+ jsonified = json .dumps (return_value )
248+ print (f"'{ jsonified } '" )
249+ except Exception as e :
250+ click .secho (f"Exception: { e } " , fg = "yellow" )
251+ sys .exit (1 )
252+ case _:
253+ click .secho (f"Did not anticipate this type: { params } --> { type (params )} " )
254+ sys .exit (1 )
222255
223256
224257def process_obj (some_obj , func ) -> dict :
0 commit comments