aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-23 14:50:01 +0900
committernsfisis <nsfisis@gmail.com>2026-02-23 14:50:01 +0900
commit7e45efd8a1f488b1a684f9efe31ff39009fc9e54 (patch)
treeba3a9cf2af9c4c383ccd7e68ab52e7e7d8de1601
parent6cf5f6363f416b558753d44bee9ec536ddf7c06c (diff)
downloadphp-mozart-7e45efd8a1f488b1a684f9efe31ff39009fc9e54.tar.gz
php-mozart-7e45efd8a1f488b1a684f9efe31ff39009fc9e54.tar.zst
php-mozart-7e45efd8a1f488b1a684f9efe31ff39009fc9e54.zip
fix(cli): align install/update output with Composer conventions
- Migrate eprintln\! to Console for consistent colored output - Use Composer terminology in lock file operations: Locking instead of Installing, Upgrading/Downgrading instead of Updating - Add is_downgrade() helper to distinguish upgrades from downgrades - Pass Console through install_from_lock for proper output handling Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
-rw-r--r--crates/mozart/src/commands/create_project.rs1
-rw-r--r--crates/mozart/src/commands/install.rs81
-rw-r--r--crates/mozart/src/commands/remove.rs2
-rw-r--r--crates/mozart/src/commands/require.rs1
-rw-r--r--crates/mozart/src/commands/update.rs71
5 files changed, 97 insertions, 59 deletions
diff --git a/crates/mozart/src/commands/create_project.rs b/crates/mozart/src/commands/create_project.rs
index 2a8ce4f..da8108c 100644
--- a/crates/mozart/src/commands/create_project.rs
+++ b/crates/mozart/src/commands/create_project.rs
@@ -505,6 +505,7 @@ pub async fn execute(
download_only: false,
prefer_source: args.prefer_source,
},
+ console,
)
.await?;
diff --git a/crates/mozart/src/commands/install.rs b/crates/mozart/src/commands/install.rs
index bf35788..97ecd80 100644
--- a/crates/mozart/src/commands/install.rs
+++ b/crates/mozart/src/commands/install.rs
@@ -353,6 +353,7 @@ pub async fn install_from_lock(
working_dir: &Path,
vendor_dir: &Path,
config: &InstallConfig,
+ console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
let dev_mode = config.dev_mode;
@@ -365,11 +366,11 @@ pub async fn install_from_lock(
// Print install mode header
if dev_mode {
- eprintln!("Installing dependencies from lock file (including require-dev)");
+ console.info("Installing dependencies from lock file (including require-dev)");
} else {
- eprintln!("Installing dependencies from lock file");
+ console.info("Installing dependencies from lock file");
}
- eprintln!("Verifying lock file contents can be installed on current platform.");
+ console.info("Verifying lock file contents can be installed on current platform.");
// Step 2: Warn about platform requirements
warn_platform_requirements(
@@ -395,20 +396,17 @@ pub async fn install_from_lock(
.collect();
if installs.is_empty() && updates.is_empty() && removals.is_empty() {
- eprintln!("Nothing to install, update or remove");
+ console.info("Nothing to install, update or remove");
} else {
- eprintln!(
- "{}",
- console_format!(
- "<info>Package operations: {} install{}, {} update{}, {} removal{}</info>",
- installs.len(),
- if installs.len() == 1 { "" } else { "s" },
- updates.len(),
- if updates.len() == 1 { "" } else { "s" },
- removals.len(),
- if removals.len() == 1 { "" } else { "s" },
- )
- );
+ console.info(&console_format!(
+ "<info>Package operations: {} install{}, {} update{}, {} removal{}</info>",
+ installs.len(),
+ if installs.len() == 1 { "" } else { "s" },
+ updates.len(),
+ if updates.len() == 1 { "" } else { "s" },
+ removals.len(),
+ if removals.len() == 1 { "" } else { "s" },
+ ));
}
// Step 6: Execute operations (unless dry_run)
@@ -417,25 +415,41 @@ pub async fn install_from_lock(
match action {
Action::Skip => {}
Action::Install => {
- eprintln!(" - Would install {} ({})", pkg.name, pkg.version);
+ console.info(&console_format!(
+ " - Would install <info>{}</info> (<comment>{}</comment>)",
+ pkg.name,
+ pkg.version
+ ));
}
Action::Update => {
- eprintln!(" - Would update {} ({})", pkg.name, pkg.version);
+ console.info(&console_format!(
+ " - Would upgrade <info>{}</info> (<comment>{}</comment>)",
+ pkg.name,
+ pkg.version
+ ));
}
}
}
for name in &removals {
- eprintln!(" - Would remove {name}");
+ console.info(&console_format!(" - Would remove <info>{}</info>", name));
}
} else {
for (pkg, action) in &ops {
match action {
Action::Skip => continue,
Action::Install => {
- eprintln!(" - Installing {} ({})", pkg.name, pkg.version);
+ console.info(&console_format!(
+ " - Installing <info>{}</info> (<comment>{}</comment>)",
+ pkg.name,
+ pkg.version
+ ));
}
Action::Update => {
- eprintln!(" - Updating {} ({})", pkg.name, pkg.version);
+ console.info(&console_format!(
+ " - Upgrading <info>{}</info> (<comment>{}</comment>)",
+ pkg.name,
+ pkg.version
+ ));
}
}
@@ -485,7 +499,7 @@ pub async fn install_from_lock(
// Handle removals
for name in &removals {
- eprintln!(" - Removing {name}");
+ console.info(&console_format!(" - Removing <info>{}</info>", name));
let pkg_dir = vendor_dir.join(name);
if pkg_dir.exists() {
std::fs::remove_dir_all(&pkg_dir)?;
@@ -516,22 +530,16 @@ pub async fn install_from_lock(
// Step 9: Generate autoloader (unless no_autoloader or download_only)
if !config.no_autoloader && !config.download_only {
- eprintln!("Generating autoload files");
+ console.info("Generating autoload files");
if config.classmap_authoritative {
- eprintln!(
- "{}",
- console_format!(
- "<info>Classmap-authoritative mode: autoloader will only look up classes in the classmap.</info>"
- )
- );
+ console.info(&console_format!(
+ "<info>Classmap-authoritative mode: autoloader will only look up classes in the classmap.</info>"
+ ));
} else if config.optimize_autoloader {
- eprintln!(
- "{}",
- console_format!(
- "<info>Optimize autoloader: classmap scanning is not yet fully supported. PSR-4/PSR-0 autoloading will still be used.</info>"
- )
- );
+ console.info(&console_format!(
+ "<info>Optimize autoloader: classmap scanning is not yet fully supported. PSR-4/PSR-0 autoloading will still be used.</info>"
+ ));
}
let suffix = lock.content_hash.clone();
@@ -551,8 +559,6 @@ pub async fn install_from_lock(
platform_check: mozart_autoload::autoload::PlatformCheckMode::Full,
ignore_platform_reqs: config.ignore_platform_reqs,
})?;
-
- eprintln!("Generated autoload files");
}
}
@@ -690,6 +696,7 @@ pub async fn execute(
download_only: args.download_only,
prefer_source,
},
+ console,
)
.await
}
diff --git a/crates/mozart/src/commands/remove.rs b/crates/mozart/src/commands/remove.rs
index 6d3b5e2..4808dd0 100644
--- a/crates/mozart/src/commands/remove.rs
+++ b/crates/mozart/src/commands/remove.rs
@@ -441,6 +441,7 @@ pub async fn execute(
download_only: false,
prefer_source: false,
},
+ console,
)
.await?;
}
@@ -582,6 +583,7 @@ async fn remove_unused(
download_only: false,
prefer_source: false,
},
+ console,
)
.await?;
}
diff --git a/crates/mozart/src/commands/require.rs b/crates/mozart/src/commands/require.rs
index 15b5f1c..46914cf 100644
--- a/crates/mozart/src/commands/require.rs
+++ b/crates/mozart/src/commands/require.rs
@@ -873,6 +873,7 @@ pub async fn execute(
download_only: false,
prefer_source: args.prefer_source,
},
+ console,
)
.await?;
}
diff --git a/crates/mozart/src/commands/update.rs b/crates/mozart/src/commands/update.rs
index c1901cd..6155306 100644
--- a/crates/mozart/src/commands/update.rs
+++ b/crates/mozart/src/commands/update.rs
@@ -682,6 +682,18 @@ pub fn apply_patch_only(
.collect()
}
+/// Determine whether a version change is a downgrade.
+///
+/// Parses both versions and compares them; returns true if `new_version` is
+/// lower than `old_version`.
+fn is_downgrade(old_version: &str, new_version: &str) -> bool {
+ use mozart_semver::Version;
+ match (Version::parse(old_version), Version::parse(new_version)) {
+ (Ok(old), Ok(new)) => new < old,
+ _ => false,
+ }
+}
+
/// Extract (major, minor) from a normalized version string.
fn major_minor(version: &str) -> (u64, u64) {
let parts: Vec<&str> = version.split('.').collect();
@@ -845,8 +857,6 @@ pub async fn execute(
} else {
console.info("Updating dependencies");
}
- console.info("Resolving dependencies...");
-
let mut resolved = match resolver::resolve(&request).await {
Ok(packages) => packages,
Err(e) => {
@@ -1013,7 +1023,7 @@ pub async fn execute(
.collect();
console.info(&format!(
- "Package operations: {} install{}, {} update{}, {} removal{}",
+ "Lock file operations: {} install{}, {} update{}, {} removal{}",
installs.len(),
if installs.len() == 1 { "" } else { "s" },
updates.len(),
@@ -1023,44 +1033,60 @@ pub async fn execute(
));
// Print individual change lines
- let prefix = if args.dry_run { "Would" } else { "" };
for change in &changes {
match &change.kind {
ChangeKind::Remove { old_version } => {
if args.dry_run {
- console.info(&format!(
- " - {} remove {} ({})",
- prefix, change.name, old_version
+ console.info(&console_format!(
+ " - Would remove <info>{}</info> (<comment>{}</comment>)",
+ change.name,
+ old_version
));
} else {
- console.info(&format!(" - Removing {} ({})", change.name, old_version));
+ console.info(&console_format!(
+ " - Removing <info>{}</info> (<comment>{}</comment>)",
+ change.name,
+ old_version
+ ));
}
}
ChangeKind::Install { new_version } => {
if args.dry_run {
- console.info(&format!(
- " - {} install {} ({})",
- prefix, change.name, new_version
+ console.info(&console_format!(
+ " - Would lock <info>{}</info> (<comment>{}</comment>)",
+ change.name,
+ new_version
));
} else {
- console.info(&format!(" - Installing {} ({})", change.name, new_version));
+ console.info(&console_format!(
+ " - Locking <info>{}</info> (<comment>{}</comment>)",
+ change.name,
+ new_version
+ ));
}
}
ChangeKind::Update {
old_version,
new_version,
} => {
- if args.dry_run {
- console.info(&format!(
- " - {} update {} ({} => {})",
- prefix, change.name, old_version, new_version
- ));
+ let direction = if is_downgrade(old_version, new_version) {
+ if args.dry_run {
+ "Would downgrade"
+ } else {
+ "Downgrading"
+ }
+ } else if args.dry_run {
+ "Would upgrade"
} else {
- console.info(&format!(
- " - Updating {} ({} => {})",
- change.name, old_version, new_version
- ));
- }
+ "Upgrading"
+ };
+ console.info(&console_format!(
+ " - {} <info>{}</info> (<comment>{}</comment> => <comment>{}</comment>)",
+ direction,
+ change.name,
+ old_version,
+ new_version
+ ));
}
ChangeKind::Unchanged => {}
}
@@ -1191,6 +1217,7 @@ pub async fn execute(
download_only: false,
prefer_source,
},
+ console,
)
.await?;
}