From 309ae9958c5b8aeb465e83d41fad81c57fcd9603 Mon Sep 17 00:00:00 2001 From: Srihari Sriraman Date: Thu, 11 Sep 2025 12:14:50 -0400 Subject: [PATCH 1/2] fix: Add early validation for target directory before story generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validate that the target directory exists and is a directory before starting story generation to fail fast instead of after processing stories. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/storymachine/cli.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/storymachine/cli.py b/src/storymachine/cli.py index 3a90d31..b2f2f3f 100644 --- a/src/storymachine/cli.py +++ b/src/storymachine/cli.py @@ -127,6 +127,15 @@ def main(): print(f"Error: Tech spec file not found: {tech_spec_path}", file=sys.stderr) sys.exit(1) + target_path = Path(args.target_dir) + if not target_path.exists(): + print(f"Error: Target directory not found: {target_path}", file=sys.stderr) + sys.exit(1) + + if not target_path.is_dir(): + print(f"Error: Target path is not a directory: {target_path}", file=sys.stderr) + sys.exit(1) + with spinner("Machining Stories"): created_stories = get_context_enriched_stories( client, From e0907170fb3aabe9a78e6e46459345f6815c1579 Mon Sep 17 00:00:00 2001 From: Srihari Sriraman Date: Thu, 11 Sep 2025 12:34:49 -0400 Subject: [PATCH 2/2] test: Add target directory validation tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add tests to verify early validation of target directory: - Test non-existent target directory exits with error - Test file instead of directory as target exits with error - Ensure tests follow existing pattern for file validation tests 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- tests/test_cli.py | 80 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/tests/test_cli.py b/tests/test_cli.py index 82413f6..45383b7 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -296,3 +296,83 @@ def test_main_missing_tech_spec_file_exits( assert excinfo.value.code == 1 err = capsys.readouterr().err assert f"Error: Tech spec file not found: {missing_tech}" in err + + +def test_main_nonexistent_target_dir_exits( + monkeypatch: pytest.MonkeyPatch, tmp_path: Path, capsys: pytest.CaptureFixture[str] +) -> None: + """Test that main() exits when target directory doesn't exist.""" + # Create both input files + prd_file = tmp_path / "prd.md" + tech_spec_file = tmp_path / "tech_spec.md" + prd_file.write_text("PRD content") + tech_spec_file.write_text("Tech spec content") + + # Use non-existent target directory + nonexistent_dir = tmp_path / "nonexistent" + + with monkeypatch.context(): + monkeypatch.setenv("OPENAI_API_KEY", "test-key") + monkeypatch.setattr( + "storymachine.cli.OpenAI", MagicMock(return_value=MagicMock()) + ) + monkeypatch.setattr( + sys, + "argv", + [ + "storymachine", + "--prd", + str(prd_file), + "--tech-spec", + str(tech_spec_file), + "--target-dir", + str(nonexistent_dir), + ], + ) + + with pytest.raises(SystemExit) as excinfo: + main() + + assert excinfo.value.code == 1 + err = capsys.readouterr().err + assert f"Error: Target directory not found: {nonexistent_dir}" in err + + +def test_main_target_is_file_exits( + monkeypatch: pytest.MonkeyPatch, tmp_path: Path, capsys: pytest.CaptureFixture[str] +) -> None: + """Test that main() exits when target path is a file, not a directory.""" + # Create both input files + prd_file = tmp_path / "prd.md" + tech_spec_file = tmp_path / "tech_spec.md" + target_file = tmp_path / "target.txt" + + prd_file.write_text("PRD content") + tech_spec_file.write_text("Tech spec content") + target_file.write_text("This is a file, not a directory") + + with monkeypatch.context(): + monkeypatch.setenv("OPENAI_API_KEY", "test-key") + monkeypatch.setattr( + "storymachine.cli.OpenAI", MagicMock(return_value=MagicMock()) + ) + monkeypatch.setattr( + sys, + "argv", + [ + "storymachine", + "--prd", + str(prd_file), + "--tech-spec", + str(tech_spec_file), + "--target-dir", + str(target_file), + ], + ) + + with pytest.raises(SystemExit) as excinfo: + main() + + assert excinfo.value.code == 1 + err = capsys.readouterr().err + assert f"Error: Target path is not a directory: {target_file}" in err