#[allow(clippy::too_many_arguments)]
async fn setup_refactoring_context(
project_path: PathBuf,
single_file_mode: bool,
file: Option<PathBuf>,
format: RefactorAutoOutputFormat,
max_iterations: u32,
dry_run: bool,
exclude_patterns: Vec<String>,
include_patterns: Vec<String>,
ignore_file: Option<PathBuf>,
github_issue_url: Option<String>,
bug_report_path: Option<PathBuf>,
) -> Result<RefactorContext> {
let start_time = std::time::Instant::now();
let mode = if let Some(bug_path) = bug_report_path {
RefactorMode::BugReport(bug_path)
} else if let Some(github_url) = github_issue_url {
RefactorMode::GitHubIssue(github_url)
} else if single_file_mode || file.is_some() {
if let Some(target_file) = file {
RefactorMode::SingleFile(target_file)
} else {
return Err(anyhow::anyhow!(
"Single file mode requires --file parameter"
));
}
} else {
RefactorMode::ProjectWide
};
let config = RefactorConfig {
project_path: project_path.clone(),
mode,
quality_profile: QualityProfile::default(),
patterns: PatternConfig {
root_path: project_path,
ignore_file: ignore_file
.as_ref()
.and_then(|p| p.file_name().map(|n| n.to_string_lossy().to_string())),
patterns: vec![],
include_patterns,
exclude_patterns,
ignore_file_path: ignore_file,
file_extensions: vec!["rs".to_string(), "toml".to_string()],
},
output: OutputConfig {
format,
dry_run,
max_iterations,
verbose: false,
},
};
Ok(RefactorContext {
config,
ignore_patterns: vec![], source_files: vec![], start_time,
})
}
async fn load_ignore_patterns(config: &PatternConfig) -> Result<Vec<String>> {
let mut all_patterns = config.exclude_patterns.clone();
if let Some(ignore_path) = &config.ignore_file_path {
if ignore_path.exists() {
let ignore_content = tokio::fs::read_to_string(ignore_path)
.await
.context(format!(
"Failed to read ignore file: {}",
ignore_path.display()
))?;
for line in ignore_content.lines() {
let trimmed = line.trim();
if !trimmed.is_empty() && !trimmed.starts_with('#') {
all_patterns.push(trimmed.to_string());
}
}
}
}
Ok(all_patterns)
}
async fn discover_source_files(
project_path: &Path,
patterns: &PatternConfig,
ignore_patterns: &[String],
) -> Result<Vec<PathBuf>> {
let mut source_files = Vec::new();
for entry in WalkDir::new(project_path)
.follow_links(false)
.into_iter()
.filter_map(std::result::Result::ok)
.filter(|e| e.file_type().is_file())
{
let path = entry.path();
if let Some(ext) = path.extension().and_then(|e| e.to_str()) {
if !patterns.file_extensions.contains(&ext.to_string()) {
continue;
}
} else {
continue;
}
let path_str = path.to_string_lossy();
let should_ignore = ignore_patterns
.iter()
.any(|pattern| path_str.contains(pattern) || path.to_string_lossy().contains(pattern));
if !should_ignore {
source_files.push(path.to_path_buf());
}
}
source_files.sort();
Ok(source_files)
}