mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-10-26 13:16:24 +00:00
fix(check): preserve UTF-8 dependency diagnostics (#6485)
* fix(check): preserve UTF-8 dependency diagnostics * chore: preserve upstream LF line endings --------- Co-authored-by: Zhangchenhao-111 <285911435+Zhangchenhao-111@users.noreply.github.com>
This commit is contained in:
parent
89c9f08714
commit
7797409355
@ -543,6 +543,10 @@ such a checkout, use `bash ./scripts/<name>.sh ...`.
|
||||
|
||||
The local `make check`, `make install`, `make dev`, and `make start` entry points use a direct `pnpm` executable when available and otherwise fall back to `corepack pnpm`. With native Windows Python, the shared runner checks `pnpm.cmd` before the generic `pnpm` lookup, which follows `PATH`/`PATHEXT` and may select an `.exe` or `.bat` in the same or an earlier PATH directory. The Corepack fallback likewise checks `corepack.cmd` before `corepack`. POSIX Python keeps the generic names first, including when running under MSYS/Cygwin. The runner and diagnostics resolve repository paths absolutely, so these checks work regardless of the caller's current directory. Corepack runs from `frontend/`, so it honors the `packageManager` version pinned in `frontend/package.json`; enabling a global pnpm shim is not required.
|
||||
|
||||
`make check` decodes tool diagnostics as UTF-8 and preserves Unicode pnpm
|
||||
errors on non-UTF-8 hosts. Invalid output bytes are replaced so the checker
|
||||
can report dependency failures instead of aborting while decoding output.
|
||||
|
||||
2. **Install dependencies**:
|
||||
```bash
|
||||
make install # Install backend + frontend dependencies + pre-commit hooks
|
||||
|
||||
@ -2,8 +2,11 @@ from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
CHECK_SCRIPT_PATH = REPO_ROOT / "scripts" / "check.py"
|
||||
PNPM_SCRIPT_PATH = REPO_ROOT / "scripts" / "pnpm.py"
|
||||
@ -162,3 +165,30 @@ def test_old_node_check_suggests_a_version_manager_command(monkeypatch, capsys):
|
||||
|
||||
assert check_script.main() == 1
|
||||
assert "nvm install 22 && nvm use 22" in capsys.readouterr().out
|
||||
|
||||
|
||||
@pytest.mark.parametrize("host_encoding", ["ascii", "cp936"])
|
||||
def test_check_decodes_tool_output_as_utf8(monkeypatch, host_encoding):
|
||||
script = _load_script(CHECK_SCRIPT_PATH, "check_utf8_tool")
|
||||
monkeypatch.setattr(subprocess, "_text_encoding", lambda: host_encoding)
|
||||
text = "✓ 检查完成"
|
||||
code = f"import sys; sys.stdout.buffer.write({text.encode('utf-8')!r})"
|
||||
assert script.run_command([sys.executable, "-c", code]) == text
|
||||
|
||||
|
||||
@pytest.mark.parametrize("host_encoding", ["ascii", "cp936"])
|
||||
def test_check_preserves_unicode_pnpm_error(tmp_path, monkeypatch, host_encoding):
|
||||
script = _load_script(CHECK_SCRIPT_PATH, "check_utf8_pnpm")
|
||||
runner = tmp_path / "pnpm.py"
|
||||
diagnostic = "✗ 无法运行 pnpm"
|
||||
runner.write_text(f"import sys\nprint({ascii(diagnostic)}, file=sys.stderr)\nsys.exit(7)\n", encoding="utf-8")
|
||||
monkeypatch.setattr(script, "PNPM_SCRIPT_PATH", runner)
|
||||
monkeypatch.setattr(script, "FRONTEND_DIR", tmp_path)
|
||||
monkeypatch.setattr(subprocess, "_text_encoding", lambda: host_encoding)
|
||||
monkeypatch.setenv("PYTHONIOENCODING", "ascii")
|
||||
assert script.run_pnpm_version() == (None, False, diagnostic)
|
||||
|
||||
|
||||
def test_check_replaces_invalid_tool_output_bytes():
|
||||
script = _load_script(CHECK_SCRIPT_PATH, "check_invalid_tool_bytes")
|
||||
assert script.run_command([sys.executable, "-c", "import sys; sys.stdout.buffer.write(b'v22.0.0\\xff')"]) == "v22.0.0\ufffd"
|
||||
|
||||
@ -1,3 +1,11 @@
|
||||
## Dependency Check Diagnostics
|
||||
|
||||
`check.py` captures tool output as UTF-8 with replacement for malformed bytes,
|
||||
independently of the host locale. Its Python pnpm runner inherits the environment
|
||||
with `PYTHONIOENCODING=utf-8:backslashreplace`, matching the capture encoding.
|
||||
Keep Unicode failure diagnostics and exit status available to `make check`.
|
||||
Real subprocess regressions live in `backend/tests/test_check_script.py`.
|
||||
|
||||
## Manual Claude OAuth Export
|
||||
|
||||
`export_claude_code_oauth.py` validates Keychain JSON as an object containing an
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
@ -28,7 +29,13 @@ def run_command(command: list[str]) -> str | None:
|
||||
"""Run a command and return trimmed stdout, or None on failure."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
command, capture_output=True, text=True, check=True, shell=False
|
||||
command,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
check=True,
|
||||
shell=False,
|
||||
)
|
||||
except (OSError, subprocess.CalledProcessError):
|
||||
return None
|
||||
@ -42,6 +49,9 @@ def run_pnpm_version() -> tuple[str | None, bool, str | None]:
|
||||
[sys.executable, str(PNPM_SCRIPT_PATH), "-v"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
env={**os.environ, "PYTHONIOENCODING": "utf-8:backslashreplace"},
|
||||
check=False,
|
||||
shell=False,
|
||||
cwd=FRONTEND_DIR,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user