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

Commit fa40393

Browse files
committed
config
1 parent fa23293 commit fa40393

2 files changed

Lines changed: 31 additions & 5 deletions

File tree

defectdojo_api_generated/cli/commands/config.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import json
44
import os
55
import shlex
6+
import shutil
67
import subprocess
78

89
import classyclick
@@ -32,10 +33,14 @@ def _mask_value(key: str, value):
3233

3334
def _resolve_editor() -> str:
3435
editor = os.environ.get('VISUAL') or os.environ.get('EDITOR')
35-
if not editor:
36-
raise click.ClickException('No editor configured. Set VISUAL or EDITOR.')
36+
if editor:
37+
return editor
3738

38-
return editor
39+
for fallback in ('vim', 'vi', 'nano'):
40+
if shutil.which(fallback):
41+
return fallback
42+
43+
raise click.ClickException('No editor configured. Set VISUAL or EDITOR, or install vim, vi, or nano.')
3944

4045

4146
class Config(CLI.Command, classyclick.Command):

tests/unit/test_cli.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ def test_config_command_edit_uses_editor_env(self):
417417
self.assertEqual(result.exit_code, 0)
418418
run_mock.assert_called_once_with(['vim', '-f', str(config_path)], check=True)
419419

420-
def test_config_command_edit_requires_configured_editor(self):
420+
def test_config_command_edit_falls_back_to_first_available_editor(self):
421421
runner = CliRunner()
422422
with runner.isolated_filesystem():
423423
config_path = Path('config.toml')
@@ -426,9 +426,30 @@ def test_config_command_edit_requires_configured_editor(self):
426426
with (
427427
mock.patch('defectdojo_api_generated.cli.commands.cli.DefectDojo') as defectdojo,
428428
mock.patch.dict('os.environ', {}, clear=True),
429+
mock.patch('defectdojo_api_generated.cli.commands.config.shutil.which') as which_mock,
430+
mock.patch('defectdojo_api_generated.cli.commands.config.subprocess.run') as run_mock,
431+
):
432+
defectdojo.return_value = mock.Mock(config=mock.Mock())
433+
which_mock.side_effect = [None, '/usr/bin/vi', '/usr/bin/nano']
434+
result = runner.invoke(CLI.click, ['--config', str(config_path), 'config', '--edit'])
435+
436+
self.assertEqual(result.exit_code, 0)
437+
self.assertEqual(which_mock.call_args_list, [mock.call('vim'), mock.call('vi')])
438+
run_mock.assert_called_once_with(['vi', str(config_path)], check=True)
439+
440+
def test_config_command_edit_requires_configured_or_installed_editor(self):
441+
runner = CliRunner()
442+
with runner.isolated_filesystem():
443+
config_path = Path('config.toml')
444+
config_path.write_text("host = 'https://example.com'\ntoken = 'token'\n")
445+
446+
with (
447+
mock.patch('defectdojo_api_generated.cli.commands.cli.DefectDojo') as defectdojo,
448+
mock.patch.dict('os.environ', {}, clear=True),
449+
mock.patch('defectdojo_api_generated.cli.commands.config.shutil.which', return_value=None),
429450
):
430451
defectdojo.return_value = mock.Mock(config=mock.Mock())
431452
result = runner.invoke(CLI.click, ['--config', str(config_path), 'config', '--edit'])
432453

433454
self.assertEqual(result.exit_code, 1)
434-
self.assertIn('No editor configured. Set VISUAL or EDITOR.', result.output)
455+
self.assertIn('No editor configured. Set VISUAL or EDITOR, or install vim, vi, or nano.', result.output)

0 commit comments

Comments
 (0)