use anyhow::Result;
use std::path::Path;
pub struct GradleMigrator;
impl GradleMigrator {
pub fn migrate(build_gradle_path: &Path) -> Result<MigrationResult> {
if !build_gradle_path.exists() {
return Err(anyhow::anyhow!(
"Gradle build file not found: {}",
build_gradle_path.display()
));
}
let gradle_content = std::fs::read_to_string(build_gradle_path)?;
let config = Self::generate_jbuild_config(&gradle_content)?;
Ok(MigrationResult {
config,
warnings: vec!["Gradle migration is experimental".to_string()],
notes: vec![
"Review and adjust dependencies".to_string(),
"Convert custom Gradle tasks to jbuild goals".to_string(),
],
})
}
fn generate_jbuild_config(gradle: &str) -> Result<String> {
let mut config = String::from("# Generated by jbuild Gradle migrator\n\n");
config.push_str("[package]\n");
config.push_str("name = \"project-name\"\n");
config.push_str("version = \"1.0.0\"\n\n");
for line in gradle.lines() {
if line.contains("implementation") || line.contains("testImplementation") {
if let Some(dep) = Self::extract_dependency(line) {
config.push_str(&dep);
config.push('\n');
}
}
}
Ok(config)
}
fn extract_dependency(line: &str) -> Option<String> {
let line = line.trim();
if !line.starts_with("implementation ") && !line.starts_with("testImplementation ") {
return None;
}
let dep_str = line
.trim_start_matches("implementation ")
.trim_start_matches("testImplementation ")
.trim()
.trim_matches('\'')
.trim_matches('"');
let parts: Vec<&str> = dep_str.split(':').collect();
if parts.len() >= 3 {
Some(format!(
r#"{{ group = "{}", artifact = "{}", version = "{}" }}"#,
parts[0], parts[1], parts[2]
))
} else {
None
}
}
}
#[derive(Debug, Clone)]
pub struct MigrationResult {
pub config: String,
pub warnings: Vec<String>,
pub notes: Vec<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_extract_dependency() {
let line = "implementation 'org.junit.jupiter:junit-jupiter:5.10.0'";
let result = GradleMigrator::extract_dependency(line);
assert!(result.is_some());
assert!(result.unwrap().contains("org.junit.jupiter"));
}
}