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
16 changes: 15 additions & 1 deletion src/shotbible/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,11 +382,25 @@ def cmd_take_add(args: argparse.Namespace) -> int:
def cmd_prompt(args: argparse.Namespace) -> int:
root, bible = _load(args)
if args.all_scenes:
if args.output not in (None, ""):
raise StoreError(
"prompt --all writes one file per scene under takes/; "
"do not pass -o FILE (use -o with no path for the default)"
)
if not bible.scenes:
raise StoreError("no scenes to compile")
character_id = args.character or ""
if character_id:
require_character(bible, character_id)
wrote = 0
for sid in bible.scenes:
text = compile_prompt(bible, sid, kind=args.kind)
text = compile_prompt(
bible,
sid,
beat=args.beat or "",
character_id=character_id,
kind=args.kind,
)
_emit_prompt(root, text, "", f"{sid}.prompt.txt")
wrote += 1
print(f"wrote {wrote} prompt file(s)")
Expand Down
2 changes: 2 additions & 0 deletions src/shotbible/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ def copy_take_file(root: Path, src: Path, take_id: str) -> str:

def copy_asset(root: Path, src: Path, kind: str, bucket: str) -> str:
src = src.expanduser().resolve()
if src.is_dir():
raise StoreError(f"not a file: {src}")
if not src.is_file():
raise StoreError(f"file not found: {src}")
dest_dir = root / kind / _safe_id(bucket)
Expand Down
22 changes: 22 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,28 @@ def test_cli_prompt_all_writes_each_scene(
assert "classroom" in text.lower() or "desks" in text


def test_cli_prompt_all_rejects_output_file(
sample_project: tuple[Path, Bible],
monkeypatch: pytest.MonkeyPatch,
) -> None:
root, _bible = sample_project
monkeypatch.chdir(root)
assert main(["prompt", "--all", "-o", "one.txt"]) == 2
assert not (root / "one.txt").exists()


def test_cli_prompt_all_applies_beat_and_character(
sample_project: tuple[Path, Bible],
monkeypatch: pytest.MonkeyPatch,
) -> None:
root, _bible = sample_project
monkeypatch.chdir(root)
assert main(["prompt", "--all", "--beat", "独自合上笔记本", "--character", "mei"]) == 0
text = (root / "takes" / "s01.prompt.txt").read_text(encoding="utf-8")
assert "独自合上笔记本" in text
assert NAME in text or "mei" in text


def test_cli_check_exit_codes(
sample_project: tuple[Path, Bible], monkeypatch: pytest.MonkeyPatch
) -> None:
Expand Down
8 changes: 8 additions & 0 deletions tests/test_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ def test_load_invalid_duration_is_store_error(tmp_path: Path) -> None:
load(root)


def test_copy_ref_rejects_directory(tmp_path: Path) -> None:
root = init_project(tmp_path / "refs-dir")
folder = tmp_path / "album"
folder.mkdir()
with pytest.raises(StoreError, match="not a file"):
copy_ref(root, folder, "mei")


def test_example_campus_night_loads() -> None:
root, bible = load(EXAMPLE)
assert root == EXAMPLE.resolve()
Expand Down
Loading