From 01395238f55b2f300e5f46888c176f14f78baa70 Mon Sep 17 00:00:00 2001 From: Denys Fedoryshchenko Date: Mon, 18 Sep 2023 13:30:50 +0300 Subject: [PATCH] base_api.py: Implement operators and document them in cli help Right now for operators we are using "magic" suffix such as __gt, __lt and so on, which is not documented and a bit non-intuitive. We can make cli tool more intuitive with this patch, where it will hide from user this magic, until we find better mechanism to handle operators as mentioned in https://github.com/kernelci/kernelci-api/issues/356 Also raise error if attribute name is used twice, as first one will be overwritten and ignored due current implementation. Signed-off-by: Denys Fedoryshchenko --- kernelci/cli/base_api.py | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/kernelci/cli/base_api.py b/kernelci/cli/base_api.py index 8a066b6dd2..d48eea34a5 100644 --- a/kernelci/cli/base_api.py +++ b/kernelci/cli/base_api.py @@ -12,6 +12,7 @@ import abc import json +import re import kernelci.api from .base import Command, Args, catch_http_error @@ -63,12 +64,41 @@ class AttributesCommand(APICommand): { 'name': 'attributes', 'nargs': '*', - 'help': "Attributes in name=value format", + 'help': "Attributes in 'name=value' format, where = is " + "OPERATOR and can be one of: >, <, >=, <=, =", }, ] @classmethod def _split_attributes(cls, attributes): - return dict( - tuple(attr.split('=')) for attr in attributes - ) if attributes else {} + """ Split attributes into a dictionary. + + At moment we use small hack, if operator matches one of: >, <, >=, <= + then we append to attribute '__gt', '__lt', '__gte', '__lte' suffix + accordingly to API documentation. + """ + ret = {} + if not attributes: + return ret + for attribute in attributes: + pattern = r'^([\S]+)([!=<>]+)([\S]+)$' + match = re.match(pattern, attribute) + if match: + attribute, operator, value = match.groups() + switch = { + '>': '__gt', + '<': '__lt', + '>=': '__gte', + '<=': '__lte', + } + if operator in switch: + attribute += switch[operator] + elif operator != '=': + raise ValueError(f"Invalid operator {operator}") + if attribute in ret: + raise ValueError(f"Attribute {attribute} already exists") + ret[attribute] = value + else: + raise ValueError(f"Invalid attribute {attribute}") + + return ret