diff --git a/lib/devtools/src/crewai_devtools/cli.py b/lib/devtools/src/crewai_devtools/cli.py index 785f943c7..c155026d9 100644 --- a/lib/devtools/src/crewai_devtools/cli.py +++ b/lib/devtools/src/crewai_devtools/cli.py @@ -514,6 +514,10 @@ def _pin_crewai_deps(content: str, version: str) -> str: def update_template_dependencies(templates_dir: Path, new_version: str) -> list[Path]: """Update crewai dependency versions in CLI template pyproject.toml files. + Uses simple string replacement instead of TOML parsing because + template files contain Jinja placeholders (``{{folder_name}}``) + that are not valid TOML. + Args: templates_dir: Path to the CLI templates directory. new_version: New version string. @@ -521,10 +525,13 @@ def update_template_dependencies(templates_dir: Path, new_version: str) -> list[ Returns: List of paths that were updated. """ + import re + + pattern = re.compile(r"(crewai(?:\[[\w,]+\])?)(?:==|>=)[^\s\"']+") updated = [] for pyproject in templates_dir.rglob("pyproject.toml"): content = pyproject.read_text() - new_content = _pin_crewai_deps(content, new_version) + new_content = pattern.sub(rf"\1=={new_version}", content) if new_content != content: pyproject.write_text(new_content) updated.append(pyproject) diff --git a/lib/devtools/tests/test_toml_updates.py b/lib/devtools/tests/test_toml_updates.py index eb93dd235..0a47283a9 100644 --- a/lib/devtools/tests/test_toml_updates.py +++ b/lib/devtools/tests/test_toml_updates.py @@ -7,6 +7,7 @@ from crewai_devtools.cli import ( _pin_crewai_deps, _repin_crewai_install, update_pyproject_version, + update_template_dependencies, ) @@ -223,3 +224,51 @@ class TestRepinCrewaiInstall: def test_no_version_specifier_unchanged(self) -> None: cmd = 'pip install "crewai[tools]>=1.0"' assert _repin_crewai_install(cmd, "2.0.0") == cmd + + +# --- update_template_dependencies --- + + +class TestUpdateTemplateDependencies: + def test_updates_jinja_template(self, tmp_path: Path) -> None: + """Template pyproject.toml files with Jinja placeholders should not break.""" + tpl = tmp_path / "crew" / "pyproject.toml" + tpl.parent.mkdir() + tpl.write_text( + dedent("""\ + [project] + name = "{{folder_name}}" + version = "0.1.0" + dependencies = [ + "crewai[tools]==1.14.0" + ] + + [project.scripts] + {{folder_name}} = "{{folder_name}}.main:run" + """) + ) + + updated = update_template_dependencies(tmp_path, "2.0.0") + + assert len(updated) == 1 + content = tpl.read_text() + assert '"crewai[tools]==2.0.0"' in content + assert "{{folder_name}}" in content + + def test_updates_bare_crewai(self, tmp_path: Path) -> None: + tpl = tmp_path / "pyproject.toml" + tpl.write_text('dependencies = [\n "crewai==1.0.0"\n]\n') + + updated = update_template_dependencies(tmp_path, "3.0.0") + + assert len(updated) == 1 + assert '"crewai==3.0.0"' in tpl.read_text() + + def test_skips_unrelated_deps(self, tmp_path: Path) -> None: + tpl = tmp_path / "pyproject.toml" + tpl.write_text('dependencies = [\n "requests>=2.0"\n]\n') + + updated = update_template_dependencies(tmp_path, "2.0.0") + + assert len(updated) == 0 + assert '"requests>=2.0"' in tpl.read_text()