diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-06 03:38:32 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-06 04:05:13 +0900 |
| commit | bf96f8292c0e9818c8b5fc8713ca7506e4338a49 (patch) | |
| tree | 61ddecc119ee0ae344eabdb9c0f784cdb3461a44 /crates/mozart | |
| parent | b97e34358be5df05a3db9f5f3ef1502eaa94b1c0 (diff) | |
| download | php-mozart-bf96f8292c0e9818c8b5fc8713ca7506e4338a49.tar.gz php-mozart-bf96f8292c0e9818c8b5fc8713ca7506e4338a49.tar.zst php-mozart-bf96f8292c0e9818c8b5fc8713ca7506e4338a49.zip | |
refactor(console): add write macros and migrate commands to use them
Diffstat (limited to 'crates/mozart')
24 files changed, 398 insertions, 466 deletions
diff --git a/crates/mozart/src/commands/about.rs b/crates/mozart/src/commands/about.rs index a8566d1..1dd6b85 100644 --- a/crates/mozart/src/commands/about.rs +++ b/crates/mozart/src/commands/about.rs @@ -2,6 +2,7 @@ use clap::Args; use mozart_core::MOZART_VERSION; use mozart_core::console; use mozart_core::console_format; +use mozart_core::console_writeln; #[derive(Args)] pub struct AboutArgs {} @@ -11,16 +12,13 @@ pub async fn execute( _cli: &super::Cli, console: &console::Console, ) -> anyhow::Result<()> { - console.write_stdout( + console_writeln!( + console, &console_format!( - "<info>Mozart - Dependency Manager for PHP - version {MOZART_VERSION}</info>", + r#"<info>Mozart - Dependency Manager for PHP - version {MOZART_VERSION}</info> +<comment>Mozart is a dependency manager tracking local dependencies of your projects and libraries. +See https://getcomposer.org/ for more information.</comment>"# ), - console::Verbosity::Normal, - ); - console.write_stdout( - &console_format!("<comment>Mozart is a dependency manager tracking local dependencies of your projects and libraries. -See https://getcomposer.org/ for more information.</comment>"), - console::Verbosity::Normal, ); Ok(()) } diff --git a/crates/mozart/src/commands/archive.rs b/crates/mozart/src/commands/archive.rs index 4386e16..044178f 100644 --- a/crates/mozart/src/commands/archive.rs +++ b/crates/mozart/src/commands/archive.rs @@ -1,5 +1,5 @@ use clap::Args; -use mozart_core::console::Verbosity; +use mozart_core::console_writeln; use std::path::PathBuf; #[derive(Args)] @@ -233,7 +233,7 @@ pub async fn execute( } else { target_path.display().to_string() }; - console.write_stdout(&format!("Created: {}", display_path), Verbosity::Normal); + console_writeln!(console, &format!("Created: {}", display_path),); Ok(()) } diff --git a/crates/mozart/src/commands/audit.rs b/crates/mozart/src/commands/audit.rs index a1b4e4a..f9da344 100644 --- a/crates/mozart/src/commands/audit.rs +++ b/crates/mozart/src/commands/audit.rs @@ -1,10 +1,10 @@ use clap::Args; +use mozart_core::console_writeln; +use mozart_core::console_writeln_error; +use mozart_registry::packagist::SecurityAdvisory; use std::collections::BTreeMap; use std::path::Path; -use mozart_core::console::Verbosity; -use mozart_registry::packagist::SecurityAdvisory; - #[derive(Args)] pub struct AuditArgs { /// Disables auditing of require-dev packages @@ -264,12 +264,12 @@ fn filter_advisories( let installed_ver = match mozart_semver::Version::parse(version_str) { Ok(v) => v, Err(_) => { - console.write( + console_writeln_error!( + console, &format!( "Warning: could not parse version \"{}\" for package \"{}\", skipping advisory matching", version_str, pkg.name ), - Verbosity::Normal, ); continue; } @@ -292,12 +292,12 @@ fn filter_advisories( let constraint = match mozart_semver::VersionConstraint::parse(&normalized_constraint) { Ok(c) => c, Err(_) => { - console.write( + console_writeln_error!( + console, &format!( "Warning: could not parse affected versions \"{}\" for advisory \"{}\", skipping", advisory.affected_versions, advisory.advisory_id ), - Verbosity::Normal, ); continue; } @@ -393,11 +393,11 @@ fn render_table(result: &AuditResult, console: &mozart_core::console::Console) { "Found {} security vulnerability {} affecting {} package(s):", result.total_advisory_count, advisory_word, result.affected_package_count ); - console.write( + console_writeln_error!( + console, &format!("{}", mozart_core::console::highlight(&header)), - Verbosity::Normal, ); - console.write("", Verbosity::Normal); + console_writeln_error!(console, ""); for advisories in result.advisories.values() { for matched in advisories { @@ -429,9 +429,10 @@ fn render_table(result: &AuditResult, console: &mozart_core::console::Console) { vw = value_width ); - console.write(&separator, Verbosity::Normal); + console_writeln_error!(console, &separator); for (label, value) in &rows { - console.write( + console_writeln_error!( + console, &format!( "| {:<lw$} | {:<vw$} |", label, @@ -439,22 +440,21 @@ fn render_table(result: &AuditResult, console: &mozart_core::console::Console) { lw = label_width, vw = value_width ), - Verbosity::Normal, ); } - console.write(&separator, Verbosity::Normal); - console.write("", Verbosity::Normal); + console_writeln_error!(console, &separator); + console_writeln_error!(console, ""); } } } if !result.abandoned.is_empty() { let header = format!("Found {} abandoned package(s):", result.abandoned.len()); - console.write( + console_writeln_error!( + console, &format!("{}", mozart_core::console::highlight(&header)), - Verbosity::Normal, ); - console.write("", Verbosity::Normal); + console_writeln_error!(console, ""); let name_width = 20usize; let ver_width = result @@ -477,7 +477,8 @@ fn render_table(result: &AuditResult, console: &mozart_core::console::Console) { .unwrap_or(0) .max("Suggested Replacement".len()); - console.write( + console_writeln_error!( + console, &format!( "| {:<nw$} | {:<vw$} | {:<rw$} |", "Abandoned Package", @@ -487,9 +488,9 @@ fn render_table(result: &AuditResult, console: &mozart_core::console::Console) { vw = ver_width, rw = repl_width ), - Verbosity::Normal, ); - console.write( + console_writeln_error!( + console, &format!( "+-{:-<nw$}-+-{:-<vw$}-+-{:-<rw$}-+", "", @@ -499,14 +500,14 @@ fn render_table(result: &AuditResult, console: &mozart_core::console::Console) { vw = ver_width, rw = repl_width ), - Verbosity::Normal, ); for pkg in &result.abandoned { let replacement = pkg .replacement .as_deref() .unwrap_or("No replacement suggested"); - console.write( + console_writeln_error!( + console, &format!( "| {:<nw$} | {:<vw$} | {:<rw$} |", pkg.name, @@ -516,10 +517,9 @@ fn render_table(result: &AuditResult, console: &mozart_core::console::Console) { vw = ver_width, rw = repl_width ), - Verbosity::Normal, ); } - console.write("", Verbosity::Normal); + console_writeln_error!(console, ""); } } @@ -535,68 +535,59 @@ fn render_plain(result: &AuditResult, console: &mozart_core::console::Console) { } else { "advisories" }; - console.write( + console_writeln_error!( + console, &format!( "Found {} security vulnerability {} affecting {} package(s):", result.total_advisory_count, advisory_word, result.affected_package_count ), - Verbosity::Normal, ); - console.write("", Verbosity::Normal); + console_writeln_error!(console, ""); for advisories in result.advisories.values() { for matched in advisories { let adv = &matched.advisory; - console.write(&format!("Package: {}", adv.package_name), Verbosity::Normal); - console.write( - &format!("Version: {}", matched.installed_version), - Verbosity::Normal, - ); - console.write( + console_writeln_error!(console, &format!("Package: {}", adv.package_name),); + console_writeln_error!(console, &format!("Version: {}", matched.installed_version),); + console_writeln_error!( + console, &format!("Severity: {}", adv.severity.as_deref().unwrap_or("")), - Verbosity::Normal, - ); - console.write( - &format!("Advisory ID: {}", adv.advisory_id), - Verbosity::Normal, ); - console.write( + console_writeln_error!(console, &format!("Advisory ID: {}", adv.advisory_id),); + console_writeln_error!( + console, &format!("CVE: {}", adv.cve.as_deref().unwrap_or("NO CVE")), - Verbosity::Normal, ); - console.write(&format!("Title: {}", adv.title), Verbosity::Normal); - console.write( + console_writeln_error!(console, &format!("Title: {}", adv.title),); + console_writeln_error!( + console, &format!("URL: {}", adv.link.as_deref().unwrap_or("")), - Verbosity::Normal, ); - console.write( + console_writeln_error!( + console, &format!("Affected versions: {}", adv.affected_versions), - Verbosity::Normal, - ); - console.write( - &format!("Reported at: {}", adv.reported_at), - Verbosity::Normal, ); - console.write("--------", Verbosity::Normal); + console_writeln_error!(console, &format!("Reported at: {}", adv.reported_at),); + console_writeln_error!(console, "--------"); } } } for pkg in &result.abandoned { match &pkg.replacement { - Some(repl) => console.write( + Some(repl) => console_writeln_error!( + console, &format!( "{} ({}) is abandoned. Use {} instead.", pkg.name, pkg.version, repl ), - Verbosity::Normal, ), - None => console.write( + None => console_writeln_error!( + console, &format!( "{} ({}) is abandoned. No replacement was suggested.", pkg.name, pkg.version ), - Verbosity::Normal, ), } } @@ -635,7 +626,7 @@ fn render_json( "abandoned": abandoned_map, }); - console.write_stdout(&serde_json::to_string_pretty(&output)?, Verbosity::Normal); + console_writeln!(console, &serde_json::to_string_pretty(&output)?,); Ok(()) } @@ -648,31 +639,31 @@ fn render_summary(result: &AuditResult, console: &mozart_core::console::Console) } else { "advisories" }; - console.write( + console_writeln_error!( + console, &format!( "Found {} security vulnerability {} affecting {} package(s).", result.total_advisory_count, advisory_word, result.affected_package_count ), - Verbosity::Normal, ); console.info("Run \"mozart audit\" for a full list of advisories."); } for pkg in &result.abandoned { match &pkg.replacement { - Some(repl) => console.write( + Some(repl) => console_writeln_error!( + console, &format!( "{} ({}) is abandoned. Use {} instead.", pkg.name, pkg.version, repl ), - Verbosity::Normal, ), - None => console.write( + None => console_writeln_error!( + console, &format!( "{} ({}) is abandoned. No replacement was suggested.", pkg.name, pkg.version ), - Verbosity::Normal, ), } } diff --git a/crates/mozart/src/commands/browse.rs b/crates/mozart/src/commands/browse.rs index 090c412..a977012 100644 --- a/crates/mozart/src/commands/browse.rs +++ b/crates/mozart/src/commands/browse.rs @@ -1,5 +1,6 @@ use clap::Args; use mozart_core::console_format; +use mozart_core::console_writeln; use mozart_core::exit_code; use std::path::Path; use std::process::Command; @@ -49,10 +50,7 @@ pub async fn execute( match resolve_url(package_name, &working_dir, args.homepage, &repo_cache).await? { ResolveResult::Found(url) => { if args.show { - console.write_stdout( - &console_format!("<info>{}</info>", url), - mozart_core::console::Verbosity::Normal, - ); + console_writeln!(console, &console_format!("<info>{}</info>", url),); } else { open_browser(&url, console)?; } diff --git a/crates/mozart/src/commands/bump.rs b/crates/mozart/src/commands/bump.rs index b97b86f..22b251e 100644 --- a/crates/mozart/src/commands/bump.rs +++ b/crates/mozart/src/commands/bump.rs @@ -1,7 +1,7 @@ use clap::Args; use indexmap::IndexMap; -use mozart_core::console::Verbosity; use mozart_core::console_format; +use mozart_core::console_writeln; /// Exit code for stale lock file (matches Composer's BumpCommand::ERROR_LOCK_OUTDATED) const ERROR_LOCK_OUTDATED: i32 = 2; @@ -149,34 +149,34 @@ pub async fn execute( let total_changes = require_changes.len() + require_dev_changes.len(); if total_changes == 0 { - console.write_stdout( + console_writeln!( + console, &console_format!( "<info>No requirements to update in {}.</info>", composer_json_path.display() ), - Verbosity::Normal, ); return Ok(()); } if args.dry_run { - console.write_stdout( + console_writeln!( + console, &console_format!( "<info>{} would be updated with:</info>", composer_json_path.display() ), - Verbosity::Normal, ); for (name, _old, new) in &require_changes { - console.write_stdout( + console_writeln!( + console, &console_format!("<info> - require.{name}: {new}</info>"), - Verbosity::Normal, ); } for (name, _old, new) in &require_dev_changes { - console.write_stdout( + console_writeln!( + console, &console_format!("<info> - require-dev.{name}: {new}</info>"), - Verbosity::Normal, ); } // Return exit code 1 when dry-run detects changes (useful for CI to detect un-bumped constraints) @@ -204,12 +204,12 @@ pub async fn execute( updated_lock.content_hash = new_hash; updated_lock.write_to_file(&lock_path)?; - console.write_stdout( + console_writeln!( + console, &console_format!( "<info>{} has been updated ({total_changes} changes).</info>", composer_json_path.display() ), - Verbosity::Normal, ); Ok(()) diff --git a/crates/mozart/src/commands/check_platform_reqs.rs b/crates/mozart/src/commands/check_platform_reqs.rs index 346d479..e96610e 100644 --- a/crates/mozart/src/commands/check_platform_reqs.rs +++ b/crates/mozart/src/commands/check_platform_reqs.rs @@ -1,5 +1,7 @@ use clap::Args; -use mozart_core::console::{Console, Verbosity}; +use mozart_core::console::Console; +use mozart_core::console_writeln; +use mozart_core::console_writeln_error; use std::collections::BTreeMap; use std::path::Path; @@ -77,9 +79,9 @@ pub async fn execute( if requirements.is_empty() { // No platform requirements to check if format == "json" { - console.write_stdout( + console_writeln!( + console, &serde_json::to_string_pretty(&serde_json::json!([]))?, - Verbosity::Normal, ); } return Ok(()); @@ -139,7 +141,8 @@ fn collect_requirements( let installed = mozart_registry::installed::InstalledPackages::read(&vendor_dir)?; if installed.packages.is_empty() { // Fall through to lock file with a warning - console.write( + console_writeln_error!( + console, &format!( "{}", mozart_core::console::warning(&format!( @@ -147,7 +150,6 @@ fn collect_requirements( dev_text )) ), - mozart_core::console::Verbosity::Normal, ); if !lock_path.exists() { anyhow::bail!( @@ -164,7 +166,8 @@ fn collect_requirements( } } else if lock_path.exists() { // Fallback: read from lock file - console.write( + console_writeln_error!( + console, &format!( "{}", mozart_core::console::warning(&format!( @@ -172,7 +175,6 @@ fn collect_requirements( dev_text )) ), - mozart_core::console::Verbosity::Normal, ); collect_from_lock(&lock_path, args.no_dev, &mut requirements)?; } else { @@ -361,14 +363,14 @@ fn render_text(results: &[CheckResult], console: &Console) { match result.status { CheckStatus::Success => { - console.write_stdout( + console_writeln!( + console, &format!( "{} {} {}", mozart_core::console::info(&padded_name), mozart_core::console::comment(&padded_version), mozart_core::console::info("success"), ), - Verbosity::Normal, ); } CheckStatus::Failed => { @@ -377,7 +379,8 @@ fn render_text(results: &[CheckResult], console: &Console) { .as_ref() .map(|(c, p)| (c.as_str(), p.as_str())) .unwrap_or(("", "")); - console.write_stdout( + console_writeln!( + console, &format!( "{} {} {} requires {} ({})", mozart_core::console::comment(&padded_name), @@ -386,7 +389,6 @@ fn render_text(results: &[CheckResult], console: &Console) { provider, constraint, ), - Verbosity::Normal, ); } CheckStatus::Missing => { @@ -395,7 +397,8 @@ fn render_text(results: &[CheckResult], console: &Console) { .as_ref() .map(|(c, p)| (c.as_str(), p.as_str())) .unwrap_or(("*", "")); - console.write_stdout( + console_writeln!( + console, &format!( "{} {} {} requires {} ({})", mozart_core::console::comment(&padded_name), @@ -404,7 +407,6 @@ fn render_text(results: &[CheckResult], console: &Console) { provider, constraint, ), - Verbosity::Normal, ); } } @@ -437,10 +439,7 @@ fn render_json(results: &[CheckResult], console: &Console) -> anyhow::Result<()> }) .collect(); - console.write_stdout( - &serde_json::to_string_pretty(&json_results)?, - Verbosity::Normal, - ); + console_writeln!(console, &serde_json::to_string_pretty(&json_results)?,); Ok(()) } diff --git a/crates/mozart/src/commands/config.rs b/crates/mozart/src/commands/config.rs index 274dcde..ebc8f30 100644 --- a/crates/mozart/src/commands/config.rs +++ b/crates/mozart/src/commands/config.rs @@ -1,5 +1,8 @@ use anyhow::anyhow; use clap::Args; +use mozart_core::config::resolve_references; +use mozart_core::console_writeln; +use mozart_core::factory::create_config; use std::collections::BTreeMap; use std::path::{Path, PathBuf}; @@ -60,9 +63,6 @@ pub struct ConfigArgs { pub source: bool, } -use mozart_core::config::resolve_references; -use mozart_core::factory::create_config; - /// Classification of config key value types for validation and normalization. #[derive(Debug)] enum ConfigValueType { @@ -776,7 +776,8 @@ fn execute_read( if args.list { for (key, value) in config.entries() { - console.write_stdout( + console_writeln!( + console, &format!("[{}] {}", key, render_value(&value)), mozart_core::console::Verbosity::Quiet, ); @@ -804,7 +805,8 @@ fn execute_read( if let Some(repos) = raw["repositories"].as_array() { for entry in repos { if entry.get("name").and_then(|n| n.as_str()) == Some(repo_name) { - console.write_stdout( + console_writeln!( + console, &render_value(entry), mozart_core::console::Verbosity::Quiet, ); @@ -819,7 +821,11 @@ fn execute_read( if key.starts_with("extra.") || key.starts_with("suggest.") { let raw = read_json_file(config_file_path, args.global)?; if let Some(v) = get_nested(&raw, key) { - console.write_stdout(&render_value(v), mozart_core::console::Verbosity::Quiet); + console_writeln!( + console, + &render_value(v), + mozart_core::console::Verbosity::Quiet, + ); return Ok(()); } return Err(anyhow!("Setting \"{}\" does not exist.", key)); @@ -829,7 +835,11 @@ fn execute_read( if CONFIGURABLE_PACKAGE_PROPERTIES.contains(&key.as_str()) { let raw = read_json_file(config_file_path, args.global)?; if let Some(v) = raw.get(key.as_str()) { - console.write_stdout(&render_value(v), mozart_core::console::Verbosity::Quiet); + console_writeln!( + console, + &render_value(v), + mozart_core::console::Verbosity::Quiet, + ); return Ok(()); } // Fall through to config section lookup @@ -838,7 +848,8 @@ fn execute_read( // 4. Standard config key lookup match config.get(key) { Some(value) => { - console.write_stdout( + console_writeln!( + console, &render_value(&value), mozart_core::console::Verbosity::Quiet, ); diff --git a/crates/mozart/src/commands/dependency.rs b/crates/mozart/src/commands/dependency.rs index 3b6f8c4..d0f2d48 100644 --- a/crates/mozart/src/commands/dependency.rs +++ b/crates/mozart/src/commands/dependency.rs @@ -10,6 +10,7 @@ use std::path::Path; use anyhow::Result; use mozart_core::console_format; +use mozart_core::console_writeln; /// Inputs for [`do_execute`], collected from the `depends` / `prohibits` CLI args. pub struct DoExecuteArgs<'a> { @@ -89,13 +90,13 @@ pub fn do_execute( if results.is_empty() { if inverted { - console.write_stdout( + console_writeln!( + console, &console_format!( "<info>{} {} can be installed.</info>", package, version.unwrap_or("") ), - mozart_core::console::Verbosity::Normal, ); return Ok(()); } @@ -647,9 +648,9 @@ fn sample_versions_from_constraint( /// Columns: package name | version | link description | link constraint pub fn print_table(results: &[DependencyResult], console: &mozart_core::console::Console) { if results.is_empty() { - console.write_stdout( + console_writeln!( + console, &format!("{}", mozart_core::console::info("No relationships found.")), - mozart_core::console::Verbosity::Normal, ); return; } @@ -680,7 +681,8 @@ pub fn print_table(results: &[DependencyResult], console: &mozart_core::console: if !seen.insert(key) { continue; } - console.write_stdout( + console_writeln!( + console, &format!( "{:<name_w$} {:<ver_w$} {:<desc_w$} {}", mozart_core::console::info(&r.package_name), @@ -691,7 +693,6 @@ pub fn print_table(results: &[DependencyResult], console: &mozart_core::console: ver_w = ver_w, desc_w = desc_w, ), - mozart_core::console::Verbosity::Normal, ); } } @@ -711,9 +712,9 @@ pub fn print_tree( console: &mozart_core::console::Console, ) { if results.is_empty() && depth == 0 { - console.write_stdout( + console_writeln!( + console, &format!("{}", mozart_core::console::info("No relationships found.")), - mozart_core::console::Verbosity::Normal, ); return; } @@ -723,7 +724,8 @@ pub fn print_tree( let is_last = i + 1 == count; let prefix = tree_prefix(depth, is_last); - console.write_stdout( + console_writeln!( + console, &format!( "{}{:<} {} {} {}", prefix, @@ -732,7 +734,6 @@ pub fn print_tree( r.link_description, mozart_core::console::comment(&r.link_constraint), ), - mozart_core::console::Verbosity::Normal, ); if !r.children.is_empty() { diff --git a/crates/mozart/src/commands/diagnose.rs b/crates/mozart/src/commands/diagnose.rs index 4c8d126..0a901e1 100644 --- a/crates/mozart/src/commands/diagnose.rs +++ b/crates/mozart/src/commands/diagnose.rs @@ -1,7 +1,8 @@ use clap::Args; use colored::Colorize; use mozart_core::MOZART_VERSION; -use mozart_core::console::{Console, Verbosity}; +use mozart_core::console::Console; +use mozart_core::console_writeln; use std::path::{Path, PathBuf}; #[derive(Args)] @@ -29,36 +30,30 @@ fn print_check(label: &str, result: &CheckResult, exit_code: &mut i32, console: let ok_str = "OK".green().bold(); match detail { Some(d) => { - console.write_stdout( - &format!("Checking {label}: {ok_str} ({d})"), - Verbosity::Normal, - ); + console_writeln!(console, &format!("Checking {label}: {ok_str} ({d})"),); } None => { - console.write_stdout(&format!("Checking {label}: {ok_str}"), Verbosity::Normal); + console_writeln!(console, &format!("Checking {label}: {ok_str}"),); } } } CheckResult::Warning(msg) => { let warn_str = "WARNING".yellow().bold(); - console.write_stdout(&format!("Checking {label}: {warn_str}"), Verbosity::Normal); - console.write_stdout(&format!(" {}", msg.yellow()), Verbosity::Normal); + console_writeln!(console, &format!("Checking {label}: {warn_str}"),); + console_writeln!(console, &format!(" {}", msg.yellow())); if *exit_code < 1 { *exit_code = 1; } } CheckResult::Fail(msg) => { let fail_str = "FAIL".red().bold(); - console.write_stdout(&format!("Checking {label}: {fail_str}"), Verbosity::Normal); - console.write_stdout(&format!(" {}", msg.red()), Verbosity::Normal); + console_writeln!(console, &format!("Checking {label}: {fail_str}"),); + console_writeln!(console, &format!(" {}", msg.red())); *exit_code = 2; } CheckResult::Skip(reason) => { let skip_str = "SKIP".cyan().bold(); - console.write_stdout( - &format!("Checking {label}: {skip_str} ({reason})"), - Verbosity::Normal, - ); + console_writeln!(console, &format!("Checking {label}: {skip_str} ({reason})"),); } CheckResult::Info(_) => { // Info results are not "checked" — use print_info_line instead. @@ -69,7 +64,7 @@ fn print_check(label: &str, result: &CheckResult, exit_code: &mut i32, console: /// Print an informational line (not a check result). fn print_info_line(result: &CheckResult, console: &Console) { if let CheckResult::Info(msg) = result { - console.write_stdout(msg, Verbosity::Normal); + console_writeln!(console, msg); } } @@ -412,7 +407,7 @@ pub async fn execute( // 1. Mozart version info print_info_line(&check_version(), console); - console.write_stdout("", Verbosity::Normal); + console_writeln!(console, ""); // 2. HTTPS connectivity to Packagist let https_result = check_http_connectivity("https://repo.packagist.org/packages.json").await; @@ -484,24 +479,21 @@ pub async fn execute( let cache_result = check_cache_dir(&cache_dir); print_check("cache directory", &cache_result, &mut exit_code, console); - console.write_stdout("", Verbosity::Normal); + console_writeln!(console, ""); if exit_code == 0 { - console.write_stdout( - &format!("{}", "No issues found.".green()), - Verbosity::Normal, - ); + console_writeln!(console, &format!("{}", "No issues found.".green()),); } else if exit_code == 1 { - console.write_stdout( + console_writeln!( + console, &format!( "{}", "Some warnings were found. See above for details.".yellow() ), - Verbosity::Normal, ); } else { - console.write_stdout( + console_writeln!( + console, &format!("{}", "Some errors were found. See above for details.".red()), - Verbosity::Normal, ); } diff --git a/crates/mozart/src/commands/exec.rs b/crates/mozart/src/commands/exec.rs index 9d79bee..4371772 100644 --- a/crates/mozart/src/commands/exec.rs +++ b/crates/mozart/src/commands/exec.rs @@ -1,6 +1,7 @@ use clap::Args; use mozart_core::composer::Composer; use mozart_core::console_format; +use mozart_core::console_writeln; use std::path::{Path, PathBuf}; #[derive(Args)] @@ -22,7 +23,6 @@ pub async fn execute( cli: &super::Cli, console: &mozart_core::console::Console, ) -> anyhow::Result<()> { - use mozart_core::console::Verbosity; let working_dir = cli.working_dir()?; // ExecCommand uses requireComposer in Composer; composer.json must exist. @@ -37,21 +37,15 @@ pub async fn execute( bin_dir.display() ); } - console.write_stdout( + console_writeln!( + console, &console_format!("<comment>Available binaries:</comment>"), - Verbosity::Normal, ); for (name, is_local) in &binaries { if *is_local { - console.write_stdout( - &console_format!("<info>- {} (local)</info>", name), - Verbosity::Normal, - ); + console_writeln!(console, &console_format!("<info>- {} (local)</info>", name),); } else { - console.write_stdout( - &console_format!("<info>- {}</info>", name), - Verbosity::Normal, - ); + console_writeln!(console, &console_format!("<info>- {}</info>", name),); } } return Ok(()); diff --git a/crates/mozart/src/commands/fund.rs b/crates/mozart/src/commands/fund.rs index 812b17d..ab8591a 100644 --- a/crates/mozart/src/commands/fund.rs +++ b/crates/mozart/src/commands/fund.rs @@ -1,6 +1,7 @@ use clap::Args; use mozart_core::console; use mozart_core::console_format; +use mozart_core::console_writeln; use serde::Serialize; use std::collections::BTreeMap; use std::path::Path; @@ -177,47 +178,41 @@ fn render_text( console: &console::Console, ) { if grouped.is_empty() { - console.write_stdout( + console_writeln!( + console, "No funding links were found in your package dependencies. \ This doesn't mean they don't need your support!", - console::Verbosity::Normal, ); return; } - console.write_stdout( + console_writeln!( + console, "The following packages were found in your dependencies which publish funding information:", - console::Verbosity::Normal, ); for (vendor, url_map) in grouped { - console.write_stdout("", console::Verbosity::Normal); - console.write_stdout( - &console_format!("<comment>{vendor}</comment>"), - console::Verbosity::Normal, - ); + console_writeln!(console, ""); + console_writeln!(console, &console_format!("<comment>{vendor}</comment>")); for (url, packages) in url_map { // Deduplicate cross-URL: only print package-names line when it differs from prev let mut prev: Option<String> = None; let packages_str = packages.join(", "); if prev.as_deref() != Some(packages_str.as_str()) { - console.write_stdout( - &console_format!(" <info>{packages_str}</info>"), - console::Verbosity::Normal, - ); + console_writeln!(console, &console_format!(" <info>{packages_str}</info>")); } prev = Some(packages_str); let _ = prev; - console.write_stdout(&format!(" {url}"), console::Verbosity::Normal); + console_writeln!(console, &format!(" {url}")); } } - console.write_stdout("", console::Verbosity::Normal); - console.write_stdout( + console_writeln!(console, ""); + console_writeln!( + console, "Please consider following these links and sponsoring the work of package authors!", - console::Verbosity::Normal, ); - console.write_stdout("Thank you!", console::Verbosity::Normal); + console_writeln!(console, "Thank you!"); } fn render_json( @@ -228,10 +223,7 @@ fn render_json( let formatter = serde_json::ser::PrettyFormatter::with_indent(b" "); let mut ser = serde_json::Serializer::with_formatter(buf, formatter); grouped.serialize(&mut ser)?; - console.write_stdout( - &String::from_utf8(ser.into_inner())?, - console::Verbosity::Normal, - ); + console_writeln!(console, &String::from_utf8(ser.into_inner())?); Ok(()) } diff --git a/crates/mozart/src/commands/licenses.rs b/crates/mozart/src/commands/licenses.rs index 5c131b4..dc232e9 100644 --- a/crates/mozart/src/commands/licenses.rs +++ b/crates/mozart/src/commands/licenses.rs @@ -1,6 +1,7 @@ use clap::Args; use indexmap::IndexSet; -use mozart_core::console::{Console, Verbosity}; +use mozart_core::console::Console; +use mozart_core::console_writeln; use serde::Serialize; use std::path::Path; @@ -195,23 +196,23 @@ fn render_text( } else { root_licenses.join(", ") }; - console.write_stdout( + console_writeln!( + console, &format!("Name: {}", mozart_core::console::comment(root_name)), - Verbosity::Normal, ); - console.write_stdout( + console_writeln!( + console, &format!("Version: {}", mozart_core::console::comment(root_version)), - Verbosity::Normal, ); - console.write_stdout( + console_writeln!( + console, &format!( "Licenses: {}", mozart_core::console::comment(&license_display) ), - Verbosity::Normal, ); - console.write_stdout("Dependencies:", Verbosity::Normal); - console.write_stdout("", Verbosity::Normal); + console_writeln!(console, "Dependencies:"); + console_writeln!(console, ""); if entries.is_empty() { return; @@ -230,7 +231,8 @@ fn render_text( .unwrap_or(0) .max("Version".len()); - console.write_stdout( + console_writeln!( + console, &format!( "{:<nw$} {:<vw$} Licenses", "Name", @@ -238,7 +240,6 @@ fn render_text( nw = name_width, vw = version_width ), - Verbosity::Normal, ); for entry in entries { @@ -247,7 +248,8 @@ fn render_text( } else { entry.licenses.join(", ") }; - console.write_stdout( + console_writeln!( + console, &format!( "{:<nw$} {:<vw$} {}", entry.name, @@ -256,7 +258,6 @@ fn render_text( nw = name_width, vw = version_width ), - Verbosity::Normal, ); } } @@ -300,7 +301,7 @@ fn render_json( let formatter = serde_json::ser::PrettyFormatter::with_indent(b" "); let mut ser = serde_json::Serializer::with_formatter(buf, formatter); output.serialize(&mut ser)?; - console.write_stdout(&String::from_utf8(ser.into_inner())?, Verbosity::Normal); + console_writeln!(console, &String::from_utf8(ser.into_inner())?,); Ok(()) } @@ -308,7 +309,7 @@ fn render_summary(entries: &[LicenseEntry], console: &Console) { let counts = count_licenses(entries); if counts.is_empty() { - console.write_stdout("No dependencies found.", Verbosity::Normal); + console_writeln!(console, "No dependencies found."); return; } @@ -330,11 +331,9 @@ fn render_summary(entries: &[LicenseEntry], console: &Console) { let border_col1 = "-".repeat(license_width + 2); let border_col2 = "-".repeat(count_width + 2); - console.write_stdout( - &format!(" {} {}", border_col1, border_col2), - Verbosity::Normal, - ); - console.write_stdout( + console_writeln!(console, &format!(" {} {}", border_col1, border_col2),); + console_writeln!( + console, &format!( " {:<lw$} {:<cw$}", "License", @@ -342,14 +341,11 @@ fn render_summary(entries: &[LicenseEntry], console: &Console) { lw = license_width, cw = count_width ), - Verbosity::Normal, - ); - console.write_stdout( - &format!(" {} {}", border_col1, border_col2), - Verbosity::Normal, ); + console_writeln!(console, &format!(" {} {}", border_col1, border_col2),); for (license, count) in &counts { - console.write_stdout( + console_writeln!( + console, &format!( " {:<lw$} {:<cw$}", license, @@ -357,13 +353,9 @@ fn render_summary(entries: &[LicenseEntry], console: &Console) { lw = license_width, cw = count_width ), - Verbosity::Normal, ); } - console.write_stdout( - &format!(" {} {}", border_col1, border_col2), - Verbosity::Normal, - ); + console_writeln!(console, &format!(" {} {}", border_col1, border_col2),); } #[cfg(test)] diff --git a/crates/mozart/src/commands/outdated.rs b/crates/mozart/src/commands/outdated.rs index 5f77315..2b25816 100644 --- a/crates/mozart/src/commands/outdated.rs +++ b/crates/mozart/src/commands/outdated.rs @@ -1,5 +1,6 @@ use clap::Args; use indexmap::IndexSet; +use mozart_core::console_writeln; use mozart_core::matches_wildcard; use std::cmp::Ordering; use std::path::Path; @@ -438,12 +439,10 @@ fn passes_level_filter(args: &OutdatedArgs, current: &str, latest: &str) -> bool } fn render_text(entries: &[OutdatedEntry], console: &mozart_core::console::Console) { - use mozart_core::console::Verbosity; - if entries.is_empty() { - console.write_stdout( + console_writeln!( + console, &mozart_core::console::info("All packages are up to date.").to_string(), - Verbosity::Normal, ); return; } @@ -481,7 +480,8 @@ fn render_text(entries: &[OutdatedEntry], console: &mozart_core::console::Consol ), }; - console.write_stdout( + console_writeln!( + console, &format!( "{} {} {} {}", name_str, @@ -489,7 +489,6 @@ fn render_text(entries: &[OutdatedEntry], console: &mozart_core::console::Consol lat_str, entry.description ), - Verbosity::Normal, ); } } @@ -498,7 +497,6 @@ fn render_json( entries: &[OutdatedEntry], console: &mozart_core::console::Console, ) -> anyhow::Result<()> { - use mozart_core::console::Verbosity; let json_entries: Vec<serde_json::Value> = entries .iter() .map(|entry| { @@ -519,7 +517,7 @@ fn render_json( .collect(); let output = serde_json::json!({ "installed": json_entries }); - console.write_stdout(&serde_json::to_string_pretty(&output)?, Verbosity::Normal); + console_writeln!(console, &serde_json::to_string_pretty(&output)?); Ok(()) } diff --git a/crates/mozart/src/commands/reinstall.rs b/crates/mozart/src/commands/reinstall.rs index 7e426f8..b421bd8 100644 --- a/crates/mozart/src/commands/reinstall.rs +++ b/crates/mozart/src/commands/reinstall.rs @@ -1,5 +1,6 @@ use clap::Args; use mozart_core::console_format; +use mozart_core::console_writeln; use mozart_core::package; #[derive(Args)] @@ -164,14 +165,14 @@ pub async fn execute( for pkg in &selected { let locked = find_locked_package(&all_locked, &pkg.name); if let Some(lp) = locked { - console.write_stdout( + console_writeln!( + console, &format!(" - Would reinstall {} ({})", lp.name, lp.version), - mozart_core::console::Verbosity::Normal, ); } else { - console.write_stdout( + console_writeln!( + console, &format!(" - Would reinstall {} (not found in lock file)", pkg.name), - mozart_core::console::Verbosity::Normal, ); } } @@ -241,10 +242,7 @@ pub async fn execute( } if reinstalled_count == 0 { - console.write_stdout( - "Nothing was reinstalled.", - mozart_core::console::Verbosity::Normal, - ); + console_writeln!(console, "Nothing was reinstalled.",); return Ok(()); } diff --git a/crates/mozart/src/commands/remove.rs b/crates/mozart/src/commands/remove.rs index ff3df47..56555f7 100644 --- a/crates/mozart/src/commands/remove.rs +++ b/crates/mozart/src/commands/remove.rs @@ -1,7 +1,7 @@ use clap::Args; use indexmap::{IndexMap, IndexSet}; -use mozart_core::console::Verbosity; use mozart_core::console_format; +use mozart_core::console_writeln; use mozart_core::package; use mozart_core::validation; use mozart_registry::lockfile; @@ -151,9 +151,9 @@ pub async fn execute( if args.dev { // Only look in require-dev if raw.require_dev.contains_key(&name) { - console.write_stdout( + console_writeln!( + console, &console_format!("<info>Removing {name} from require-dev</info>"), - Verbosity::Normal, ); raw.require_dev.remove(&name); any_removed = true; @@ -163,16 +163,16 @@ pub async fn execute( } else { // Auto-detect: look in require first, then require-dev if raw.require.contains_key(&name) { - console.write_stdout( + console_writeln!( + console, &console_format!("<info>Removing {name} from require</info>"), - Verbosity::Normal, ); raw.require.remove(&name); any_removed = true; } else if raw.require_dev.contains_key(&name) { - console.write_stdout( + console_writeln!( + console, &console_format!("<info>Removing {name} from require-dev</info>"), - Verbosity::Normal, ); raw.require_dev.remove(&name); any_removed = true; @@ -184,9 +184,9 @@ pub async fn execute( // Step 6: Write updated composer.json (unless --dry-run) if args.dry_run { - console.write_stdout( + console_writeln!( + console, &console_format!("<comment>Dry run: composer.json not modified.</comment>"), - Verbosity::Normal, ); } else if any_removed { package::write_to_file(&raw, &composer_path)?; @@ -195,11 +195,11 @@ pub async fn execute( // Step 7: Handle --no-update early return if args.no_update { - console.write_stdout( + console_writeln!( + console, &console_format!( "<comment>Not updating dependencies, only modifying composer.json.</comment>" ), - Verbosity::Normal, ); return Ok(()); } diff --git a/crates/mozart/src/commands/repository.rs b/crates/mozart/src/commands/repository.rs index 5bb3db7..c2d2bd8 100644 --- a/crates/mozart/src/commands/repository.rs +++ b/crates/mozart/src/commands/repository.rs @@ -1,5 +1,6 @@ use anyhow::anyhow; use clap::Args; +use mozart_core::console_writeln; use std::path::PathBuf; use super::config_helpers::{ @@ -91,10 +92,7 @@ fn execute_list( if let Some(obj) = entry.as_object() { // Check for disabled repo entry like {"packagist.org": false} if let Some((key, _)) = obj.iter().find(|(_, v)| v == &&serde_json::json!(false)) { - console.write_stdout( - &format!("[{key}] disabled"), - mozart_core::console::Verbosity::Normal, - ); + console_writeln!(console, &format!("[{key}] disabled"),); if key == "packagist.org" { has_packagist_disable = true; } @@ -112,16 +110,13 @@ fn execute_list( .unwrap_or("unknown"); let url = entry.get("url").and_then(|u| u.as_str()).unwrap_or(""); - console.write_stdout( - &format!("[{name}] {repo_type} {url}"), - mozart_core::console::Verbosity::Normal, - ); + console_writeln!(console, &format!("[{name}] {repo_type} {url}"),); } if !has_packagist_disable { - console.write_stdout( + console_writeln!( + console, "[packagist.org] composer https://repo.packagist.org", - mozart_core::console::Verbosity::Normal, ); } @@ -273,10 +268,7 @@ fn execute_get_url( let entry = &repos[idx]; match entry.get("url") { Some(url_val) => { - console.write_stdout( - &render_value(url_val), - mozart_core::console::Verbosity::Normal, - ); + console_writeln!(console, &render_value(url_val),); Ok(()) } None => Err(anyhow!("The \"{name}\" repository does not have a URL")), diff --git a/crates/mozart/src/commands/require.rs b/crates/mozart/src/commands/require.rs index 828474d..150a003 100644 --- a/crates/mozart/src/commands/require.rs +++ b/crates/mozart/src/commands/require.rs @@ -1,7 +1,7 @@ use clap::Args; use indexmap::{IndexMap, IndexSet}; -use mozart_core::console::Verbosity; use mozart_core::console_format; +use mozart_core::console_writeln; use mozart_core::package::{self, Stability}; use mozart_core::validation; use mozart_registry::lockfile; @@ -462,11 +462,11 @@ pub async fn execute( anyhow::bail!("Invalid package name: \"{name}\""); } - console.write_stdout( + console_writeln!( + console, &console_format!( "<info>Using version constraint for {name} from Packagist...</info>" ), - Verbosity::Normal, ); let versions = packagist::fetch_package_versions(&name, &repo_cache).await?; @@ -489,9 +489,9 @@ pub async fn execute( ) }; - console.write_stdout( + console_writeln!( + console, &console_format!("<info>Using version {constraint} for {name}</info>"), - Verbosity::Normal, ); (name, constraint) @@ -543,16 +543,16 @@ pub async fn execute( }; if let Some(existing) = target.get(name) { - console.write_stdout( + console_writeln!( + console, &console_format!( "<comment>Updating {name} from {existing} to {constraint} in {section_name}</comment>" ), - Verbosity::Normal, ); } else { - console.write_stdout( + console_writeln!( + console, &console_format!("<info>Adding {name} ({constraint}) to {section_name}</info>"), - Verbosity::Normal, ); } @@ -578,9 +578,9 @@ pub async fn execute( // Write back composer.json (unless --dry-run) if args.dry_run { - console.write_stdout( + console_writeln!( + console, &console_format!("<comment>Dry run: composer.json not modified.</comment>"), - Verbosity::Normal, ); } else { package::write_to_file(&raw, &composer_path)?; @@ -588,11 +588,11 @@ pub async fn execute( // Handle --no-update: skip resolution entirely if args.no_update { - console.write_stdout( + console_writeln!( + console, &console_format!( "<comment>Not updating dependencies, only modifying composer.json.</comment>" ), - Verbosity::Normal, ); return Ok(()); } diff --git a/crates/mozart/src/commands/run_script.rs b/crates/mozart/src/commands/run_script.rs index 7e5cbe4..f7ce7b9 100644 --- a/crates/mozart/src/commands/run_script.rs +++ b/crates/mozart/src/commands/run_script.rs @@ -1,4 +1,5 @@ use clap::Args; +use mozart_core::console_writeln; use std::collections::BTreeMap; use std::path::{Path, PathBuf}; use std::time::Duration; @@ -198,12 +199,10 @@ fn list_scripts( descriptions: &BTreeMap<String, String>, console: &mozart_core::console::Console, ) -> anyhow::Result<()> { - use mozart_core::console::Verbosity; - - console.write_stdout("scripts:", Verbosity::Normal); + console_writeln!(console, "scripts:"); for name in scripts.keys() { let desc = descriptions.get(name).map(|s| s.as_str()).unwrap_or(""); - console.write_stdout(&format!(" {} {}", name, desc), Verbosity::Normal); + console_writeln!(console, &format!(" {} {}", name, desc)); } Ok(()) } diff --git a/crates/mozart/src/commands/search.rs b/crates/mozart/src/commands/search.rs index 2ee84de..25d32da 100644 --- a/crates/mozart/src/commands/search.rs +++ b/crates/mozart/src/commands/search.rs @@ -1,6 +1,6 @@ use clap::Args; -use mozart_core::console::Verbosity; use mozart_core::console_format; +use mozart_core::console_writeln; use mozart_registry::packagist::SearchResult; use serde::Serialize; @@ -151,7 +151,7 @@ pub async fn execute( match format { "json" => { let json = serde_json::to_string_pretty(&vendor_names)?; - console.write_stdout(&json, Verbosity::Normal); + console_writeln!(console, &json); } _ => { if vendor_names.is_empty() { @@ -160,10 +160,7 @@ pub async fn execute( )); } else { for vendor in &vendor_names { - console.write_stdout( - &console_format!("<info>{vendor}</info>"), - Verbosity::Normal, - ); + console_writeln!(console, &console_format!("<info>{vendor}</info>"),); } } } @@ -179,7 +176,7 @@ pub async fn execute( .map(|r| SearchResultOutput::from(*r)) .collect(); let json = serde_json::to_string_pretty(&output)?; - console.write_stdout(&json, Verbosity::Normal); + console_writeln!(console, &json); } _ => { if results.is_empty() { @@ -210,9 +207,9 @@ pub async fn execute( }; let padding = " ".repeat(name_width.saturating_sub(result.name.len())); - console.write_stdout( + console_writeln!( + console, &format!("{}{}{}{}", result.name, padding, warning, desc_display), - Verbosity::Normal, ); } } diff --git a/crates/mozart/src/commands/self_update.rs b/crates/mozart/src/commands/self_update.rs index 4037355..d5ddda0 100644 --- a/crates/mozart/src/commands/self_update.rs +++ b/crates/mozart/src/commands/self_update.rs @@ -1,7 +1,7 @@ use clap::Args; use mozart_core::MOZART_VERSION; -use mozart_core::console::Verbosity; use mozart_core::console_format; +use mozart_core::console_writeln; use std::io::Write; use std::path::{Path, PathBuf}; @@ -278,20 +278,20 @@ async fn update( // If no explicit version was requested and we're already up-to-date, bail early if args.version.is_none() && target_version == current_version { - console.write_stdout( + console_writeln!( + console, &console_format!( "<info>You are already using the latest available Mozart version {current_version} ({channel} channel).</info>" ), - Verbosity::Normal, ); if args.clean_backups { // Preserve the most recent backup let latest = find_latest_backup(data_dir).ok(); clean_backups(data_dir, latest.as_deref())?; - console.write_stdout( + console_writeln!( + console, &console_format!("<comment>Old backups removed.</comment>"), - Verbosity::Normal, ); } @@ -347,11 +347,11 @@ async fn update( // tmp is still in scope and will be cleaned up; the replace succeeded drop(tmp); - console.write_stdout( + console_writeln!( + console, &console_format!( "<info>Mozart updated successfully from {current_version} to {target_version}</info>" ), - Verbosity::Normal, ); console.info(&format!( "Use `mozart self-update --rollback` to return to version {current_version}" @@ -359,9 +359,9 @@ async fn update( if args.clean_backups { clean_backups(data_dir, Some(&backup_path))?; - console.write_stdout( + console_writeln!( + console, &console_format!("<comment>Old backups removed.</comment>"), - Verbosity::Normal, ); } @@ -391,9 +391,9 @@ fn rollback( self_replace::self_replace(&backup) .map_err(|e| anyhow::anyhow!("Could not restore backup: {e}"))?; - console.write_stdout( + console_writeln!( + console, &console_format!("<info>Rollback successful. Restored version {backup_version}</info>"), - Verbosity::Normal, ); let _ = current_exe; // suppress unused warning diff --git a/crates/mozart/src/commands/show.rs b/crates/mozart/src/commands/show.rs index c07ffb1..7b87403 100644 --- a/crates/mozart/src/commands/show.rs +++ b/crates/mozart/src/commands/show.rs @@ -1,7 +1,8 @@ use clap::Args; use indexmap::{IndexMap, IndexSet}; -use mozart_core::console::Verbosity; use mozart_core::console_format; +use mozart_core::console_writeln; +use mozart_core::console_writeln_error; use mozart_core::matches_wildcard; use std::path::Path; @@ -158,11 +159,11 @@ pub async fn execute( // Fix 8: --ignore without --outdated warning if !args.ignore.is_empty() && !args.outdated { - console.write( + console_writeln_error!( + console, &console_format!( "<warning>You are using the option \"ignore\" for action other than \"outdated\", it will be ignored.</warning>" ), - Verbosity::Normal, ); } @@ -212,11 +213,11 @@ async fn execute_installed( if composer_json_path.exists() { let root = mozart_core::package::read_from_file(&composer_json_path)?; if !root.require.is_empty() || !root.require_dev.is_empty() { - console.write( + console_writeln_error!( + console, &console_format!( "<warning>No dependencies installed. Try running mozart install or update.</warning>" ), - Verbosity::Normal, ); } } @@ -236,7 +237,7 @@ async fn execute_installed( Some(p) => { let install_path = vendor_dir.join(&p.name); let path_str = resolve_path(&install_path); - console.write_stdout(&format!("{} {}", p.name, path_str), Verbosity::Normal); + console_writeln!(console, &format!("{} {}", p.name, path_str),); } None => { anyhow::bail!( @@ -268,7 +269,7 @@ async fn execute_installed( for pkg in &packages { let install_path = vendor_dir.join(&pkg.name); let path_str = resolve_path(&install_path); - console.write_stdout(&format!("{} {}", pkg.name, path_str), Verbosity::Normal); + console_writeln!(console, &format!("{} {}", pkg.name, path_str),); } return Ok(()); } @@ -327,7 +328,7 @@ async fn show_installed_package_list( if args.name_only { for pkg in packages { - console.write_stdout(&pkg.name, Verbosity::Normal); + console_writeln!(console, &pkg.name); } return Ok(()); } @@ -480,17 +481,17 @@ async fn show_installed_package_list( } None => format!("{:<width$}", "", width = latest_width), }; - console.write_stdout( + console_writeln!( + console, &format!( "{} {} {} {}", name_str, version_str, latest_str, entry.description ), - Verbosity::Normal, ); } else { - console.write_stdout( + console_writeln!( + console, &format!("{} {} {}", name_str, version_str, entry.description), - Verbosity::Normal, ); } } @@ -601,7 +602,7 @@ fn render_installed_json( .collect(); let output = serde_json::json!({ "installed": json_entries }); - console.write_stdout(&serde_json::to_string_pretty(&output)?, Verbosity::Normal); + console_writeln!(console, &serde_json::to_string_pretty(&output)?,); Ok(()) } @@ -629,64 +630,64 @@ fn show_installed_package_detail( let vendor_dir = working_dir.join("vendor"); - console.write_stdout( + console_writeln!( + console, &format!("{} : {}", console_format!("<info>name</info>"), pkg.name), - Verbosity::Normal, ); - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>descrip.</info>"), get_installed_description(pkg) ), - Verbosity::Normal, ); - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>keywords</info>"), get_installed_keywords(pkg) ), - Verbosity::Normal, ); - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>versions</info>"), format_version_highlight(&pkg.version) ), - Verbosity::Normal, ); - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>type</info>"), pkg.package_type.as_deref().unwrap_or("library") ), - Verbosity::Normal, ); // License — one line per identifier, matching Composer's printLicenses. for license_id in get_installed_licenses(pkg) { - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>license</info>"), format_license_for_show(&license_id), ), - Verbosity::Normal, ); } // Homepage if let Some(homepage) = get_installed_homepage(pkg) { - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>homepage</info>"), homepage ), - Verbosity::Normal, ); } @@ -698,7 +699,8 @@ fn show_installed_package_detail( .get("reference") .and_then(|v| v.as_str()) .unwrap_or(""); - console.write_stdout( + console_writeln!( + console, &format!( "{} : [{}] {} {}", console_format!("<info>source</info>"), @@ -706,7 +708,6 @@ fn show_installed_package_detail( console_format!("<comment>{}</comment>", source_url), source_ref ), - Verbosity::Normal, ); } @@ -715,7 +716,8 @@ fn show_installed_package_detail( let dist_type = dist.get("type").and_then(|v| v.as_str()).unwrap_or(""); let dist_url = dist.get("url").and_then(|v| v.as_str()).unwrap_or(""); let dist_ref = dist.get("reference").and_then(|v| v.as_str()).unwrap_or(""); - console.write_stdout( + console_writeln!( + console, &format!( "{} : [{}] {} {}", console_format!("<info>dist</info>"), @@ -723,20 +725,19 @@ fn show_installed_package_detail( console_format!("<comment>{}</comment>", dist_url), dist_ref ), - Verbosity::Normal, ); } // Path let install_path = vendor_dir.join(&pkg.name); if install_path.exists() { - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>path</info>"), install_path.display() ), - Verbosity::Normal, ); } @@ -744,13 +745,13 @@ fn show_installed_package_detail( if let Some(requires) = pkg.extra_fields.get("require").and_then(|v| v.as_object()) && !requires.is_empty() { - console.write_stdout("", Verbosity::Normal); - console.write_stdout(&console_format!("<info>requires</info>"), Verbosity::Normal); + console_writeln!(console, ""); + console_writeln!(console, &console_format!("<info>requires</info>"),); for (name, constraint) in requires { let c = constraint.as_str().unwrap_or(""); - console.write_stdout( + console_writeln!( + console, &format!("{} {}", name, console_format!("<comment>{}</comment>", c)), - Verbosity::Normal, ); } } @@ -762,16 +763,13 @@ fn show_installed_package_detail( .and_then(|v| v.as_object()) && !requires_dev.is_empty() { - console.write_stdout("", Verbosity::Normal); - console.write_stdout( - &console_format!("<info>requires (dev)</info>"), - Verbosity::Normal, - ); + console_writeln!(console, ""); + console_writeln!(console, &console_format!("<info>requires (dev)</info>"),); for (name, constraint) in requires_dev { let c = constraint.as_str().unwrap_or(""); - console.write_stdout( + console_writeln!( + console, &format!("{} {}", name, console_format!("<comment>{}</comment>", c)), - Verbosity::Normal, ); } } @@ -845,7 +843,7 @@ async fn show_locked_package_list( if args.name_only { for pkg in packages { - console.write_stdout(&pkg.name, Verbosity::Normal); + console_writeln!(console, &pkg.name); } return Ok(()); } @@ -996,17 +994,17 @@ async fn show_locked_package_list( } None => format!("{:<width$}", "", width = latest_width), }; - console.write_stdout( + console_writeln!( + console, &format!( "{} {} {} {}", name_str, version_str, latest_str, entry.description ), - Verbosity::Normal, ); } else { - console.write_stdout( + console_writeln!( + console, &format!("{} {} {}", name_str, version_str, entry.description), - Verbosity::Normal, ); } } @@ -1057,7 +1055,7 @@ fn render_locked_json( .collect(); let output = serde_json::json!({ "installed": json_entries }); - console.write_stdout(&serde_json::to_string_pretty(&output)?, Verbosity::Normal); + console_writeln!(console, &serde_json::to_string_pretty(&output)?,); Ok(()) } @@ -1080,17 +1078,17 @@ fn show_locked_package_detail( } }; - console.write_stdout( + console_writeln!( + console, &format!("{} : {}", console_format!("<info>name</info>"), pkg.name), - Verbosity::Normal, ); - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>descrip.</info>"), pkg.description.as_deref().unwrap_or("") ), - Verbosity::Normal, ); // Keywords @@ -1099,61 +1097,62 @@ fn show_locked_package_detail( .as_ref() .map(|kw| kw.join(", ")) .unwrap_or_default(); - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>keywords</info>"), keywords ), - Verbosity::Normal, ); - console.write_stdout( + console_writeln!( + console, &format!( "{} : * {}", console_format!("<info>versions</info>"), format_version(&pkg.version) ), - Verbosity::Normal, ); - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>type</info>"), pkg.package_type.as_deref().unwrap_or("library") ), - Verbosity::Normal, ); // License — one line per identifier, matching Composer's printLicenses. if let Some(ref licenses) = pkg.license { for license_id in licenses { - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>license</info>"), format_license_for_show(license_id), ), - Verbosity::Normal, ); } } // Homepage if let Some(ref homepage) = pkg.homepage { - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>homepage</info>"), homepage ), - Verbosity::Normal, ); } // Source if let Some(ref source) = pkg.source { - console.write_stdout( + console_writeln!( + console, &format!( "{} : [{}] {} {}", console_format!("<info>source</info>"), @@ -1161,13 +1160,13 @@ fn show_locked_package_detail( console_format!("<comment>{}</comment>", &source.url), source.reference.as_deref().unwrap_or("") ), - Verbosity::Normal, ); } // Dist if let Some(ref dist) = pkg.dist { - console.write_stdout( + console_writeln!( + console, &format!( "{} : [{}] {} {}", console_format!("<info>dist</info>"), @@ -1175,41 +1174,37 @@ fn show_locked_package_detail( console_format!("<comment>{}</comment>", &dist.url), dist.reference.as_deref().unwrap_or("") ), - Verbosity::Normal, ); } // Requires if !pkg.require.is_empty() { - console.write_stdout("", Verbosity::Normal); - console.write_stdout(&console_format!("<info>requires</info>"), Verbosity::Normal); + console_writeln!(console, ""); + console_writeln!(console, &console_format!("<info>requires</info>"),); for (name, constraint) in &pkg.require { - console.write_stdout( + console_writeln!( + console, &format!( "{} {}", name, console_format!("<comment>{}</comment>", constraint) ), - Verbosity::Normal, ); } } // Requires (dev) if !pkg.require_dev.is_empty() { - console.write_stdout("", Verbosity::Normal); - console.write_stdout( - &console_format!("<info>requires (dev)</info>"), - Verbosity::Normal, - ); + console_writeln!(console, ""); + console_writeln!(console, &console_format!("<info>requires (dev)</info>"),); for (name, constraint) in &pkg.require_dev { - console.write_stdout( + console_writeln!( + console, &format!( "{} {}", name, console_format!("<comment>{}</comment>", constraint) ), - Verbosity::Normal, ); } } @@ -1218,16 +1213,16 @@ fn show_locked_package_detail( if let Some(ref suggests) = pkg.suggest && !suggests.is_empty() { - console.write_stdout("", Verbosity::Normal); - console.write_stdout(&console_format!("<info>suggests</info>"), Verbosity::Normal); + console_writeln!(console, ""); + console_writeln!(console, &console_format!("<info>suggests</info>"),); for (name, reason) in suggests { - console.write_stdout( + console_writeln!( + console, &format!( "{} {}", name, console_format!("<comment>{}</comment>", reason) ), - Verbosity::Normal, ); } } @@ -1247,82 +1242,79 @@ fn show_self( let root = mozart_core::package::read_from_file(&composer_json_path)?; if args.name_only { - console.write_stdout(&root.name, Verbosity::Normal); + console_writeln!(console, &root.name); return Ok(()); } - console.write_stdout( + console_writeln!( + console, &format!("{} : {}", console_format!("<info>name</info>"), root.name), - Verbosity::Normal, ); - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>descrip.</info>"), root.description.as_deref().unwrap_or("") ), - Verbosity::Normal, ); - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>type</info>"), root.package_type.as_deref().unwrap_or("project") ), - Verbosity::Normal, ); if let Some(ref license) = root.license { - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>license</info>"), format_license_for_show(license), ), - Verbosity::Normal, ); } if let Some(ref homepage) = root.homepage { - console.write_stdout( + console_writeln!( + console, &format!( "{} : {}", console_format!("<info>homepage</info>"), homepage ), - Verbosity::Normal, ); } // Requires if !root.require.is_empty() { - console.write_stdout("", Verbosity::Normal); - console.write_stdout(&console_format!("<info>requires</info>"), Verbosity::Normal); + console_writeln!(console, ""); + console_writeln!(console, &console_format!("<info>requires</info>"),); for (name, constraint) in &root.require { - console.write_stdout( + console_writeln!( + console, &format!( "{} {}", name, console_format!("<comment>{}</comment>", constraint) ), - Verbosity::Normal, ); } } // Requires (dev) if !root.require_dev.is_empty() { - console.write_stdout("", Verbosity::Normal); - console.write_stdout( - &console_format!("<info>requires (dev)</info>"), - Verbosity::Normal, - ); + console_writeln!(console, ""); + console_writeln!(console, &console_format!("<info>requires (dev)</info>"),); for (name, constraint) in &root.require_dev { - console.write_stdout( + console_writeln!( + console, &format!( "{} {}", name, console_format!("<comment>{}</comment>", constraint) ), - Verbosity::Normal, ); } } @@ -1378,13 +1370,13 @@ fn show_tree( }; // Print root - console.write_stdout( + console_writeln!( + console, &console_format!( "<info>{}</info> <comment>{}</comment>", &root.name, root.description.as_deref().unwrap_or("") ), - Verbosity::Normal, ); // Render each root dependency as a tree @@ -1430,22 +1422,22 @@ fn print_tree_node( let description = pkg.description.as_deref().unwrap_or(""); let version = format_version(&pkg.version); - console.write_stdout( + console_writeln!( + console, &format!( "{} {} {}", prefix, console_format!("<info>{}</info> <comment>{}</comment>", pkg_name, &version), description ), - Verbosity::Normal, ); // Detect circular dependency or depth limit if visited.contains(&key) || depth >= MAX_DEPTH { if visited.contains(&key) { - console.write_stdout( + console_writeln!( + console, &format!("{} {} (circular dependency)", child_prefix, pkg_name), - Verbosity::Normal, ); } return; @@ -1494,14 +1486,14 @@ fn print_tree_node( } else { // Package not found in lock file (platform package or not installed) if !is_platform_package(&key) { - console.write_stdout( + console_writeln!( + console, &format!( "{} {} {} (not installed)", prefix, console_format!("<comment>{}</comment>", pkg_name), constraint ), - Verbosity::Normal, ); } } @@ -1588,9 +1580,9 @@ fn show_platform( }) }) .collect(); - console.write_stdout( + console_writeln!( + console, &serde_json::to_string_pretty(&serde_json::json!({ "platform": json_entries }))?, - Verbosity::Normal, ); return Ok(()); } @@ -1604,7 +1596,7 @@ fn show_platform( if args.name_only { for (name, _, _) in &platform_packages { - console.write_stdout(name, Verbosity::Normal); + console_writeln!(console, name); } return Ok(()); } @@ -1621,7 +1613,8 @@ fn show_platform( .unwrap_or(0); for (name, version, _source) in &platform_packages { - console.write_stdout( + console_writeln!( + console, &format!( "{} {}", console_format!("<info>{:<width$}</info>", name, width = name_width), @@ -1631,7 +1624,6 @@ fn show_platform( width = version_width ), ), - Verbosity::Normal, ); } @@ -1661,13 +1653,13 @@ async fn show_available( let lock_path = working_dir.join("composer.lock"); if lock_path.exists() { let lock = mozart_registry::lockfile::LockFile::read_from_file(&lock_path)?; - console.write_stdout( + console_writeln!( + console, &console_format!( "<info>Available versions for locked packages (from Packagist):</info>" ), - Verbosity::Normal, ); - console.write_stdout("", Verbosity::Normal); + console_writeln!(console, ""); let mut all_packages: Vec<&mozart_registry::lockfile::LockedPackage> = lock.packages.iter().collect(); @@ -1686,23 +1678,23 @@ async fn show_available( return Ok(()); } - console.write( + console_writeln_error!( + console, &console_format!( "<warning>No dependencies installed. Try running mozart install or update.</warning>" ), - Verbosity::Normal, ); return Ok(()); } }; - console.write_stdout( + console_writeln!( + console, &console_format!( "<info>Available versions for installed packages (from Packagist):</info>" ), - Verbosity::Normal, ); - console.write_stdout("", Verbosity::Normal); + console_writeln!(console, ""); let format = args.format.as_deref().unwrap_or("text"); @@ -1732,7 +1724,7 @@ async fn show_available( } } let output = serde_json::json!({ "packages": json_entries }); - console.write_stdout(&serde_json::to_string_pretty(&output)?, Verbosity::Normal); + console_writeln!(console, &serde_json::to_string_pretty(&output)?,); return Ok(()); } @@ -1754,10 +1746,7 @@ async fn show_available_versions( ) -> anyhow::Result<()> { let versions = mozart_registry::packagist::fetch_package_versions(pkg_name, repo_cache).await?; if versions.is_empty() { - console.write_stdout( - &format!("No versions found for {pkg_name}"), - Verbosity::Normal, - ); + console_writeln!(console, &format!("No versions found for {pkg_name}"),); return Ok(()); } @@ -1768,18 +1757,18 @@ async fn show_available_versions( "name": pkg_name, "versions": version_strings, }); - console.write_stdout(&serde_json::to_string_pretty(&output)?, Verbosity::Normal); + console_writeln!(console, &serde_json::to_string_pretty(&output)?,); return Ok(()); } - console.write_stdout( + console_writeln!( + console, &console_format!("<info>Available versions for {pkg_name}:</info>"), - Verbosity::Normal, ); for v in &versions { - console.write_stdout( + console_writeln!( + console, &format!(" {}", console_format!("<comment>{}</comment>", &v.version)), - Verbosity::Normal, ); } Ok(()) @@ -1793,12 +1782,12 @@ async fn show_available_versions_inline( match mozart_registry::packagist::fetch_package_versions(pkg_name, repo_cache).await { Ok(versions) => { if versions.is_empty() { - console.write_stdout( + console_writeln!( + console, &format!( "{}: no versions found", console_format!("<info>{}</info>", pkg_name) ), - Verbosity::Normal, ); return; } @@ -1813,23 +1802,23 @@ async fn show_available_versions_inline( } else { String::new() }; - console.write_stdout( + console_writeln!( + console, &format!( "{}: {}{}", console_format!("<info>{}</info>", pkg_name), console_format!("<comment>{}</comment>", &shown.join(", ")), rest ), - Verbosity::Normal, ); } Err(_) => { - console.write_stdout( + console_writeln!( + console, &format!( "{}: (could not fetch from Packagist)", console_format!("<comment>{}</comment>", pkg_name) ), - Verbosity::Normal, ); } } diff --git a/crates/mozart/src/commands/status.rs b/crates/mozart/src/commands/status.rs index 9bccef0..c2f0d69 100644 --- a/crates/mozart/src/commands/status.rs +++ b/crates/mozart/src/commands/status.rs @@ -1,6 +1,6 @@ use clap::Args; use indexmap::IndexMap; -use mozart_core::console::Verbosity; +use mozart_core::console_writeln; use sha1::{Digest, Sha1}; use std::path::{Path, PathBuf}; @@ -176,9 +176,9 @@ pub async fn execute( for pkg_status in &modified_packages { if let Some(ref note) = pkg_status.note { - console.write_stdout(note, Verbosity::Normal); + console_writeln!(console, note); } else { - console.write_stdout(&pkg_status.install_path, Verbosity::Normal); + console_writeln!(console, &pkg_status.install_path); if show_files { let mut sorted_changes: Vec<&FileChange> = pkg_status.changes.iter().collect(); @@ -190,10 +190,7 @@ pub async fn execute( ChangeKind::Added => '+', ChangeKind::Removed => '-', }; - console.write_stdout( - &format!(" {} {}", prefix, change.path), - Verbosity::Normal, - ); + console_writeln!(console, &format!(" {} {}", prefix, change.path),); } } } diff --git a/crates/mozart/src/commands/suggests.rs b/crates/mozart/src/commands/suggests.rs index 678fd91..f00a2a2 100644 --- a/crates/mozart/src/commands/suggests.rs +++ b/crates/mozart/src/commands/suggests.rs @@ -2,8 +2,8 @@ use clap::Args; use indexmap::IndexMap; use indexmap::IndexSet; use mozart_core::console; -use mozart_core::console::Verbosity; use mozart_core::console_format; +use mozart_core::console_writeln; use std::collections::BTreeMap; use std::path::Path; @@ -130,13 +130,13 @@ pub async fn execute( let shown = filtered.len(); let diff = total_before_direct_filter.saturating_sub(shown); if diff > 0 { - console.write_stdout( + console_writeln!( + console, &format!( "{} by transitive dependencies can be shown with {}", console_format!("<info>{diff} additional suggestions</info>"), console_format!("<info>--all</info>"), ), - Verbosity::Normal, ); } } @@ -148,7 +148,7 @@ pub async fn execute( render_by_suggestion(&filtered, console); } else if args.by_package && args.by_suggestion { render_by_package(&filtered, console); - console.write_stdout(&"-".repeat(78), Verbosity::Normal); + console_writeln!(console, &"-".repeat(78)); render_by_suggestion(&filtered, console); } else { // Default: by-package @@ -423,7 +423,7 @@ fn render_list(suggestions: &[&Suggestion], console: &console::Console) { targets.sort_unstable(); targets.dedup(); for t in targets { - console.write_stdout(&console_format!("<info>{}</info>", t), Verbosity::Normal); + console_writeln!(console, &console_format!("<info>{}</info>", t),); } } @@ -434,25 +434,22 @@ fn render_by_package(suggestions: &[&Suggestion], console: &console::Console) { grouped.entry(s.source.as_str()).or_default().push(s); } for (source, items) in &grouped { - console.write_stdout( + console_writeln!( + console, &console_format!("<comment>{}</comment> suggests:", source), - Verbosity::Normal, ); for s in items { let reason = sanitize_reason(&s.reason); if reason.is_empty() { - console.write_stdout( - &console_format!(" - <info>{}</info>", &s.target), - Verbosity::Normal, - ); + console_writeln!(console, &console_format!(" - <info>{}</info>", &s.target),); } else { - console.write_stdout( + console_writeln!( + console, &console_format!(" - <info>{}</info>: {}", &s.target, reason), - Verbosity::Normal, ); } } - console.write_stdout("", Verbosity::Normal); + console_writeln!(console, ""); } } @@ -463,25 +460,25 @@ fn render_by_suggestion(suggestions: &[&Suggestion], console: &console::Console) grouped.entry(s.target.as_str()).or_default().push(s); } for (target, items) in &grouped { - console.write_stdout( + console_writeln!( + console, &console_format!("<info>{}</info> is suggested by:", target), - Verbosity::Normal, ); for s in items { let reason = sanitize_reason(&s.reason); if reason.is_empty() { - console.write_stdout( + console_writeln!( + console, &console_format!(" - <comment>{}</comment>", &s.source), - Verbosity::Normal, ); } else { - console.write_stdout( + console_writeln!( + console, &console_format!(" - <comment>{}</comment>: {}", &s.source, reason), - Verbosity::Normal, ); } } - console.write_stdout("", Verbosity::Normal); + console_writeln!(console, ""); } } diff --git a/crates/mozart/src/commands/validate.rs b/crates/mozart/src/commands/validate.rs index 6bff198..972593f 100644 --- a/crates/mozart/src/commands/validate.rs +++ b/crates/mozart/src/commands/validate.rs @@ -1,6 +1,6 @@ use clap::Args; -use mozart_core::console::Verbosity; use mozart_core::console_format; +use mozart_core::console_writeln; use regex::Regex; use std::path::{Path, PathBuf}; use std::sync::LazyLock; @@ -789,15 +789,12 @@ fn output_result( )); } else if !lock_errors.is_empty() { let kind = if check_lock { "errors" } else { "warnings" }; - console.write_stdout( + console_writeln!( + console, &console_format!("<info>{name} is valid but your composer.lock has some {kind}</info>"), - Verbosity::Normal, ); } else { - console.write_stdout( - &console_format!("<info>{name} is valid</info>"), - Verbosity::Normal, - ); + console_writeln!(console, &console_format!("<info>{name} is valid</info>"),); } // Collect error and warning message lines |
