You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@magpie.apache.org by po...@apache.org on 2026/10/23 10:41:14 UTC

(magpie) branch main updated: fix(dev): support stdin '-' and normalize path separators in ci-pytest-batches.py (#1767)

This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/magpie.git


The following commit(s) were added to refs/heads/main by this push:
     new 5841d2eed fix(dev): support stdin '-' and normalize path separators in ci-pytest-batches.py (#1767)
5841d2eed is described below

commit 5841d2eed4d3fbbbc10b47ec911c17256e8ab5cd
Author: Vardhman Gupta <11...@users.noreply.github.com>
AuthorDate: Fri Oct 23 16:11:09 2026 +0530

    fix(dev): support stdin '-' and normalize path separators in ci-pytest-batches.py (#1767)
    
    * fix(dev): support stdin '-' and normalize path separators in ci-pytest-batches.py
    
    * docs(dev): mention `-` for stdin in ci-pytest-batches.py
    
    - module docstring: `--changed-file` names a file, or `-` to read the
      changed paths from stdin
    - `--help` text for `--changed-file`: add "or - for stdin"
    
    Generated-by: Claude Code (Opus 5.5)
    
    * style(setup): format test_probe_1_ssh_agent.py for ruff-format
    
    ---------
    
    Co-authored-by: Jarek Potiuk <po...@apache.org>
---
 .../tests/test_probe_1_ssh_agent.py                     |  4 +---
 tools/dev/ci-pytest-batches.py                          | 17 ++++++++++-------
 tools/dev/run-workspace-check.sh                        |  2 +-
 tools/dev/tests/test_ci_pytest_batches.py               | 15 ++++++++++++++-
 4 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/plugins/magpie-setup/skills/isolated-setup-doctor/tests/test_probe_1_ssh_agent.py b/plugins/magpie-setup/skills/isolated-setup-doctor/tests/test_probe_1_ssh_agent.py
index 6acdc70ea..b96889b19 100644
--- a/plugins/magpie-setup/skills/isolated-setup-doctor/tests/test_probe_1_ssh_agent.py
+++ b/plugins/magpie-setup/skills/isolated-setup-doctor/tests/test_probe_1_ssh_agent.py
@@ -69,9 +69,7 @@ class ProbeOneSshAgent(unittest.TestCase):
             "SSH_AUTH_SOCK": str(self.sock_path),
             "TMPDIR": str(self.tmp),
         }
-        result = subprocess.run(
-            ["bash", str(PROBE)], env=env, capture_output=True, text=True, check=True
-        )
+        result = subprocess.run(["bash", str(PROBE)], env=env, capture_output=True, text=True, check=True)
         return result.stdout.strip()
 
     def test_counts_listed_identities(self) -> None:
diff --git a/tools/dev/ci-pytest-batches.py b/tools/dev/ci-pytest-batches.py
index 565f1cd4e..f1282214c 100644
--- a/tools/dev/ci-pytest-batches.py
+++ b/tools/dev/ci-pytest-batches.py
@@ -35,7 +35,8 @@ members are grouped:
 Prints a JSON array of `{"key", "name", "paths", "packages"}` for the workflow's
 matrix (`paths` and `packages` space-separated, in the same order; `packages` are
 the members' project names, so a job syncs only what its members declare).
-`--changed-file` names a file listing the changed paths; omit it for a full run.
+`--changed-file` names a file listing the changed paths, or `-` to read them from stdin;
+omit it for a full run.
 `--paths` prints the picked member paths one per line instead, for the local
 `workspace-pytest` hook, so a commit runs the same members a pull request would.
 """
@@ -209,16 +210,18 @@ def batches(paths: list[str], weights: dict[str, int]) -> list[dict[str, str]]:
 def main(argv: list[str] | None = None) -> int:
     parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
     parser.add_argument("--root", type=Path, default=Path("."))
-    parser.add_argument("--changed-file", type=Path, help="file listing a pull request's changed paths")
+    parser.add_argument(
+        "--changed-file", type=Path, help="file listing a pull request's changed paths, or - for stdin"
+    )
     parser.add_argument("--paths", action="store_true", help="print the picked member paths, one per line")
     args = parser.parse_args(argv)
     changed = None
     if args.changed_file:
-        changed = [
-            line.strip()
-            for line in args.changed_file.read_text(encoding="utf-8").splitlines()
-            if line.strip()
-        ]
+        if str(args.changed_file) == "-":
+            raw_lines = sys.stdin.read().splitlines()
+        else:
+            raw_lines = args.changed_file.read_text(encoding="utf-8").splitlines()
+        changed = [line.strip().replace("\\", "/") for line in raw_lines if line.strip()]
     paths = select(args.root, changed)
     if args.paths:
         for path in paths:
diff --git a/tools/dev/run-workspace-check.sh b/tools/dev/run-workspace-check.sh
index 2457370e8..84cba55d7 100755
--- a/tools/dev/run-workspace-check.sh
+++ b/tools/dev/run-workspace-check.sh
@@ -162,7 +162,7 @@ fi
 if [ "$CHECK_KEY" = "pytest" ] && [ "$#" -gt 0 ]; then
   # The list goes through stdin, not a temp file: a sandboxed agent may
   # not be able to write the system temp directory.
-  applicable=$(printf '%s\n' "$@" | python3 tools/dev/ci-pytest-batches.py --changed-file /dev/stdin --paths)
+  applicable=$(printf '%s\n' "$@" | python3 tools/dev/ci-pytest-batches.py --changed-file - --paths | tr -d '\r')
   status=$?
   if [ "$status" -ne 0 ]; then
     exit "$status"
diff --git a/tools/dev/tests/test_ci_pytest_batches.py b/tools/dev/tests/test_ci_pytest_batches.py
index 6959a8e3c..8fc716eb3 100644
--- a/tools/dev/tests/test_ci_pytest_batches.py
+++ b/tools/dev/tests/test_ci_pytest_batches.py
@@ -20,6 +20,7 @@
 from __future__ import annotations
 
 import importlib.util
+import io
 import json
 from pathlib import Path
 from types import ModuleType
@@ -91,7 +92,12 @@ def test_a_change_behind_a_member_symlink_picks_the_member(tmp_path):
     root = _workspace(tmp_path, {"tools/a": PYTEST, "tools/b": PYTEST})
     (root / "plugins" / "shared").mkdir(parents=True)
     (root / "tools" / "a" / "src").mkdir()
-    (root / "tools" / "a" / "src" / "shared").symlink_to(root / "plugins" / "shared")
+    try:
+        (root / "tools" / "a" / "src" / "shared").symlink_to(
+            root / "plugins" / "shared", target_is_directory=True
+        )
+    except OSError as exc:
+        pytest.skip(f"symlinks not supported on this platform: {exc}")
     assert cpb.select(root, ["plugins/shared/x.py"]) == ["tools/a"]
 
 
@@ -135,6 +141,13 @@ def test_the_shared_toolchain_does_not_make_a_dependent(tmp_path):
     assert cpb.select(root, ["tools/dev/src/z.py"]) == ["tools/dev"]
 
 
+def test_the_cli_reads_stdin_with_dash(tmp_path, monkeypatch, capsys):
+    root = _workspace(tmp_path, {"tools/a": PYTEST, "tools/b": PYTEST})
+    monkeypatch.setattr("sys.stdin", io.StringIO("tools\\a\\src\\x.py\ntools/b/tests/test_y.py\n"))
+    assert cpb.main(["--root", str(root), "--changed-file", "-", "--paths"]) == 0
+    assert capsys.readouterr().out == "tools/a\ntools/b\n"
+
+
 def test_the_cli_prints_the_picked_paths(tmp_path, capsys):
     root = _workspace(tmp_path, {"tools/a": PYTEST, "tools/b": PYTEST})
     changed = tmp_path / "changed.txt"