mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-10 14:27:00 -04:00
fix(opencode): Use opencode.jsonc when present (#1590)
## Description Fix OpenCode proxy injection so it respects user configurations that use the `.jsonc` extension, preventing Headroom from creating a duplicate `.json` file that overrides it. Closes #1588 ## Type of Change - [x] Bug fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update - [ ] Performance improvement - [ ] Code refactoring (no functional changes) ## Changes Made - Updated `opencode_config_path` in `paths.py` to check for `.jsonc` - Updated backup creation in `config.py` to preserve the original extension ## Testing <!-- Check what you actually ran, then paste the real command output below. --> - [ ] Unit tests pass (`pytest`) - [ ] Linting passes (`ruff check .`) - [ ] Type checking passes (`mypy headroom`) - [ ] New tests added for new functionality - [x] Manual testing performed ### Test Output ```text N/A ``` ## Real Behavior Proof - Environment: local headroom dev - Exact command / steps: creating a dummy `.config/opencode/opencode.jsonc` and running `headroom wrap opencode`. - Observed result: Headroom successfully injects into `.jsonc` and creates a backup named `opencode.jsonc.headroom-backup`. - Not tested: N/A ## Review Readiness - [x] I have performed a self-review - [x] This PR is ready for human review ## Checklist - [x] My code follows the project's style guidelines - [x] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] I have updated the CHANGELOG.md if applicable ## Screenshots (if applicable) ## Additional Notes
This commit is contained in:
parent
f42ce4a239
commit
4e2bbfee3f
4 changed files with 69 additions and 4 deletions
|
|
@ -125,13 +125,20 @@ def opencode_config_path() -> Path:
|
|||
"""Return the OpenCode config path.
|
||||
|
||||
Resolves ``~/.config/opencode/opencode.json`` when ``OPENCODE_CONFIG``
|
||||
is unset; otherwise the value of that environment variable.
|
||||
is unset; otherwise the value of that environment variable. Checks for
|
||||
``opencode.jsonc`` as well.
|
||||
"""
|
||||
|
||||
env_path = os.environ.get("OPENCODE_CONFIG", "").strip()
|
||||
if env_path:
|
||||
return Path(env_path).expanduser()
|
||||
return Path.home() / ".config" / "opencode" / "opencode.json"
|
||||
base_dir = Path.home() / ".config" / "opencode"
|
||||
jsonc_path = base_dir / "opencode.jsonc"
|
||||
|
||||
if jsonc_path.exists():
|
||||
return jsonc_path
|
||||
|
||||
return base_dir / "opencode.json"
|
||||
|
||||
|
||||
def zcode_config_dir() -> Path:
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ def _opencode_home_dir() -> Path:
|
|||
def opencode_config_paths() -> tuple[Path, Path]:
|
||||
"""Return ``(config_file, backup_file)`` for OpenCode."""
|
||||
config_file = opencode_config_path()
|
||||
backup_file = config_file.with_suffix(".json.headroom-backup")
|
||||
backup_file = config_file.with_name(config_file.name + ".headroom-backup")
|
||||
return config_file, backup_file
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -346,7 +346,7 @@ def test_unwrap_opencode_restores_from_backup(
|
|||
_set_test_home(monkeypatch, tmp_path)
|
||||
|
||||
config_file = tmp_path / ".config" / "opencode" / "opencode.json"
|
||||
backup_file = config_file.with_suffix(".json.headroom-backup")
|
||||
backup_file = config_file.with_name("opencode.json.headroom-backup")
|
||||
config_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
original = '{"model": "openai/gpt-4o"}'
|
||||
config_file.write_text(original)
|
||||
|
|
@ -361,6 +361,31 @@ def test_unwrap_opencode_restores_from_backup(
|
|||
assert config_file.read_text(encoding="utf-8") == original
|
||||
|
||||
|
||||
def test_unwrap_opencode_restores_from_backup_jsonc(
|
||||
runner: CliRunner,
|
||||
tmp_path: Path,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
"""Unwrap restores the pre-wrap backup and removes it for jsonc files."""
|
||||
monkeypatch.chdir(tmp_path)
|
||||
_set_test_home(monkeypatch, tmp_path)
|
||||
|
||||
config_file = tmp_path / ".config" / "opencode" / "opencode.jsonc"
|
||||
backup_file = config_file.with_name("opencode.jsonc.headroom-backup")
|
||||
config_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
original = '{\n // User comment\n "model": "openai/gpt-4o"\n}'
|
||||
config_file.write_text(original)
|
||||
backup_file.write_text(original)
|
||||
|
||||
with patch.object(wrap_mod, "_stop_local_proxy_for_unwrap", return_value="stopped"):
|
||||
result = runner.invoke(main, ["unwrap", "opencode"])
|
||||
|
||||
assert result.exit_code == 0, result.output
|
||||
assert "Restored prior" in result.output
|
||||
assert not backup_file.exists()
|
||||
assert config_file.read_text(encoding="utf-8") == original
|
||||
|
||||
|
||||
def test_unwrap_opencode_strips_blocks_when_no_backup(
|
||||
runner: CliRunner,
|
||||
tmp_path: Path,
|
||||
|
|
|
|||
|
|
@ -49,6 +49,39 @@ def test_opencode_config_paths_from_env(tmp_path: Path, monkeypatch: pytest.Monk
|
|||
assert backup_file == tmp_path / "custom" / "opencode.json.headroom-backup"
|
||||
|
||||
|
||||
def test_opencode_config_paths_default_jsonc(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
"""Default config path resolves to opencode.jsonc when it exists."""
|
||||
_set_test_home(monkeypatch, tmp_path)
|
||||
base_dir = tmp_path / ".config" / "opencode"
|
||||
base_dir.mkdir(parents=True, exist_ok=True)
|
||||
jsonc_path = base_dir / "opencode.jsonc"
|
||||
jsonc_path.write_text("{}")
|
||||
|
||||
config_file, backup_file = opencode_config_paths()
|
||||
assert config_file == jsonc_path
|
||||
assert backup_file == base_dir / "opencode.jsonc.headroom-backup"
|
||||
|
||||
|
||||
def test_opencode_config_paths_env_overrides_jsonc(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
"""OPENCODE_CONFIG takes precedence even if opencode.jsonc exists."""
|
||||
_set_test_home(monkeypatch, tmp_path)
|
||||
base_dir = tmp_path / ".config" / "opencode"
|
||||
base_dir.mkdir(parents=True, exist_ok=True)
|
||||
jsonc_path = base_dir / "opencode.jsonc"
|
||||
jsonc_path.write_text("{}")
|
||||
|
||||
custom_path = tmp_path / "custom" / "opencode.json"
|
||||
monkeypatch.setenv("OPENCODE_CONFIG", str(custom_path))
|
||||
|
||||
config_file, backup_file = opencode_config_paths()
|
||||
assert config_file == custom_path
|
||||
assert backup_file == tmp_path / "custom" / "opencode.json.headroom-backup"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Snapshot
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue