first sorry for my bad terminology, I am an electrical engineer, so maybe my coding terms are not so accurate or even far from that.
we have a CLI in the company, accessed from the Linux terminal, you know usual stuff, `{command.exe} {plugin} {options}, and you get the output on the terminal screen.
In order to unit test the product, we need it in a python class, which is returned as an object to the test environment, and eventually, prints that open a process that execute that command.
to build the command, we have a dictionary of the plugin, the subplugin, and the option for each cmd:
self.commands = {
"plugin": ['subplugin', 'subsubplugin', '-a', 'flaga', '-b', 'flagb'],...
and we built a function for every command we want, from the plugin
list extracted from the dict above
I am looking for a better approach that auto-built the tool entirely, sort of what the OS does for prediction.
I am assuming that would include the "set_attr" method of classes and stuff like that.
at the end of all this, I expect to access the plugin like this: cli.plugin.subplugin.subsubplugin(arg,arg,arg)
and that would generate a command cli, or at least the list above so I could inject it into the existing infra.
can anyone help, please?
thx in advance
I am more looking for guidence then say what I tried and fix it.
I found my answer, this code worked for me yo achieve what I was looking for. thanks for the commenters.
import re
import subprocess
PKG_NAME = "sudo mycli"
PKG_PLUGIN_START = "The following are all installed plugin extensions:" # this is the message before the commands list in the cli help
PKG_PLUGIN_END = f"See 'mycli <plugin> help' for more information on a plugin" # hit is the message after the commands list in the cli help
PKG_CMD_START = "The following are all implemented sub-commands:"
PKG_CMD_END = "See 'mycli help <command>' for more information on a specific command"
PLUGIN_CMD_START = PKG_CMD_START
PLUGIN_CMD_END = "See 'mycli <plugin> help <command>' for more information on a specific command"
def get_help(s):
s += " help"
return subprocess.getoutput([s])
def get_plugin_list(s, start, end):
s = '\n'.join(l.strip() for l in s.splitlines() if l)
res = re.search(f'{start}([\s\S]*){end}', s) # regex that matches everything between both strings
if not res:
raise ValueError("Couldn't find plugin list in string")
return [l.split(' ')[0] for l in res.group(1).strip().splitlines()] # remove the unnecessary text and return the plugins as a list
class CMD():
def __init__(self, name, parent_plugin_name=None, *args):
self.args = args
self.pkg_name = PKG_NAME
self.parent_plugin_name = parent_plugin_name
self.name = name
def __call__(self, *args, **kwargs):
if self.parent_plugin_name:
command = " ".join([self.pkg_name, self.parent_plugin_name])
else:
command = self.pkg_name
command = " ".join([command, self.name, *args, " "])
command += " ".join([f"-{each[0]}={each[1]}" for each in list(kwargs.items())])
return subprocess.getoutput(command)
class Plugin():
def __init__(self, name, parent_pkg_name):
self.name = name
self.parent_pkg_name = PKG_NAME
plugin_cmd_start = PLUGIN_CMD_START
plugin_cmd_end = PLUGIN_CMD_END.replace("<plugin>", self.name)
for cmd in get_plugin_list(get_help(f"{self.parent_pkg_name} {self.name}"), plugin_cmd_start, plugin_cmd_end):
setattr(self, cmd, CMD(cmd, parent_plugin_name=self.name))
class Package():
def __init__(self, name, root=True):
self.name = name
if root:
self.name = "sudo " + self.name
self.command_string = f"{self.name}"
for cmd in get_plugin_list(get_help(self.name), PKG_CMD_START, PKG_CMD_END):
setattr(self, cmd, CMD(cmd))
for plugin in get_plugin_list(get_help(self.name), PKG_PLUGIN_START, PKG_PLUGIN_END):
setattr(self, plugin, Plugin(plugin, parent_pkg_name=self.name))
if __name__ == "__main__":
mycli_tool = Package("mycli")
print()
print(mycli_tool.cmd())
print()
print(mycli_tool.system.get_disk_usage("-x0"))
print()
print(mycli_tool.system.get_disk_usage(x=0))
print()
print(mycli_tool.system.get_disk_usage(json=1))