Merge pull request #3 from oib/codex/analyze-codebase-and-suggest-improvements-exvc22

cli/docs/tests: harden config edit invocation and add YAML empty-export coverage
This commit is contained in:
Andreas Michael Fleckl
2026-02-17 16:25:07 +01:00
committed by GitHub
3 changed files with 28 additions and 8 deletions

View File

@@ -2,6 +2,8 @@
import click import click
import os import os
import shlex
import subprocess
import yaml import yaml
import json import json
from pathlib import Path from pathlib import Path
@@ -128,8 +130,9 @@ def edit(ctx, global_config: bool):
yaml.dump(config_data, f, default_flow_style=False) yaml.dump(config_data, f, default_flow_style=False)
# Open in editor # Open in editor
editor = os.getenv('EDITOR', 'nano') editor = os.getenv('EDITOR', 'nano').strip() or 'nano'
os.system(f"{editor} {config_file}") editor_cmd = shlex.split(editor)
subprocess.run([*editor_cmd, str(config_file)], check=False)
@config.command() @config.command()

View File

@@ -153,7 +153,7 @@ Choose a tutorial based on your interest:
### Community ### Community
- [Discord](https://discord.gg/aitbc) - [Discord](https://discord.gg/aitbc)
- [GitHub Discussions](https://github.com/aitbc/discussions) - [GitHub Discussions](https://github.com/oib/AITBC/discussions)
- [Stack Overflow](https://stackoverflow.com/questions/tagged/aitbc) - [Stack Overflow](https://stackoverflow.com/questions/tagged/aitbc)
## Development Workflow ## Development Workflow

View File

@@ -145,8 +145,8 @@ class TestConfigCommands:
assert result.exit_code == 0 assert result.exit_code == 0
assert '.config/aitbc/config.yaml' in result.output assert '.config/aitbc/config.yaml' in result.output
@patch('os.system') @patch('aitbc_cli.commands.config.subprocess.run')
def test_edit_command(self, mock_system, runner, mock_config, tmp_path): def test_edit_command(self, mock_run, runner, mock_config, tmp_path):
"""Test editing configuration file""" """Test editing configuration file"""
# Change to the tmp_path directory # Change to the tmp_path directory
@@ -160,9 +160,10 @@ class TestConfigCommands:
assert result.exit_code == 0 assert result.exit_code == 0
# Verify editor was called # Verify editor was called
mock_system.assert_called_once() mock_run.assert_called_once()
assert 'nano' in mock_system.call_args[0][0] args = mock_run.call_args[0][0]
assert str(actual_config_file) in mock_system.call_args[0][0] assert args[0] == 'nano'
assert str(actual_config_file) in args
def test_reset_config_cancelled(self, runner, mock_config, temp_config_file): def test_reset_config_cancelled(self, runner, mock_config, temp_config_file):
"""Test config reset cancelled by user""" """Test config reset cancelled by user"""
@@ -267,6 +268,22 @@ class TestConfigCommands:
data = json.loads(result.output) data = json.loads(result.output)
assert data == {} assert data == {}
def test_export_empty_yaml_yaml_format(self, runner, mock_config, tmp_path):
"""Test exporting an empty YAML config file as YAML"""
with runner.isolated_filesystem(temp_dir=tmp_path):
local_config = Path.cwd() / ".aitbc.yaml"
local_config.write_text("")
result = runner.invoke(config, [
'export',
'--format', 'yaml'
], obj={'config': mock_config, 'output_format': 'table'})
assert result.exit_code == 0
data = yaml.safe_load(result.output)
assert data == {}
def test_export_no_config(self, runner, mock_config): def test_export_no_config(self, runner, mock_config):
"""Test export when no config file exists""" """Test export when no config file exists"""
with runner.isolated_filesystem(): with runner.isolated_filesystem():