Skip to content
Open
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
7 changes: 5 additions & 2 deletions src/pytest_just/fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,11 @@ def dry_run(
*args: str,
env: dict[str, str] | None = None,
) -> subprocess.CompletedProcess[str]:
"""Run ``just --dry-run`` for a non-shebang recipe."""
self.assert_not_shebang(recipe)
"""Run ``just --dry-run`` for any recipe, including shebang and script recipes.

``just --dry-run`` does not run recipes of any kind — linewise, shebang, or script.
See https://github.com/casey/just/issues/3177.
"""
merged_env = dict(os.environ)
if env:
merged_env.update(env)
Expand Down
77 changes: 77 additions & 0 deletions tests/test_dry_run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"""Tests for ``JustfileFixture.dry_run`` across all recipe types."""

from __future__ import annotations

import shutil
from pathlib import Path

import pytest

from pytest_just import JustfileFixture


pytestmark = pytest.mark.skipif(shutil.which("just") is None, reason="just binary is required")


@pytest.fixture
def linewise(tmp_path: Path) -> JustfileFixture:
"""Justfile with a linewise recipe."""
(tmp_path / "justfile").write_text(
"greet name='world':\n"
" echo hello {{ name }}\n",
encoding="utf-8",
)
return JustfileFixture(root=tmp_path)


@pytest.fixture
def shebang(tmp_path: Path) -> JustfileFixture:
"""Justfile with a shebang recipe."""
(tmp_path / "justfile").write_text(
"deploy:\n"
" #!/usr/bin/env bash\n"
" echo deploying\n",
encoding="utf-8",
)
return JustfileFixture(root=tmp_path)


@pytest.fixture
def script(tmp_path: Path) -> JustfileFixture:
"""Justfile with a [script] recipe."""
(tmp_path / "justfile").write_text(
"[script]\n"
"check target='all':\n"
" echo checking {{ target }}\n"
" echo done\n",
encoding="utf-8",
)
return JustfileFixture(root=tmp_path)


def test_dry_run_linewise(linewise: JustfileFixture) -> None:
"""Linewise dry-run resolves variables and prints commands."""
result = linewise.dry_run("greet")
assert result.returncode == 0
assert "echo hello world" in result.stderr


def test_dry_run_shebang(shebang: JustfileFixture) -> None:
"""Shebang dry-run prints the script body without executing."""
result = shebang.dry_run("deploy")
assert result.returncode == 0
assert "echo deploying" in result.stderr


def test_dry_run_script(script: JustfileFixture) -> None:
"""[script] dry-run resolves variables and prints the script body."""
result = script.dry_run("check")
assert result.returncode == 0
assert "checking all" in result.stderr


def test_dry_run_with_args(linewise: JustfileFixture) -> None:
"""Arguments are interpolated into the dry-run output."""
result = linewise.dry_run("greet", "alice")
assert result.returncode == 0
assert "echo hello alice" in result.stderr
10 changes: 4 additions & 6 deletions tests/test_fixture_edge_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ def test_imported_recipe_is_visible(tmp_path: Path) -> None:
just.assert_body_contains("hello", "@echo hi")


def test_dry_run_rejects_shebang_recipe(tmp_path: Path) -> None:
"""Ensure shebang recipes are rejected for dry-run execution."""
def test_dry_run_allows_shebang_recipe(tmp_path: Path) -> None:
"""Ensure shebang/script recipes can be dry-run safely."""
(tmp_path / "justfile").write_text(
"deploy:\n"
" #!/usr/bin/env bash\n"
Expand All @@ -132,10 +132,8 @@ def test_dry_run_rejects_shebang_recipe(tmp_path: Path) -> None:
)
just = JustfileFixture(root=tmp_path)

with pytest.raises(AssertionError) as exc_info:
just.dry_run("deploy")

assert "not dry-run safe" in str(exc_info.value)
result = just.dry_run("deploy")
assert result.returncode == 0


def test_assert_dry_run_contains_failure_includes_output(tmp_path: Path) -> None:
Expand Down