diff --git a/packages/specfact-code-review/module-package.yaml b/packages/specfact-code-review/module-package.yaml index 2f5114f..2c4d484 100644 --- a/packages/specfact-code-review/module-package.yaml +++ b/packages/specfact-code-review/module-package.yaml @@ -1,5 +1,5 @@ name: nold-ai/specfact-code-review -version: 0.47.14 +version: 0.47.15 commands: - code tier: official @@ -23,5 +23,5 @@ description: Official SpecFact code review bundle package. category: codebase bundle_group_command: code integrity: - checksum: sha256:9feec110298126ea77f58789dc4c7ba61ff9bfdcaee91b580afd57b9178903ae - signature: kIHPg05QU/PSTuGYnn1a2JtXooCCWx1gGZ4bmjoJqOjRQpso/tD2xaApAjYOwCEpXXpRceaBMa+PC3DrniKrCA== + checksum: sha256:f9b3b54bcbf8f481607bbfe7bf02fb77625953d19ccce8b11d74e44580608e8c + signature: w5tEmlYK7MGBFVD19g7b7D3pob27CgP2dF12J3fxbr268LskXZZ1rNvwhK/7FRYYjGci8pIJAfg8ZtRCeWTfBg== diff --git a/packages/specfact-code-review/src/specfact_code_review/tools/semgrep_runner.py b/packages/specfact-code-review/src/specfact_code_review/tools/semgrep_runner.py index 67fdb70..5fee2b5 100644 --- a/packages/specfact-code-review/src/specfact_code_review/tools/semgrep_runner.py +++ b/packages/specfact-code-review/src/specfact_code_review/tools/semgrep_runner.py @@ -169,11 +169,15 @@ def _run_semgrep_command( with tempfile.TemporaryDirectory(prefix="semgrep-home-") as temp_home: semgrep_home = Path(temp_home) semgrep_log_dir = semgrep_home / ".semgrep" + semgrep_config_dir = semgrep_home / ".config" + semgrep_cache_dir = semgrep_home / ".cache" semgrep_log_dir.mkdir(parents=True, exist_ok=True) + semgrep_config_dir.mkdir(parents=True, exist_ok=True) + semgrep_cache_dir.mkdir(parents=True, exist_ok=True) env = os.environ.copy() env["HOME"] = str(semgrep_home) - env["XDG_CONFIG_HOME"] = str(semgrep_home / ".config") - env["XDG_CACHE_HOME"] = str(semgrep_home / ".cache") + env["XDG_CONFIG_HOME"] = str(semgrep_config_dir) + env["XDG_CACHE_HOME"] = str(semgrep_cache_dir) env["SEMGREP_SETTINGS_FILE"] = str(semgrep_log_dir / "settings.yml") env.setdefault("SEMGREP_SEND_METRICS", "off") return subprocess.run( diff --git a/registry/index.json b/registry/index.json index a2caa4b..b4b431c 100644 --- a/registry/index.json +++ b/registry/index.json @@ -78,9 +78,9 @@ }, { "id": "nold-ai/specfact-code-review", - "latest_version": "0.47.14", - "download_url": "modules/specfact-code-review-0.47.14.tar.gz", - "checksum_sha256": "2dbe299a82c3fc48f676a5b90ddc35f0454abf6fa48abc1913b8aaba07fba321", + "latest_version": "0.47.15", + "download_url": "modules/specfact-code-review-0.47.15.tar.gz", + "checksum_sha256": "f9b675348b58aec57c13250bd999f8adf6edb9a1db6c99d418e10a9eb69979ca", "core_compatibility": ">=0.44.0,<1.0.0", "tier": "official", "publisher": { diff --git a/registry/modules/specfact-code-review-0.47.15.tar.gz b/registry/modules/specfact-code-review-0.47.15.tar.gz new file mode 100644 index 0000000..852aca9 Binary files /dev/null and b/registry/modules/specfact-code-review-0.47.15.tar.gz differ diff --git a/registry/modules/specfact-code-review-0.47.15.tar.gz.sha256 b/registry/modules/specfact-code-review-0.47.15.tar.gz.sha256 new file mode 100644 index 0000000..4b9c71f --- /dev/null +++ b/registry/modules/specfact-code-review-0.47.15.tar.gz.sha256 @@ -0,0 +1 @@ +f9b675348b58aec57c13250bd999f8adf6edb9a1db6c99d418e10a9eb69979ca diff --git a/registry/signatures/specfact-code-review-0.47.15.tar.sig b/registry/signatures/specfact-code-review-0.47.15.tar.sig new file mode 100644 index 0000000..1808ab5 --- /dev/null +++ b/registry/signatures/specfact-code-review-0.47.15.tar.sig @@ -0,0 +1 @@ +w5tEmlYK7MGBFVD19g7b7D3pob27CgP2dF12J3fxbr268LskXZZ1rNvwhK/7FRYYjGci8pIJAfg8ZtRCeWTfBg== diff --git a/tests/unit/specfact_code_review/tools/test_semgrep_runner.py b/tests/unit/specfact_code_review/tools/test_semgrep_runner.py index b2f1207..6661ec8 100644 --- a/tests/unit/specfact_code_review/tools/test_semgrep_runner.py +++ b/tests/unit/specfact_code_review/tools/test_semgrep_runner.py @@ -10,6 +10,7 @@ from pytest import MonkeyPatch from specfact_code_review.tools.semgrep_runner import ( + _run_semgrep_command, _snip_stderr_tail, find_semgrep_config, run_semgrep, @@ -35,6 +36,30 @@ ] +def test_run_semgrep_command_creates_runtime_dirs(tmp_path: Path, monkeypatch: MonkeyPatch) -> None: + target = tmp_path / "target.py" + config = tmp_path / "clean_code.yaml" + target.write_text("print('x')\n", encoding="utf-8") + config.write_text("rules: []\n", encoding="utf-8") + captured_env: dict[str, str] = {} + + def _run(command: list[str], **kwargs: object) -> subprocess.CompletedProcess[str]: + del command + env = kwargs["env"] + assert isinstance(env, dict) + captured_env.update({str(key): str(value) for key, value in env.items()}) + assert Path(captured_env["XDG_CONFIG_HOME"]).is_dir() + assert Path(captured_env["XDG_CACHE_HOME"]).is_dir() + assert Path(captured_env["SEMGREP_SETTINGS_FILE"]).parent.is_dir() + return completed_process("semgrep", stdout='{"results": []}', returncode=0) + + monkeypatch.setattr(subprocess, "run", _run) + + _run_semgrep_command([target], bundle_root=None, config_file=config) + + assert captured_env["XDG_CONFIG_HOME"].endswith(".config") + + @pytest.fixture(autouse=True) def _stub_semgrep_on_path(monkeypatch: MonkeyPatch) -> None: # pyright: ignore[reportUnusedFunction] real_which = shutil.which