Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions edalize/flows/edaflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,9 @@ def _run_tool(self, cmd, args=[], cwd=None, quiet=False, env={}):
logger.debug("args : " + " ".join(args))

capture_output = quiet and not (self.verbose or self.stdout or self.stderr)
abs_cwd = os.path.abspath(cwd) if cwd else None
if abs_cwd:
print(f"Entering directory '{abs_cwd}'")
try:
cp = run(
[cmd] + args,
Expand All @@ -369,6 +372,8 @@ def _run_tool(self, cmd, args=[], cwd=None, quiet=False, env={}):
logger.debug(e.stderr)

raise RuntimeError(_s)
if abs_cwd:
print(f"Leaving directory '{abs_cwd}'")
return cp.returncode, cp.stdout, cp.stderr

def build(self):
Expand Down
106 changes: 106 additions & 0 deletions tests/test_run_tool_dirnotify.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import os
from unittest.mock import patch, MagicMock
import subprocess

import pytest


# ── Legacy API ──────────────────────────────────────────────────────────


def _make_legacy_tool(work_root):
"""Create a minimal legacy Edatool instance with enough state to call _run_tool."""
from edalize.edatool import Edatool

obj = object.__new__(Edatool)
obj.work_root = str(work_root)
obj.verbose = False
obj.stdout = None
obj.stderr = None
return obj


@patch("edalize.edatool.run")
def test_legacy_run_tool_prints_dir_notifications(mock_run, tmp_path, capsys):
mock_run.return_value = subprocess.CompletedProcess(
args=["true"], returncode=0, stdout=None, stderr=None
)

tool = _make_legacy_tool(tmp_path)
tool._run_tool("true")

captured = capsys.readouterr().out
abs_path = str(os.path.abspath(tmp_path))
assert f"Entering directory '{abs_path}'" in captured
assert f"Leaving directory '{abs_path}'" in captured


@patch("edalize.edatool.run")
def test_legacy_run_tool_no_leaving_on_error(mock_run, tmp_path, capsys):
mock_run.side_effect = FileNotFoundError("not found")

tool = _make_legacy_tool(tmp_path)
with pytest.raises(RuntimeError):
tool._run_tool("nonexistent_cmd")

captured = capsys.readouterr().out
abs_path = str(os.path.abspath(tmp_path))
assert f"Entering directory '{abs_path}'" in captured
assert "Leaving directory" not in captured


# ── Flow API ────────────────────────────────────────────────────────────


def _make_flow_tool():
"""Create a minimal Edaflow-like object to test _run_tool."""
from edalize.flows.edaflow import Edaflow

obj = object.__new__(Edaflow)
obj.verbose = False
obj.stdout = None
obj.stderr = None
return obj


@patch("edalize.flows.edaflow.run")
def test_flow_run_tool_prints_dir_notifications(mock_run, tmp_path, capsys):
mock_run.return_value = subprocess.CompletedProcess(
args=["true"], returncode=0, stdout=None, stderr=None
)

flow = _make_flow_tool()
flow._run_tool("true", cwd=str(tmp_path))

captured = capsys.readouterr().out
abs_path = str(os.path.abspath(tmp_path))
assert f"Entering directory '{abs_path}'" in captured
assert f"Leaving directory '{abs_path}'" in captured


@patch("edalize.flows.edaflow.run")
def test_flow_run_tool_no_leaving_on_error(mock_run, tmp_path, capsys):
mock_run.side_effect = FileNotFoundError("not found")

flow = _make_flow_tool()
with pytest.raises(RuntimeError):
flow._run_tool("nonexistent_cmd", cwd=str(tmp_path))

captured = capsys.readouterr().out
abs_path = str(os.path.abspath(tmp_path))
assert f"Entering directory '{abs_path}'" in captured
assert "Leaving directory" not in captured


@patch("edalize.flows.edaflow.run")
def test_flow_run_tool_no_cwd_skips_notifications(mock_run, capsys):
mock_run.return_value = subprocess.CompletedProcess(
args=["true"], returncode=0, stdout=None, stderr=None
)

flow = _make_flow_tool()
flow._run_tool("true")

captured = capsys.readouterr().out
assert "Entering directory" not in captured
assert "Leaving directory" not in captured
Loading