mirror of
https://github.com/crewAIInc/crewAI.git
synced 2025-12-26 17:28:29 +00:00
Compare commits
4 Commits
bugfix-pyt
...
devin/1741
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4480bc694 | ||
|
|
a7d7edb983 | ||
|
|
64b8708bae | ||
|
|
92d420dcc4 |
@@ -1,5 +1,8 @@
|
||||
import logging
|
||||
import subprocess
|
||||
import sys
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import List, Optional
|
||||
|
||||
import click
|
||||
@@ -8,6 +11,8 @@ from packaging import version
|
||||
from crewai.cli.utils import read_toml
|
||||
from crewai.cli.version import get_crewai_version
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CrewType(Enum):
|
||||
STANDARD = "standard"
|
||||
@@ -48,12 +53,31 @@ def run_crew() -> None:
|
||||
|
||||
|
||||
def execute_command(crew_type: CrewType) -> None:
|
||||
"""
|
||||
Execute the appropriate command based on crew type.
|
||||
"""Execute the appropriate command based on crew type.
|
||||
|
||||
Args:
|
||||
crew_type: The type of crew to run
|
||||
|
||||
Note:
|
||||
Automatically adds the 'src' directory to sys.path if it exists
|
||||
to ensure proper module resolution.
|
||||
"""
|
||||
# Add the 'src' directory to sys.path to ensure module imports work correctly
|
||||
cwd = Path.cwd()
|
||||
src_path = cwd / "src"
|
||||
|
||||
logger.debug(f"Current working directory: {cwd}")
|
||||
|
||||
if src_path.exists() and str(src_path) not in sys.path:
|
||||
logger.info(f"Adding {src_path} to sys.path")
|
||||
sys.path.insert(0, str(src_path))
|
||||
elif not src_path.exists():
|
||||
logger.warning(f"src directory not found: {src_path}")
|
||||
click.secho(
|
||||
f"Warning: 'src' directory not found at {src_path}. Module imports may fail.",
|
||||
fg="yellow",
|
||||
)
|
||||
|
||||
command = ["uv", "run", "kickoff" if crew_type == CrewType.FLOW else "run_crew"]
|
||||
|
||||
try:
|
||||
@@ -63,6 +87,7 @@ def execute_command(crew_type: CrewType) -> None:
|
||||
handle_error(e, crew_type)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Unexpected error: {e}")
|
||||
click.echo(f"An unexpected error occurred: {e}", err=True)
|
||||
|
||||
|
||||
|
||||
48
tests/cli/test_run_crew.py
Normal file
48
tests/cli/test_run_crew.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from crewai.cli.run_crew import CrewType, execute_command
|
||||
|
||||
|
||||
def test_execute_command_adds_src_to_path():
|
||||
"""
|
||||
Test that execute_command correctly modifies sys.path.
|
||||
|
||||
Ensures:
|
||||
1. src directory is added to sys.path when it exists.
|
||||
2. Original sys.path is preserved for other entries.
|
||||
3. Command execution proceeds correctly.
|
||||
"""
|
||||
# Create a temporary directory with a src subdirectory
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
src_path = temp_path / "src"
|
||||
src_path.mkdir()
|
||||
|
||||
# Change to the temporary directory
|
||||
original_dir = os.getcwd()
|
||||
os.chdir(temp_dir)
|
||||
|
||||
try:
|
||||
# Save the original sys.path
|
||||
original_sys_path = sys.path.copy()
|
||||
|
||||
# Mock subprocess.run to avoid actually running the command
|
||||
with patch("subprocess.run") as mock_run:
|
||||
# Call execute_command
|
||||
execute_command(CrewType.STANDARD)
|
||||
|
||||
# Check that src_path was added to sys.path
|
||||
assert str(src_path) in sys.path
|
||||
|
||||
# Check that the command was called
|
||||
mock_run.assert_called_once()
|
||||
finally:
|
||||
# Restore the original directory and sys.path
|
||||
os.chdir(original_dir)
|
||||
sys.path = original_sys_path
|
||||
115
tests/cli/test_run_crew_edge_cases.py
Normal file
115
tests/cli/test_run_crew_edge_cases.py
Normal file
@@ -0,0 +1,115 @@
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from crewai.cli.run_crew import CrewType, execute_command
|
||||
|
||||
|
||||
@pytest.mark.parametrize("crew_type", [CrewType.STANDARD, CrewType.FLOW])
|
||||
def test_execute_command_with_different_crew_types(crew_type):
|
||||
"""
|
||||
Test that execute_command works with different crew types.
|
||||
|
||||
Verifies that the correct command is executed based on the crew type.
|
||||
"""
|
||||
# Create a temporary directory with a src subdirectory
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
src_path = temp_path / "src"
|
||||
src_path.mkdir()
|
||||
|
||||
# Change to the temporary directory
|
||||
original_dir = os.getcwd()
|
||||
os.chdir(temp_dir)
|
||||
|
||||
try:
|
||||
# Save the original sys.path
|
||||
original_sys_path = sys.path.copy()
|
||||
|
||||
# Mock subprocess.run to avoid actually running the command
|
||||
with patch("subprocess.run") as mock_run:
|
||||
# Call execute_command
|
||||
execute_command(crew_type)
|
||||
|
||||
# Check that the correct command was called based on crew_type
|
||||
expected_command = ["uv", "run", "kickoff" if crew_type == CrewType.FLOW else "run_crew"]
|
||||
mock_run.assert_called_once_with(expected_command, capture_output=False, text=True, check=True)
|
||||
finally:
|
||||
# Restore the original directory and sys.path
|
||||
os.chdir(original_dir)
|
||||
sys.path = original_sys_path
|
||||
|
||||
|
||||
def test_execute_command_handles_missing_src_directory():
|
||||
"""
|
||||
Test that execute_command handles missing src directory gracefully.
|
||||
|
||||
Verifies that the command executes even when the src directory doesn't exist.
|
||||
"""
|
||||
# Create a temporary directory without a src subdirectory
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
|
||||
# Change to the temporary directory
|
||||
original_dir = os.getcwd()
|
||||
os.chdir(temp_dir)
|
||||
|
||||
try:
|
||||
# Save the original sys.path
|
||||
original_sys_path = sys.path.copy()
|
||||
|
||||
# Mock subprocess.run to avoid actually running the command
|
||||
with patch("subprocess.run") as mock_run:
|
||||
# Call execute_command
|
||||
execute_command(CrewType.STANDARD)
|
||||
|
||||
# Check that sys.path wasn't modified (since src doesn't exist)
|
||||
assert sys.path == original_sys_path
|
||||
|
||||
# Check that the command was still called
|
||||
mock_run.assert_called_once_with(["uv", "run", "run_crew"], capture_output=False, text=True, check=True)
|
||||
finally:
|
||||
# Restore the original directory and sys.path
|
||||
os.chdir(original_dir)
|
||||
sys.path = original_sys_path
|
||||
|
||||
|
||||
def test_execute_command_handles_subprocess_error():
|
||||
"""
|
||||
Test that execute_command properly handles subprocess errors.
|
||||
|
||||
Verifies that exceptions from subprocess.run are propagated correctly.
|
||||
"""
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
src_path = temp_path / "src"
|
||||
src_path.mkdir()
|
||||
|
||||
# Create a dummy pyproject.toml file
|
||||
with open(temp_path / "pyproject.toml", "w") as f:
|
||||
f.write("[project]\nname = \"test\"\n")
|
||||
|
||||
# Change to the temporary directory
|
||||
original_dir = os.getcwd()
|
||||
os.chdir(temp_dir)
|
||||
|
||||
try:
|
||||
# Save the original sys.path
|
||||
original_sys_path = sys.path.copy()
|
||||
|
||||
# Mock subprocess.run to raise an exception
|
||||
with patch("subprocess.run", side_effect=subprocess.CalledProcessError(1, [])):
|
||||
# Call execute_command and verify it handles the error
|
||||
execute_command(CrewType.STANDARD)
|
||||
|
||||
# Verify that sys.path was modified correctly
|
||||
assert str(src_path) in sys.path
|
||||
finally:
|
||||
# Restore the original directory and sys.path
|
||||
os.chdir(original_dir)
|
||||
sys.path = original_sys_path
|
||||
Reference in New Issue
Block a user