use anyhow::Result;
use log::error;
use snafu::ensure;
pub mod cli;
mod editorconfig;
mod files;
#[cfg(test)]
pub(crate) mod test_utils;
use cli::{CommandArgs, LibCommands};
use editorconfig::status_types::{ConsideredFiles, EditorConfigFiles, StatusInfo, StatusTexts};
pub use crate::editorconfig::errors;
pub use crate::editorconfig::status_types;
pub fn execute(cmd: &LibCommands) -> Result<()> {
match cmd {
LibCommands::Check(args) => check(args),
LibCommands::Fix(args) => fix(args),
LibCommands::Status(args) => status(args).map(|s| {
if let Some(log_level) = args.verbosity().log_level() {
if log_level < log::Level::Warn {
s.print_short_text();
} else {
s.print_long_text();
}
}
}),
}
}
pub fn check(args: &CommandArgs) -> Result<()> {
let mut errors = Vec::new();
let targets = &args.targets()?;
for entry in files::get_target_files(targets, &args.ignore_args) {
let path = entry?;
if let Err(e) = editorconfig::check_file(&path, &args.editorconfig_args) {
let check_error = errors::CheckSnafu {
path,
error_type: e.downcast::<editorconfig::errors::CheckErrorType>()?,
}
.build();
error!("{check_error}");
errors.push(errors::EditorConfigError::FileError(check_error));
}
}
let config_handlers = editorconfig::build_config_handlers(&args.editorconfig_args);
if !config_handlers.is_empty() {
for entry in files::get_editorconfig_files(targets, &args.ignore_args) {
let mut config = entry?;
let mut section: usize = 0;
while !config.reader.has_more() {
let properties = config.reader.read_section()?.into_props();
if let Err(e) = editorconfig::check_properties(
&properties,
&config.path,
section,
&config_handlers,
) {
let check_config_error = errors::CheckConfigSnafu {
path: &config.path,
section,
error_type: e.downcast::<editorconfig::errors::CheckConfigErrorType>()?,
}
.build();
error!("{check_config_error}");
errors.push(errors::EditorConfigError::ConfigError(check_config_error));
}
section += 1;
}
}
}
ensure!(
errors.is_empty(),
editorconfig::errors::CheckErrorListSnafu { errors }
);
Ok(())
}
pub fn fix(args: &CommandArgs) -> Result<()> {
for entry in files::get_target_files(&args.targets()?, &args.ignore_args) {
editorconfig::fix_file(&entry?, &args.editorconfig_args)?
}
Ok(())
}
pub fn status<'a>(args: &'a CommandArgs) -> Result<StatusInfo<'a>> {
let targets = &args.targets()?;
let configs = files::get_editorconfig_files(targets, &args.ignore_args);
let editorconfig_files = EditorConfigFiles::build(configs)?;
let considered_files = ConsideredFiles::build(
files::get_target_files(targets, &args.ignore_args),
&args.editorconfig_args,
)?;
Ok(StatusInfo {
editorconfig_files,
considered_files,
})
}