use std::borrow::Cow;
use std::io::IsTerminal;
use clap::ColorChoice;
use diffy::PatchFormatter;
use mago_database::change::ChangeLog;
use mago_database::file::File;
use mago_linter::integration::IntegrationSet;
use mago_linter::settings::RulesSettings;
use mago_linter::settings::Settings;
use mago_orchestrator::Orchestrator;
use mago_orchestrator::OrchestratorConfiguration;
use crate::config::Configuration;
use crate::error::Error;
pub mod git;
pub mod logger;
pub mod progress;
pub mod version;
#[inline]
pub fn should_use_colors(color_choice: ColorChoice) -> bool {
match color_choice {
ColorChoice::Always => true,
ColorChoice::Never => false,
ColorChoice::Auto => {
if let Some(force_color) = std::env::var_os("FORCE_COLOR")
&& !force_color.is_empty()
{
return force_color != "0";
}
if std::env::var_os("NO_COLOR").is_some_and(|value| !value.is_empty()) {
return false;
}
std::io::stdout().is_terminal()
}
}
}
#[inline]
pub fn configure_colors(color_choice: ColorChoice) {
let use_colors = should_use_colors(color_choice);
colored::control::set_override(use_colors);
}
pub(crate) fn create_orchestrator<'a>(
configuration: &'a Configuration,
color_choice: ColorChoice,
pedantic_linter: bool,
use_progress_bars: bool,
enable_diff: bool,
) -> Orchestrator<'a> {
let glob = configuration.source.glob.to_database_settings();
let linter_settings = if pedantic_linter {
Settings {
php_version: configuration.php_version,
integrations: IntegrationSet::all(),
rules: RulesSettings::default(),
glob,
}
} else {
Settings {
php_version: configuration.php_version,
integrations: IntegrationSet::from_slice(&configuration.linter.integrations),
rules: configuration.linter.rules.clone(),
glob,
}
};
let orchestrator_config = OrchestratorConfiguration {
php_version: configuration.php_version,
parser_settings: configuration.parser.to_settings(),
analyzer_settings: configuration.analyzer.to_settings(configuration.php_version, color_choice, enable_diff),
linter_settings,
guard_settings: configuration.guard.settings.clone(),
formatter_settings: configuration.formatter.settings,
disable_default_analyzer_plugins: configuration.analyzer.disable_default_plugins,
analyzer_plugins: configuration.analyzer.plugins.clone(),
use_progress_bars,
use_colors: should_use_colors(color_choice),
paths: configuration.source.paths.clone(),
excludes: configuration.source.excludes.iter().map(|p| p.as_ref()).collect(),
extensions: configuration.source.extensions.iter().map(|e| e.as_ref()).collect(),
includes: configuration.source.includes.clone(),
glob,
};
Orchestrator::new(orchestrator_config)
}
pub fn apply_update(
change_log: &ChangeLog,
file: &File,
modified_contents: &str,
dry_run: bool,
color_choice: ColorChoice,
) -> Result<bool, Error> {
if file.contents == modified_contents {
return Ok(false);
}
if dry_run {
let patch = diffy::create_patch(&file.contents, modified_contents);
let mut formatter = PatchFormatter::new();
if should_use_colors(color_choice) {
formatter = formatter.with_color();
};
println!("diff of '{}':", file.name);
println!("{}", formatter.fmt_patch(&patch));
} else {
change_log.update(file.id, Cow::Owned(modified_contents.to_owned()))?;
}
Ok(true)
}