From cc8f22ff7f1d9ed32e14f5b59a5498f8aa653091 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Mon, 23 Feb 2026 01:45:14 +0900 Subject: fix(show): validate option combinations and support --ignore wildcards - Reject invalid option combinations: --direct with --all/--platform/--available, --tree with --all/--available/--latest/--path, --self with package argument - Reject unsupported --format values (only "text" and "json" allowed) - Warn when --ignore is used without --outdated - Support wildcard patterns in --ignore values via matches_wildcard Co-Authored-By: Claude Opus 4.6 --- crates/mozart/src/commands/require.rs | 7 ++-- crates/mozart/src/commands/show.rs | 66 ++++++++++++++++++++++++++++++----- 2 files changed, 62 insertions(+), 11 deletions(-) (limited to 'crates/mozart') diff --git a/crates/mozart/src/commands/require.rs b/crates/mozart/src/commands/require.rs index 16d865f..ef5ff04 100644 --- a/crates/mozart/src/commands/require.rs +++ b/crates/mozart/src/commands/require.rs @@ -679,9 +679,10 @@ pub async fn execute( eprintln!("Warning: Failed to revert composer.json: {revert_err}"); } if let Some(ref lock_content) = original_composer_lock - && let Err(revert_err) = std::fs::write(&lock_path_for_backup, lock_content) { - eprintln!("Warning: Failed to revert composer.lock: {revert_err}"); - } + && let Err(revert_err) = std::fs::write(&lock_path_for_backup, lock_content) + { + eprintln!("Warning: Failed to revert composer.lock: {revert_err}"); + } } return Err(mozart_core::exit_code::bail( mozart_core::exit_code::DEPENDENCY_RESOLUTION_FAILED, diff --git a/crates/mozart/src/commands/show.rs b/crates/mozart/src/commands/show.rs index 346c7b7..9eae36e 100644 --- a/crates/mozart/src/commands/show.rs +++ b/crates/mozart/src/commands/show.rs @@ -112,6 +112,54 @@ pub async fn execute( anyhow::bail!("Only one of --major-only, --minor-only or --patch-only can be used at once"); } + // Fix 1: --direct with --all, --platform, or --available + if args.direct && (args.all || args.platform || args.available) { + anyhow::bail!( + "The --direct (-D) option is not usable in combination with --all, --platform (-p) or --available (-a)" + ); + } + + // Fix 2: --tree with --all or --available + if args.tree && (args.all || args.available) { + anyhow::bail!( + "The --tree (-t) option is not usable in combination with --all or --available (-a)" + ); + } + + // Fix 3: --tree with --latest + if args.tree && args.latest { + anyhow::bail!("The --tree (-t) option is not usable in combination with --latest (-l)"); + } + + // Fix 4: --tree with --path + if args.tree && args.path { + anyhow::bail!("The --tree (-t) option is not usable in combination with --path (-P)"); + } + + // Fix 5: --format with invalid value + if let Some(ref fmt) = args.format + && fmt != "text" && fmt != "json" { + anyhow::bail!( + "Unsupported format \"{}\". See help for supported formats.", + fmt + ); + } + + // Fix 6: --self with a package argument + if args.self_info && args.package.is_some() { + anyhow::bail!("You cannot use --self together with a package name"); + } + + // Fix 8: --ignore without --outdated warning + if !args.ignore.is_empty() && !args.outdated { + eprintln!( + "{}", + console_format!( + "You are using the option \"ignore\" for action other than \"outdated\", it will be ignored." + ) + ); + } + let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), None => std::env::current_dir()?, @@ -280,13 +328,14 @@ async fn show_installed_package_list( return Ok(()); } - // Build ignore set - let ignore_set: HashSet = args.ignore.iter().map(|n| n.to_lowercase()).collect(); - // Gather entries (fetch latest if needed, apply outdated filter) let mut entries: Vec = Vec::new(); for pkg in packages { - if ignore_set.contains(&pkg.name.to_lowercase()) { + if args + .ignore + .iter() + .any(|pattern| matches_wildcard(&pkg.name, pattern)) + { continue; } @@ -736,13 +785,14 @@ async fn show_locked_package_list( return Ok(()); } - // Build ignore set - let ignore_set: HashSet = args.ignore.iter().map(|n| n.to_lowercase()).collect(); - // Gather entries let mut entries: Vec = Vec::new(); for pkg in packages { - if ignore_set.contains(&pkg.name.to_lowercase()) { + if args + .ignore + .iter() + .any(|pattern| matches_wildcard(&pkg.name, pattern)) + { continue; } -- cgit v1.3.1