From 146cd10262d89c499746e078ed8a0e06b422af80 Mon Sep 17 00:00:00 2001 From: Matthias Veit Date: Mon, 23 Sep 2024 12:15:29 +0200 Subject: [PATCH] [core][feat] list: allow for listing props with default props (#2200) --- fixcore/fixcore/cli/command.py | 23 +++++++++++++++++++---- fixcore/tests/fixcore/cli/command_test.py | 5 +++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/fixcore/fixcore/cli/command.py b/fixcore/fixcore/cli/command.py index 09e1e22558..c82749f97d 100644 --- a/fixcore/fixcore/cli/command.py +++ b/fixcore/fixcore/cli/command.py @@ -18,7 +18,7 @@ from collections import defaultdict from contextlib import suppress from datetime import timedelta, datetime -from functools import partial, lru_cache +from functools import partial, lru_cache, cached_property from itertools import dropwhile, chain from pathlib import Path from typing import ( @@ -2444,8 +2444,12 @@ class PropToShow: alternative_path: Optional[List[str]] = None override_kind: Optional[str] = None + @cached_property + def path_str(self) -> str: + return ".".join(self.path) + def full_path(self) -> str: - return self.path_access or ".".join(self.path) + return self.path_access or self.path_str def value(self, node: JsonElement) -> Optional[JsonElement]: result = js_value_at(node, self.path) @@ -2502,8 +2506,9 @@ class ListCommand(CLICommand, OutputTransformer): ## Options - `--csv` [optional]: format the output as CSV. Can't be used together with `--markdown`. - - `--markdown` [optional]: format the output as Markdown table. Can't be used together with `--csv`. + - `--json-table` [optional]: format the output as JSON table. + - `--with-defaults` [optional]: show the default properties in addition to the defined ones. ## Examples @@ -2619,6 +2624,7 @@ def args_info(self) -> ArgsInfo: ArgInfo("--csv", help_text="format", option_group="format"), ArgInfo("--markdown", help_text="format", option_group="format"), ArgInfo("--json-table", help_text="format", option_group="format"), + ArgInfo("--with-defaults"), ArgInfo( expects_value=True, help_text="comma separated list of properties to show", @@ -2632,6 +2638,7 @@ def parse(self, arg: Optional[str] = None, ctx: CLIContext = EmptyContext, **kwa output_type.add_argument("--csv", dest="csv", action="store_true") output_type.add_argument("--markdown", dest="markdown", action="store_true") output_type.add_argument("--json-table", dest="json_table", action="store_true") + parser.add_argument("--with-defaults", dest="with_defaults", action="store_true") parsed, properties_list = parser.parse_known_args(arg.split() if arg else []) properties = " ".join(properties_list) if properties_list else None is_aggregate: bool = ctx.query is not None and ctx.query.aggregate is not None @@ -2766,7 +2773,15 @@ def unique_name(path: List[str], current: str) -> str: def props_to_show( props_setting: Tuple[List[PropToShow], List[PropToShow], List[PropToShow], List[PropToShow]] ) -> List[PropToShow]: - props = parse_props_to_show(properties) if properties is not None else default_props_to_show(props_setting) + if properties: + props = parse_props_to_show(properties) + if parsed.with_defaults: + paths = {prop.path_str for prop in props} + for prop in default_props_to_show(props_setting): + if prop.path_str not in paths: + props.append(prop) + else: + props = default_props_to_show(props_setting) return create_unique_names(props) def fmt_json(elem: Json) -> JsonElement: diff --git a/fixcore/tests/fixcore/cli/command_test.py b/fixcore/tests/fixcore/cli/command_test.py index 1c739ce4ac..17cf54494a 100644 --- a/fixcore/tests/fixcore/cli/command_test.py +++ b/fixcore/tests/fixcore/cli/command_test.py @@ -2,6 +2,7 @@ import json import logging import os +import re import sqlite3 from datetime import timedelta from functools import partial @@ -680,6 +681,10 @@ async def test_list_command(cli: CLI) -> None: "Region / Zone", ] + # define properties and add default properties + result = await cli.execute_cli_command("search is (foo) and id=0 | list --with-defaults kind as k, id", list_sink) + assert re.fullmatch("k=foo, id=0, age=.+, cloud=collector, account=sub_root", result[0][0]) + @pytest.mark.asyncio async def test_jq_command(cli: CLI) -> None: