Skip to content
This repository was archived by the owner on Jun 2, 2026. It is now read-only.

Commit 24ab317

Browse files
authored
cli: add --max-records (-m) cap for iterator list output (#72)
1 parent 2a12e36 commit 24ab317

2 files changed

Lines changed: 67 additions & 2 deletions

File tree

defectdojo_api_generated/cli/commands/apis.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,12 @@ def _collect_command_values(parameters, getter, *, should_include):
342342

343343

344344
def _render_api_result(result: Any, instance: Any) -> None:
345-
_render_result(result, json_mode=instance.json, jq_expression=instance.jq)
345+
_render_result(
346+
result,
347+
json_mode=instance.json,
348+
jq_expression=instance.jq,
349+
max_records=getattr(instance, 'max_records', None),
350+
)
346351

347352

348353
def _create_standard_command_call(api_class: type, target_method: str, command_parameters):
@@ -515,9 +520,13 @@ def _format_text_item(item: Any) -> str:
515520
return '\n'.join(lines)
516521

517522

518-
def _render_result(result: Any, *, json_mode: bool, jq_expression: Optional[str]):
523+
def _render_result(result: Any, *, json_mode: bool, jq_expression: Optional[str], max_records: Optional[int] = None):
519524
div = False
525+
emitted = 0
520526
for item in _iter_output_items(result):
527+
if max_records is not None and emitted >= max_records:
528+
break
529+
521530
item = _apply_jq(item, jq_expression)
522531

523532
if json_mode:
@@ -529,6 +538,8 @@ def _render_result(result: Any, *, json_mode: bool, jq_expression: Optional[str]
529538
div = True
530539
click.echo(_format_text_item(item))
531540

541+
emitted += 1
542+
532543

533544
def make_api_command(api_class: type, command_name: str, target_method: str, *, parent_class: type):
534545
raw_parameters = list(_iter_command_parameters(api_class, target_method))
@@ -561,6 +572,15 @@ def make_api_command(api_class: type, command_name: str, target_method: str, *,
561572
default_getter=lambda item: item[1].default,
562573
)
563574

575+
if target_method.endswith('_iterator'):
576+
namespace['__annotations__']['max_records'] = Optional[int]
577+
namespace['max_records'] = classyclick.Option(
578+
'-m',
579+
type=click.IntRange(min=1),
580+
default=None,
581+
help='Maximum number of records to emit.',
582+
)
583+
564584
return _build_command_class(parent_class, namespace)
565585

566586

tests/unit/test_cli.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,51 @@ def test_findings_list_accepts_limit_option(self):
8484
self.assertEqual(result.exit_code, 0)
8585
self.assertIn('limit: 1', result.output)
8686

87+
def test_findings_list_accepts_max_records_option(self):
88+
runner = CliRunner()
89+
with runner.isolated_filesystem():
90+
config_path = Path('config.toml')
91+
config_path.write_text("host = 'https://example.com'\ntoken = 'token'\n")
92+
93+
result = runner.invoke(CLI.click, ['--config', str(config_path), 'api', 'findings', 'list', '--help'])
94+
95+
self.assertEqual(result.exit_code, 0)
96+
self.assertIn('--max-records', result.output)
97+
self.assertIn('-m', result.output)
98+
99+
def test_findings_list_max_records_stops_output(self):
100+
runner = CliRunner()
101+
with runner.isolated_filesystem():
102+
config_path = Path('config.toml')
103+
config_path.write_text("host = 'https://example.com'\ntoken = 'token'\n")
104+
105+
with mock.patch.object(
106+
FindingsApi,
107+
'list_iterator',
108+
new=lambda self, **kwargs: [
109+
IteratorResult(result='first', page='page-1'),
110+
IteratorResult(result='second', page='page-2'),
111+
IteratorResult(result='third', page='page-3'),
112+
],
113+
):
114+
result = runner.invoke(
115+
CLI.click,
116+
[
117+
'--config',
118+
str(config_path),
119+
'api',
120+
'findings',
121+
'list',
122+
'--limit',
123+
'1',
124+
'--max-records',
125+
'2',
126+
],
127+
)
128+
129+
self.assertEqual(result.exit_code, 0)
130+
self.assertEqual(result.output.splitlines(), ['first', '', '---', '', 'second'])
131+
87132
def test_findings_list_prints_iterator_items_one_per_line(self):
88133
runner = CliRunner()
89134
with runner.isolated_filesystem():

0 commit comments

Comments
 (0)