diff --git a/lib/cli/src/crewai_cli/create_crew.py b/lib/cli/src/crewai_cli/create_crew.py index d7c33bd62..549fc023e 100644 --- a/lib/cli/src/crewai_cli/create_crew.py +++ b/lib/cli/src/crewai_cli/create_crew.py @@ -6,6 +6,7 @@ import click import tomli from crewai_cli.constants import ENV_VARS, MODELS +from crewai_cli.git import initialize_if_git_available from crewai_cli.provider import ( get_provider_data, select_model, @@ -318,4 +319,7 @@ def create_crew( dst_file = src_folder / file_name copy_template(src_file, dst_file, name, class_name, folder_name) + if not parent_folder: + initialize_if_git_available(folder_path) + click.secho(f"Crew {name} created successfully!", fg="green", bold=True) diff --git a/lib/cli/src/crewai_cli/create_flow.py b/lib/cli/src/crewai_cli/create_flow.py index 24fee7af5..678228f65 100644 --- a/lib/cli/src/crewai_cli/create_flow.py +++ b/lib/cli/src/crewai_cli/create_flow.py @@ -4,6 +4,7 @@ import shutil import click from crewai_core.telemetry import Telemetry +from crewai_cli.git import initialize_if_git_available from crewai_cli.version import get_crewai_tools_dependency @@ -30,6 +31,8 @@ def create_flow(name: str, *, declarative: bool = False) -> None: else: _create_python_flow(name, class_name, folder_name, project_root) + initialize_if_git_available(project_root) + click.secho(f"Flow {name} created successfully!", fg="green", bold=True) diff --git a/lib/cli/src/crewai_cli/create_json_crew.py b/lib/cli/src/crewai_cli/create_json_crew.py index 61a29b874..3e4a7bbfe 100644 --- a/lib/cli/src/crewai_cli/create_json_crew.py +++ b/lib/cli/src/crewai_cli/create_json_crew.py @@ -13,6 +13,7 @@ from rich.console import Console from rich.text import Text from crewai_cli.constants import ENV_VARS +from crewai_cli.git import initialize_if_git_available from crewai_cli.tui_picker import pick_many, pick_one from crewai_cli.utils import ( enable_prompt_line_editing, @@ -955,6 +956,8 @@ def create_json_crew( for model in models: _setup_env(folder_path, model) + initialize_if_git_available(folder_path) + click.echo() click.secho(f" ✔ Crew {name} created successfully!", fg="green", bold=True) click.echo() diff --git a/lib/cli/src/crewai_cli/git.py b/lib/cli/src/crewai_cli/git.py index 6961313e5..bc320eb78 100644 --- a/lib/cli/src/crewai_cli/git.py +++ b/lib/cli/src/crewai_cli/git.py @@ -201,3 +201,12 @@ class Repository: return result.stdout.strip() except subprocess.CalledProcessError: return None + + +def initialize_if_git_available(path: Path) -> bool: + """Initialize a Git repository when Git is available.""" + if not Repository.is_git_installed(): + return False + + subprocess.run(["git", "init"], cwd=path, check=True) # noqa: S607 + return True diff --git a/lib/cli/tests/test_create_crew.py b/lib/cli/tests/test_create_crew.py index d9ed7a24b..cb2a4820b 100644 --- a/lib/cli/tests/test_create_crew.py +++ b/lib/cli/tests/test_create_crew.py @@ -11,6 +11,7 @@ from packaging.requirements import Requirement from packaging.version import Version import crewai_cli.create_json_crew as json_crew import crewai_cli.tui_picker as tui_picker +from crewai_cli.cli import crewai from crewai_cli.create_crew import create_crew, create_folder_structure from crewai_cli.utils import render_template from crewai_cli.version import get_crewai_tools_dependency @@ -109,6 +110,7 @@ def test_create_crew_with_trailing_slash_creates_valid_project( "crewai_cli.create_crew.create_folder_structure" ) as mock_create_folder: mock_folder_path = Path(work_dir) / "test_project" + mock_folder_path.mkdir() mock_create_folder.return_value = ( mock_folder_path, "test_project", @@ -143,6 +145,7 @@ def test_create_crew_with_multiple_trailing_slashes( "crewai_cli.create_crew.create_folder_structure" ) as mock_create_folder: mock_folder_path = Path(work_dir) / "test_project" + mock_folder_path.mkdir() mock_create_folder.return_value = ( mock_folder_path, "test_project", @@ -167,6 +170,7 @@ def test_create_crew_normal_name_still_works( "crewai_cli.create_crew.create_folder_structure" ) as mock_create_folder: mock_folder_path = Path(work_dir) / "normal_project" + mock_folder_path.mkdir() mock_create_folder.return_value = ( mock_folder_path, "normal_project", @@ -178,6 +182,26 @@ def test_create_crew_normal_name_still_works( mock_create_folder.assert_called_once_with("normal-project", None) +@pytest.mark.skipif(shutil.which("git") is None, reason="git is not installed") +@pytest.mark.parametrize( + ("args", "project_root"), + [ + (["create", "crew", "Git Crew"], "git_crew"), + (["create", "flow", "Git Flow"], "git_flow"), + ], +) +def test_create_initializes_git_repo_when_git_is_available( + args, project_root, tmp_path, monkeypatch, runner +): + monkeypatch.chdir(tmp_path) + monkeypatch.setenv("CREWAI_DMN", "True") + + result = runner.invoke(crewai, args) + + assert result.exit_code == 0, result.output + assert (tmp_path / project_root / ".git").is_dir() + + def test_create_folder_structure_handles_spaces_and_dashes_with_slash(): with tempfile.TemporaryDirectory() as temp_dir: folder_path, folder_name, class_name = create_folder_structure(