From 8f3a904e8a6f1fa65241535c86e5325f3f0f45f5 Mon Sep 17 00:00:00 2001 From: Steven Kessler Date: Fri, 15 Nov 2024 11:10:02 -0500 Subject: [PATCH] fix(poetry): was not clearly translating poetry dep groups to uv ones in many circumstances --- src/migrators/poetry.rs | 44 ++++++++++++++++++++++++++--------------- tests/poetry_test.rs | 29 +++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/migrators/poetry.rs b/src/migrators/poetry.rs index 1d93563..22dd7ce 100644 --- a/src/migrators/poetry.rs +++ b/src/migrators/poetry.rs @@ -1,9 +1,9 @@ // In migrators/poetry.rs -use super::{MigrationSource, Dependency, DependencyType}; +use super::{Dependency, DependencyType, MigrationSource}; use crate::types::PyProject; -use std::path::Path; use std::fs; +use std::path::Path; pub struct PoetryMigrationSource; @@ -13,8 +13,13 @@ impl MigrationSource for PoetryMigrationSource { let contents = fs::read_to_string(&pyproject_path) .map_err(|e| format!("Error reading file '{}': {}", pyproject_path.display(), e))?; - let pyproject: PyProject = toml::from_str(&contents) - .map_err(|e| format!("Error parsing TOML in '{}': {}", pyproject_path.display(), e))?; + let pyproject: PyProject = toml::from_str(&contents).map_err(|e| { + format!( + "Error parsing TOML in '{}': {}", + pyproject_path.display(), + e + ) + })?; let mut dependencies = Vec::new(); @@ -23,7 +28,8 @@ impl MigrationSource for PoetryMigrationSource { // Handle main dependencies if let Some(deps) = &poetry.dependencies { for (name, value) in deps { - if let Some(dep) = self.format_dependency(name, value, DependencyType::Main) { + if let Some(dep) = self.format_dependency(name, value, DependencyType::Main) + { dependencies.push(dep); } } @@ -33,13 +39,15 @@ impl MigrationSource for PoetryMigrationSource { if let Some(groups) = &poetry.group { for (group_name, group) in groups { // Determine dependency type based on group name + // Only "dev" group should be converted to DependencyType::Dev let dep_type = match group_name.as_str() { - "dev" | "test" => DependencyType::Dev, - _ => DependencyType::Group(group_name.clone()) + "dev" => DependencyType::Dev, + _ => DependencyType::Group(group_name.clone()), }; for (name, value) in &group.dependencies { - if let Some(dep) = self.format_dependency(name, value, dep_type.clone()) { + if let Some(dep) = self.format_dependency(name, value, dep_type.clone()) + { dependencies.push(dep); } } @@ -53,7 +61,12 @@ impl MigrationSource for PoetryMigrationSource { } impl PoetryMigrationSource { - fn format_dependency(&self, name: &str, value: &toml::Value, dep_type: DependencyType) -> Option { + fn format_dependency( + &self, + name: &str, + value: &toml::Value, + dep_type: DependencyType, + ) -> Option { if name == "python" { return None; } @@ -66,13 +79,12 @@ impl PoetryMigrationSource { } else { Some(v.to_string()) } - }, - toml::Value::Table(t) => { - t.get("version") - .and_then(|v| v.as_str()) - .map(|v| v.trim().to_string()) - .filter(|v| v != "*") } + toml::Value::Table(t) => t + .get("version") + .and_then(|v| v.as_str()) + .map(|v| v.trim().to_string()) + .filter(|v| v != "*"), _ => None, }; @@ -83,4 +95,4 @@ impl PoetryMigrationSource { environment_markers: None, }) } -} \ No newline at end of file +} diff --git a/tests/poetry_test.rs b/tests/poetry_test.rs index 15bdd24..a900c5b 100644 --- a/tests/poetry_test.rs +++ b/tests/poetry_test.rs @@ -261,17 +261,42 @@ python = "^3.11" [tool.poetry.group.test.dependencies] blue = ">=0.9.1" +pytest = "^8.0.0" +pytest-cov = "^4.1.0" "#; let (_temp_dir, project_dir) = create_test_project(content); let source = PoetryMigrationSource; let dependencies = source.extract_dependencies(&project_dir).unwrap(); - assert_eq!(dependencies.len(), 1); + // Should have all test dependencies (excluding python) + assert_eq!(dependencies.len(), 3, "Should have three test dependencies"); + + // Verify each dependency is in the test group + for dep in &dependencies { + match &dep.dep_type { + DependencyType::Group(name) => { + assert_eq!(name, "test", "Group name should be 'test'"); + } + other => panic!("Expected Group(\"test\"), got {:?}", other), + } + } + // Check specific dependency details let blue_dep = dependencies.iter().find(|d| d.name == "blue").unwrap(); assert_eq!(blue_dep.version, Some(">=0.9.1".to_string())); - assert_eq!(blue_dep.dep_type, DependencyType::Dev); // All group dependencies should be marked as Dev + assert!(matches!(blue_dep.dep_type, DependencyType::Group(ref name) if name == "test")); + + let pytest_dep = dependencies.iter().find(|d| d.name == "pytest").unwrap(); + assert_eq!(pytest_dep.version, Some("^8.0.0".to_string())); + assert!(matches!(pytest_dep.dep_type, DependencyType::Group(ref name) if name == "test")); + + let pytest_cov_dep = dependencies + .iter() + .find(|d| d.name == "pytest-cov") + .unwrap(); + assert_eq!(pytest_cov_dep.version, Some("^4.1.0".to_string())); + assert!(matches!(pytest_cov_dep.dep_type, DependencyType::Group(ref name) if name == "test")); } #[cfg(test)]