feat: Enhance node runner to execute scripts in source directory and update tests
This commit is contained in:
@@ -465,7 +465,16 @@ def _build_run_cmd(
|
||||
cmd.extend(run.args) # type: ignore[union-attr]
|
||||
return cmd
|
||||
case "node":
|
||||
cmd = [run.package_manager, "run", run.script] # type: ignore[union-attr]
|
||||
# Like the python runner bakes `--project <source>` into `uv run`, the
|
||||
# node runner bakes `--dir <source>` so the package manager runs the
|
||||
# script in the program's source dir — the systemd unit carries no
|
||||
# WorkingDirectory, so a bare `pnpm run` would otherwise execute in the
|
||||
# service's (wrong) cwd. Resolve the package manager to an absolute path.
|
||||
pm = shutil.which(run.package_manager) or run.package_manager # type: ignore[union-attr]
|
||||
cmd = [pm]
|
||||
if source_dir and source_dir.is_dir():
|
||||
cmd.extend(["--dir", str(source_dir)])
|
||||
cmd.extend(["run", run.script]) # type: ignore[union-attr]
|
||||
if run.args: # type: ignore[union-attr]
|
||||
cmd.extend(run.args) # type: ignore[union-attr]
|
||||
return cmd
|
||||
|
||||
@@ -6,7 +6,7 @@ from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
from castle_core.deploy import _build_run_cmd
|
||||
from castle_core.manifest import RunContainer, RunPython
|
||||
from castle_core.manifest import RunContainer, RunNode, RunPython
|
||||
|
||||
|
||||
def test_python_runner_uses_uv_run_from_source(tmp_path: Path) -> None:
|
||||
@@ -52,6 +52,39 @@ def test_python_runner_warns_when_unresolvable() -> None:
|
||||
assert any("my-svc" in m for m in messages)
|
||||
|
||||
|
||||
def test_node_runner_bakes_source_dir(tmp_path: Path) -> None:
|
||||
"""A node service runs the script in its source dir via `--dir` (no unit cwd)."""
|
||||
run = RunNode(runner="node", script="gateway:watch:raw", package_manager="pnpm")
|
||||
with patch("castle_core.deploy.shutil.which", return_value="/usr/bin/pnpm"):
|
||||
cmd = _build_run_cmd("oc", run, {}, [], source_dir=tmp_path)
|
||||
assert cmd == ["/usr/bin/pnpm", "--dir", str(tmp_path), "run", "gateway:watch:raw"]
|
||||
|
||||
|
||||
def test_node_runner_appends_args(tmp_path: Path) -> None:
|
||||
run = RunNode(
|
||||
runner="node", script="start", package_manager="pnpm", args=["--port", "18789"]
|
||||
)
|
||||
with patch("castle_core.deploy.shutil.which", return_value="/usr/bin/pnpm"):
|
||||
cmd = _build_run_cmd("oc", run, {}, [], source_dir=tmp_path)
|
||||
assert cmd == [
|
||||
"/usr/bin/pnpm",
|
||||
"--dir",
|
||||
str(tmp_path),
|
||||
"run",
|
||||
"start",
|
||||
"--port",
|
||||
"18789",
|
||||
]
|
||||
|
||||
|
||||
def test_node_runner_without_source_omits_dir() -> None:
|
||||
"""No resolvable source → bare `pnpm run` (package manager still PATH-resolved)."""
|
||||
run = RunNode(runner="node", script="start", package_manager="pnpm")
|
||||
with patch("castle_core.deploy.shutil.which", return_value="/usr/bin/pnpm"):
|
||||
cmd = _build_run_cmd("oc", run, {}, [], source_dir=None)
|
||||
assert cmd == ["/usr/bin/pnpm", "run", "start"]
|
||||
|
||||
|
||||
def test_container_secrets_use_env_file_not_argv() -> None:
|
||||
"""Secrets go through --env-file; plain vars stay as -e; no secret in argv."""
|
||||
run = RunContainer(runner="container", image="img:latest", env={"PLAIN": "1"})
|
||||
|
||||
Reference in New Issue
Block a user