diff options
Diffstat (limited to 'python/knot_resolver/client/commands/config.py')
-rw-r--r-- | python/knot_resolver/client/commands/config.py | 110 |
1 files changed, 43 insertions, 67 deletions
diff --git a/python/knot_resolver/client/commands/config.py b/python/knot_resolver/client/commands/config.py index 52df39c4..d13d24d9 100644 --- a/python/knot_resolver/client/commands/config.py +++ b/python/knot_resolver/client/commands/config.py @@ -3,7 +3,8 @@ import sys from enum import Enum from typing import List, Literal, Optional, Tuple, Type -from knot_resolver.client.command import Command, CommandArgs, CompWords, register_command +from knot_resolver.client.command import COMP_NOSPACE, Command, CommandArgs, CompWords, comp_get_words, register_command +from knot_resolver.datamodel import KresConfig from knot_resolver.utils.modeling.parsing import DataFormat, parse_json, try_to_parse from knot_resolver.utils.requests import request @@ -22,56 +23,6 @@ def operation_to_method(operation: Operations) -> Literal["PUT", "GET", "DELETE" return "GET" -# def _properties_words(props: Dict[str, Any]) -> CompWords: -# words: CompWords = {} -# for name, prop in props.items(): -# words[name] = prop["description"] if "description" in prop else None -# return words - - -# def _path_comp_words(node: str, nodes: List[str], props: Dict[str, Any]) -> CompWords: -# i = nodes.index(node) -# ln = len(nodes[i:]) - -# # if node is last in path, return all possible words on thi level -# if ln == 1: -# return _properties_words(props) -# # if node is valid -# elif node in props: -# node_schema = props[node] - -# if "anyOf" in node_schema: -# for item in node_schema["anyOf"]: -# print(item) - -# elif "type" not in node_schema: -# pass - -# elif node_schema["type"] == "array": -# if ln > 2: -# # skip index for item in array -# return _path_comp_words(nodes[i + 2], nodes, node_schema["items"]["properties"]) -# if "enum" in node_schema["items"]: -# print(node_schema["items"]["enum"]) -# return {"0": "first array item", "-": "last array item"} -# elif node_schema["type"] == "object": -# if "additionalProperties" in node_schema: -# print(node_schema) -# return _path_comp_words(nodes[i + 1], nodes, node_schema["properties"]) -# return {} - -# # arrays/lists must be handled sparately -# if node_schema["type"] == "array": -# if ln > 2: -# # skip index for item in array -# return _path_comp_words(nodes[i + 2], nodes, node_schema["items"]["properties"]) -# return {"0": "first array item", "-": "last array item"} -# return _path_comp_words(nodes[i + 1], nodes, node_schema["properties"]) -# else: -# # if node is not last or valid, value error -# raise ValueError(f"unknown config path node: {node}") - - @register_command class ConfigCommand(Command): def __init__(self, namespace: argparse.Namespace) -> None: @@ -141,7 +92,7 @@ class ConfigCommand(Command): value_or_file = set_op.add_mutually_exclusive_group() value_or_file.add_argument( "file", - help="Optional, path to file with new configuraion.", + help="Optional, path to file with new configuration.", type=str, nargs="?", ) @@ -165,25 +116,50 @@ class ConfigCommand(Command): type=str, default="", ) - return config, ConfigCommand @staticmethod def completion(args: List[str], parser: argparse.ArgumentParser) -> CompWords: - # words = parser_words(parser._actions) # pylint: disable=W0212 - - # for arg in args: - # if arg in words: - # continue - # elif arg.startswith("-"): - # return words - # elif arg == args[-1]: - # config_path = arg[1:].split("/") if arg.startswith("/") else arg.split("/") - # schema_props: Dict[str, Any] = KresConfig.json_schema()["properties"] - # return _path_comp_words(config_path[0], config_path, schema_props) - # else: - # break - return {} + nargs = len(args) + + if nargs > 1 and args[-2] in ["-p", "--path"]: + words: CompWords = {} + words[COMP_NOSPACE] = None + + path = args[-1] + path_nodes = path.split("/") + + prefix = "" + properties = KresConfig.json_schema()["properties"] + is_list = False + for i, node in enumerate(path_nodes): + # first node is empty string + if i == 0: + continue + + if node in properties: + is_list = False + if "properties" in properties[node]: + properties = properties[node]["properties"] + prefix += f"/{node}" + continue + if "items" in properties[node]: + properties = properties[node]["items"]["properties"] + prefix += f"/{node}" + is_list = True + continue + del words[COMP_NOSPACE] + break + if is_list and node.isnumeric(): + prefix += f"/{node}" + continue + + for key in properties.keys(): + words[f"{prefix}/{key}"] = properties[key]["description"] + + return words + + return comp_get_words(args, parser) def run(self, args: CommandArgs) -> None: if not self.operation: |