64 lines
2.1 KiB
Python
64 lines
2.1 KiB
Python
"""Regression tests for bundled skill scripts and local shell execution.
|
|
|
|
Issue #953 verifies that bundled skill scripts run out of the box from the
|
|
installed ~/.hermes/skills tree without manual chmod or PATH surgery.
|
|
"""
|
|
|
|
import shlex
|
|
import shutil
|
|
import stat
|
|
from pathlib import Path
|
|
|
|
from tools.environments.local import LocalEnvironment
|
|
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
SKILLS_ROOT = REPO_ROOT / "skills"
|
|
|
|
|
|
def _bundled_shebang_scripts() -> list[Path]:
|
|
scripts: list[Path] = []
|
|
for path in SKILLS_ROOT.rglob("*"):
|
|
if not path.is_file() or path.is_symlink() or "scripts" not in path.parts:
|
|
continue
|
|
first_line = path.read_bytes().splitlines()[:1]
|
|
if first_line and first_line[0].startswith(b"#!"):
|
|
scripts.append(path)
|
|
return sorted(scripts)
|
|
|
|
|
|
def test_bundled_skill_shebang_scripts_are_executable():
|
|
missing = []
|
|
for path in _bundled_shebang_scripts():
|
|
mode = stat.S_IMODE(path.stat().st_mode)
|
|
if mode & 0o111 == 0:
|
|
missing.append(f"{path.relative_to(REPO_ROOT)} ({oct(mode)})")
|
|
|
|
assert not missing, (
|
|
"Bundled shebang scripts must ship executable so synced skill copies run "
|
|
"without manual chmod:\n" + "\n".join(missing)
|
|
)
|
|
|
|
|
|
def test_local_environment_executes_installed_skill_script_without_manual_prep(tmp_path):
|
|
hermes_home = tmp_path / ".hermes"
|
|
installed_skill = hermes_home / "skills" / "research" / "arxiv"
|
|
installed_skill.parent.mkdir(parents=True, exist_ok=True)
|
|
shutil.copytree(SKILLS_ROOT / "research" / "arxiv", installed_skill)
|
|
|
|
script_path = installed_skill / "scripts" / "search_arxiv.py"
|
|
env = LocalEnvironment(
|
|
cwd=str(tmp_path),
|
|
timeout=15,
|
|
env={
|
|
"HERMES_HOME": str(hermes_home),
|
|
"PATH": "/custom/bin",
|
|
},
|
|
)
|
|
|
|
result = env.execute(f"{shlex.quote(str(script_path))} --help")
|
|
|
|
assert result["returncode"] == 0, result["output"]
|
|
assert "Search arXiv and display results in a clean format." in result["output"]
|
|
assert "python search_arxiv.py" in result["output"]
|