use super::read_file;
use crate::error::CliError;
use colored::Colorize;
use hedl_core::parse;
use hedl_lint::{lint_with_config, LintConfig, Severity};
pub fn lint(file: &str, format: &str, warn_error: bool) -> Result<(), CliError> {
let content = read_file(file)?;
let doc =
parse(content.as_bytes()).map_err(|e| CliError::parse(format!("Parse error: {e}")))?;
let config = LintConfig::default();
let diagnostics = lint_with_config(&doc, config);
match format {
"json" => {
let json = serde_json::json!({
"file": file,
"diagnostics": diagnostics.iter().map(|d| {
serde_json::json!({
"severity": format!("{:?}", d.severity()),
"rule": d.rule_id(),
"message": d.message(),
"line": d.line(),
"suggestion": d.suggestion()
})
}).collect::<Vec<_>>()
});
let output = serde_json::to_string_pretty(&json)
.map_err(|e| CliError::json_conversion(format!("JSON serialization error: {e}")))?;
println!("{output}");
}
_ => {
if diagnostics.is_empty() {
println!("{} {} - no issues found", "✓".green().bold(), file);
} else {
println!(
"{} {} - {} issue(s) found:",
"!".yellow().bold(),
file,
diagnostics.len()
);
for diag in &diagnostics {
let severity_str = match diag.severity() {
Severity::Error => "error".red(),
Severity::Warning => "warning".yellow(),
Severity::Hint => "hint".blue(),
};
if let Some(line) = diag.line() {
println!(" {}:{}: {}: {}", file, line, severity_str, diag.message());
} else {
println!(" {}: {}: {}", file, severity_str, diag.message());
}
if let Some(suggestion) = diag.suggestion() {
println!(" {} {}", "suggestion:".cyan(), &suggestion);
}
}
}
}
}
let has_errors = diagnostics.iter().any(|d| d.severity() == Severity::Error);
let has_warnings = diagnostics
.iter()
.any(|d| d.severity() == Severity::Warning);
if has_errors || (warn_error && has_warnings) {
Err(CliError::LintErrors)
} else {
Ok(())
}
}