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
57 changes: 33 additions & 24 deletions manim/cli/init/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,31 +115,40 @@ def project(default_settings: bool, **kwargs: Any) -> None:
default="Default",
)

if project_name.is_dir():
console.print(
f"\nFolder [red]{project_name}[/red] exists. Please type another name\n",
)
else:
project_name.mkdir()
new_cfg: dict[str, Any] = {}
new_cfg_path = Path.resolve(project_name / "manim.cfg")

if not default_settings:
for key, value in CFG_DEFAULTS.items():
if key == "scene_names":
new_cfg[key] = template_name + "Template"
elif key == "resolution":
new_cfg[key] = select_resolution()
else:
new_cfg[key] = click.prompt(f"\n{key}", default=value)

console.print("\n", new_cfg)
if click.confirm("Do you want to continue?", default=True, abort=True):
copy_template_files(project_name, template_name)
update_cfg(new_cfg, new_cfg_path)
else:
# Initializing into an existing (e.g. ``uv init``ed) folder is allowed;
# only the files we would create can conflict, so confirm before
# overwriting them instead of refusing outright.
conflicts = [
name for name in ("manim.cfg", "main.py") if (project_name / name).exists()
]
if conflicts and not click.confirm(
f"\nFolder [red]{project_name}[/red] already contains "
f"{', '.join(conflicts)}. Overwrite?",
default=False,
):
console.print("\nAborted; existing files were left untouched.\n")
return

project_name.mkdir(parents=True, exist_ok=True)
new_cfg: dict[str, Any] = {}
new_cfg_path = Path.resolve(project_name / "manim.cfg")

if not default_settings:
for key, value in CFG_DEFAULTS.items():
if key == "scene_names":
new_cfg[key] = template_name + "Template"
elif key == "resolution":
new_cfg[key] = select_resolution()
else:
new_cfg[key] = click.prompt(f"\n{key}", default=value)

console.print("\n", new_cfg)
if click.confirm("Do you want to continue?", default=True, abort=True):
copy_template_files(project_name, template_name)
update_cfg(CFG_DEFAULTS, new_cfg_path)
update_cfg(new_cfg, new_cfg_path)
else:
copy_template_files(project_name, template_name)
update_cfg(CFG_DEFAULTS, new_cfg_path)


@cloup.command(
Expand Down
37 changes: 37 additions & 0 deletions tests/interface/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,43 @@ def test_manim_init_project(tmp_path):
assert (Path(tmp_dir) / "testproject/manim.cfg").exists()


def test_manim_init_project_existing_folder(tmp_path):
command = ["init", "project", "--default", "."]
runner = CliRunner()
with runner.isolated_filesystem(temp_dir=tmp_path) as tmp_dir:
# A pre-existing, non-conflicting folder should be usable.
(Path(tmp_dir) / "pyproject.toml").write_text("")
result = runner.invoke(main, command, prog_name="manim", input="Default\n")
assert not result.exception
assert (Path(tmp_dir) / "main.py").exists()
assert (Path(tmp_dir) / "manim.cfg").exists()


def test_manim_init_project_conflicting_files_declined(tmp_path):
command = ["init", "project", "--default", "."]
runner = CliRunner()
with runner.isolated_filesystem(temp_dir=tmp_path) as tmp_dir:
# Declining the overwrite prompt must leave the conflicting file intact.
(Path(tmp_dir) / "main.py").write_text("# keep me\n")
result = runner.invoke(main, command, prog_name="manim", input="Default\nn\n")
assert not result.exception
assert "already contains" in result.output
assert (Path(tmp_dir) / "main.py").read_text() == "# keep me\n"
assert not (Path(tmp_dir) / "manim.cfg").exists()


def test_manim_init_project_conflicting_files_overwritten(tmp_path):
command = ["init", "project", "--default", "."]
runner = CliRunner()
with runner.isolated_filesystem(temp_dir=tmp_path) as tmp_dir:
# Confirming the overwrite prompt replaces the conflicting file.
(Path(tmp_dir) / "main.py").write_text("# keep me\n")
result = runner.invoke(main, command, prog_name="manim", input="Default\ny\n")
assert not result.exception
assert (Path(tmp_dir) / "main.py").read_text() != "# keep me\n"
assert (Path(tmp_dir) / "manim.cfg").exists()


def test_manim_init_scene(tmp_path):
command_named = ["init", "scene", "NamedFileTestScene", "my_awesome_file.py"]
command_unnamed = ["init", "scene", "DefaultFileTestScene"]
Expand Down
Loading