在python中自动将cli工具内置到对象中

rnmwe5a2  于 2022-12-05  发布在  Python
关注(0)|答案(1)|浏览(104)

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.

oxf4rvwz

oxf4rvwz1#

我找到了我的答案,这个代码对我很有效,你实现了我想要的。谢谢评论者。

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))

相关问题