Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/vp_global_cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1092,7 +1092,7 @@ pub async fn run_command_with_options(
} else {
command_with_help_with_options(render_options).print_help().ok();
}
println!();
vp_shared::output::print_stdout_line(format_args!(""));
// Return a successful exit status since help was requested implicitly
return Ok(std::process::ExitStatus::default());
};
Expand Down
15 changes: 11 additions & 4 deletions crates/vp_global_cli/src/commands/env/current.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,15 @@ struct PackageManagerInfo {
}

fn print_rows(title: &str, rows: &[(String, String)]) {
println!("{}", help::render_heading(title));
vp_shared::output::print_stdout_line(format_args!("{}", help::render_heading(title)));
let label_width = rows.iter().map(|(label, _)| label.chars().count()).max().unwrap_or(0);
for (label, value) in rows {
let padding = " ".repeat(label_width.saturating_sub(label.chars().count()));
println!(" {}{} {value}", help::accent(label), padding);
vp_shared::output::print_stdout_line(format_args!(
" {}{} {value}",
help::accent(label),
padding
));
}
}

Expand Down Expand Up @@ -108,7 +112,10 @@ pub async fn execute(
};

if json {
println!("{}", serde_json::to_string_pretty(&CurrentEnvInfo { node, package_manager })?);
vp_shared::output::print_stdout_line(format_args!(
"{}",
serde_json::to_string_pretty(&CurrentEnvInfo { node, package_manager })?
));
return Ok(ExitStatus::default());
}

Expand All @@ -126,7 +133,7 @@ pub async fn execute(
}
if let Some(package_manager) = package_manager {
if scope.includes_node() {
println!();
vp_shared::output::print_stdout_line(format_args!(""));
}
let mut rows = vec![
("Name".into(), package_manager.name),
Expand Down
45 changes: 31 additions & 14 deletions crates/vp_global_cli/src/commands/env/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ pub async fn execute(values: Vec<String>, unset: bool) -> Result<ExitStatus, Err
}
save_config(&config).await?;
crate::shim::invalidate_cache();
println!("Cleared selected environment defaults.");
vp_shared::output::print_stdout_line(format_args!(
"Cleared selected environment defaults."
));
return Ok(ExitStatus::default());
}

Expand Down Expand Up @@ -67,7 +69,7 @@ pub async fn execute(values: Vec<String>, unset: bool) -> Result<ExitStatus, Err
save_config(&config).await?;
crate::shim::invalidate_cache();
for update in updates {
println!("\u{2713} {update}");
vp_shared::output::print_stdout_line(format_args!("\u{2713} {update}"));
}
Ok(ExitStatus::default())
}
Expand All @@ -79,27 +81,35 @@ async fn show_default(scope: EnvScope) -> Result<ExitStatus, Error> {
match config.default_node_version.as_deref() {
Some(version) => {
has_configured_default = true;
println!("Default Node.js version: {version}");
vp_shared::output::print_stdout_line(format_args!(
"Default Node.js version: {version}"
));
if matches!(version, "lts" | "latest") {
let provider = vp_js_runtime::NodeProvider::new();
if let Ok(resolved) =
super::config::resolve_version_alias(version, &provider).await
{
println!(" Currently resolves to: {resolved}");
vp_shared::output::print_stdout_line(format_args!(
" Currently resolves to: {resolved}"
));
}
}
}
None => {
let provider = vp_js_runtime::NodeProvider::new();
match provider.resolve_latest_version().await {
Ok(version) => {
println!(
vp_shared::output::print_stdout_line(format_args!(
"No default Node.js version configured. Using latest LTS ({version})."
);
));
}
Err(_) => println!("No default Node.js version configured."),
Err(_) => vp_shared::output::print_stdout_line(format_args!(
"No default Node.js version configured."
)),
}
println!(" Run 'vp env default <version>' to set a default.");
vp_shared::output::print_stdout_line(format_args!(
" Run 'vp env default <version>' to set a default."
));
}
}
}
Expand All @@ -115,20 +125,27 @@ async fn show_default(scope: EnvScope) -> Result<ExitStatus, Error> {
.collect::<Vec<_>>();
if configured.is_empty() {
match scope {
EnvScope::PackageManager(kind) => {
println!("Default {kind} version: not configured")
}
_ => println!("Package manager defaults: not configured"),
EnvScope::PackageManager(kind) => vp_shared::output::print_stdout_line(
format_args!("Default {kind} version: not configured"),
),
_ => vp_shared::output::print_stdout_line(format_args!(
"Package manager defaults: not configured"
)),
}
} else {
for (package_manager, version) in configured {
has_configured_default = true;
println!("Default {package_manager} version: {version}");
vp_shared::output::print_stdout_line(format_args!(
"Default {package_manager} version: {version}"
));
}
}
}
if has_configured_default {
println!(" Set via: {}", get_config_path()?.as_path().display());
vp_shared::output::print_stdout_line(format_args!(
" Set via: {}",
get_config_path()?.as_path().display()
));
}
Ok(ExitStatus::default())
}
Expand Down
126 changes: 85 additions & 41 deletions crates/vp_global_cli/src/commands/env/doctor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ const KEY_WIDTH: usize = 18;

/// Print a section header (bold, with blank line before).
fn print_section(name: &str) {
println!();
println!("{}", style(&name).bold());
vp_shared::output::print_stdout_line(format_args!(""));
vp_shared::output::print_stdout_line(format_args!("{}", style(&name).bold()));
}

/// Print an aligned key-value line with a status indicator.
Expand All @@ -53,11 +53,11 @@ fn print_section(name: &str) {
/// Use `" "` for informational lines with no status.
fn print_check(status: &str, key: &str, value: &str) {
if status.trim().is_empty() {
println!(" {key:<KEY_WIDTH$}{value}");
vp_shared::output::print_stdout_line(format_args!(" {key:<KEY_WIDTH$}{value}"));
} else if key.trim().is_empty() {
println!(" {status} {value}");
vp_shared::output::print_stdout_line(format_args!(" {status} {value}"));
} else {
println!(" {status} {key:<KEY_WIDTH$}{value}");
vp_shared::output::print_stdout_line(format_args!(" {status} {key:<KEY_WIDTH$}{value}"));
}
}

Expand All @@ -71,7 +71,10 @@ fn print_package_manager_mode(key: &str, mode: ShimMode) {

/// Print a continuation/hint line (dimmed).
fn print_hint(text: &str) {
println!(" {}", style(format!("note: {text}")).dim());
vp_shared::output::print_stdout_line(format_args!(
" {}",
style(format!("note: {text}")).dim()
));
}

/// Abbreviate home directory to `~` for display.
Expand All @@ -90,7 +93,7 @@ pub async fn execute(cwd: AbsolutePathBuf, scope: Option<String>) -> Result<Exit
let mut has_errors = false;

// Section: Installation
println!("{}", style("Installation").bold());
vp_shared::output::print_stdout_line(format_args!("{}", style("Installation").bold()));
if crate::homebrew::owns_current_exe() {
print_check(" ", "CLI source", "Homebrew");
if let Ok(binary) = std::env::current_exe().and_then(std::fs::canonicalize) {
Expand Down Expand Up @@ -146,17 +149,20 @@ pub async fn execute(cwd: AbsolutePathBuf, scope: Option<String>) -> Result<Exit
}

// Summary
println!();
vp_shared::output::print_stdout_line(format_args!(""));
if has_errors {
println!(
vp_shared::output::print_stdout_line(format_args!(
"{}",
style("\u{2717} Some issues found. Run the suggested commands to fix them.")
.red()
.bold()
);
));
Ok(super::exit_status(1))
} else {
println!("{}", style("\u{2713} All checks passed").green().bold());
vp_shared::output::print_stdout_line(format_args!(
"{}",
style("\u{2713} All checks passed").green().bold()
));
Ok(ExitStatus::default())
}
}
Expand Down Expand Up @@ -559,7 +565,7 @@ async fn check_path(scope: EnvScope) -> bool {
&style("not in PATH").red().to_string(),
);
print_hint(&format!("Expected: {bin_display}"));
println!();
vp_shared::output::print_stdout_line(format_args!(""));
print_path_fix(&vp_shared::EnvConfig::get().dirs.config);
return false;
}
Expand Down Expand Up @@ -630,28 +636,48 @@ fn print_path_fix(env_dir: &vt_path::AbsolutePath) {
env_path
};

println!(" {}", style("Add to your shell profile (~/.zshrc, ~/.bashrc, etc.):").dim());
println!();
println!(" . \"{env_path}/env\"");
println!();
println!(" {}", style("For fish shell, add to ~/.config/fish/config.fish:").dim());
println!();
println!(" source \"{env_path}/env.fish\"");
println!();
println!(" {}", style("For Nushell, add to ~/.config/nushell/config.nu:").dim());
println!();
println!(" source '{env_path}/env.nu'");
println!();
println!(" {}", style("Then restart your terminal.").dim());
vp_shared::output::print_stdout_line(format_args!(
" {}",
style("Add to your shell profile (~/.zshrc, ~/.bashrc, etc.):").dim()
));
vp_shared::output::print_stdout_line(format_args!(""));
vp_shared::output::print_stdout_line(format_args!(" . \"{env_path}/env\""));
vp_shared::output::print_stdout_line(format_args!(""));
vp_shared::output::print_stdout_line(format_args!(
" {}",
style("For fish shell, add to ~/.config/fish/config.fish:").dim()
));
vp_shared::output::print_stdout_line(format_args!(""));
vp_shared::output::print_stdout_line(format_args!(" source \"{env_path}/env.fish\""));
vp_shared::output::print_stdout_line(format_args!(""));
vp_shared::output::print_stdout_line(format_args!(
" {}",
style("For Nushell, add to ~/.config/nushell/config.nu:").dim()
));
vp_shared::output::print_stdout_line(format_args!(""));
vp_shared::output::print_stdout_line(format_args!(" source '{env_path}/env.nu'"));
vp_shared::output::print_stdout_line(format_args!(""));
vp_shared::output::print_stdout_line(format_args!(
" {}",
style("Then restart your terminal.").dim()
));
}

#[cfg(windows)]
{
let _ = env_dir;
println!(" {}", style("Add the bin directory to your PATH via:").dim());
println!(" System Properties -> Environment Variables -> Path");
println!();
println!(" {}", style("Then restart your terminal.").dim());
vp_shared::output::print_stdout_line(format_args!(
" {}",
style("Add the bin directory to your PATH via:").dim()
));
vp_shared::output::print_stdout_line(format_args!(
" System Properties -> Environment Variables -> Path"
));
vp_shared::output::print_stdout_line(format_args!(""));
vp_shared::output::print_stdout_line(format_args!(
" {}",
style("Then restart your terminal.").dim()
));
}
}

Expand Down Expand Up @@ -705,30 +731,48 @@ fn print_ide_setup_guidance(env_dir: &vt_path::AbsolutePath) {
"",
&style("GUI applications may not see shell PATH changes.").yellow().to_string(),
);
println!();
vp_shared::output::print_stdout_line(format_args!(""));

#[cfg(target_os = "macos")]
{
println!(" {}", style("macOS:").dim());
println!(" {}", style("Add to ~/.zshenv or ~/.profile:").dim());
println!(" . \"{env_path}/env\"");
println!(" {}", style("Then restart your IDE to apply changes.").dim());
vp_shared::output::print_stdout_line(format_args!(" {}", style("macOS:").dim()));
vp_shared::output::print_stdout_line(format_args!(
" {}",
style("Add to ~/.zshenv or ~/.profile:").dim()
));
vp_shared::output::print_stdout_line(format_args!(" . \"{env_path}/env\""));
vp_shared::output::print_stdout_line(format_args!(
" {}",
style("Then restart your IDE to apply changes.").dim()
));
}

#[cfg(target_os = "linux")]
{
println!(" {}", style("Linux:").dim());
println!(" {}", style("Add to ~/.profile:").dim());
println!(" . \"{env_path}/env\"");
println!(" {}", style("Then log out and log back in for changes to take effect.").dim());
vp_shared::output::print_stdout_line(format_args!(" {}", style("Linux:").dim()));
vp_shared::output::print_stdout_line(format_args!(
" {}",
style("Add to ~/.profile:").dim()
));
vp_shared::output::print_stdout_line(format_args!(" . \"{env_path}/env\""));
vp_shared::output::print_stdout_line(format_args!(
" {}",
style("Then log out and log back in for changes to take effect.").dim()
));
}

// Fallback for other Unix platforms
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
{
println!(" {}", style("Add to your shell profile:").dim());
println!(" . \"{env_path}/env\"");
println!(" {}", style("Then restart your IDE to apply changes.").dim());
vp_shared::output::print_stdout_line(format_args!(
" {}",
style("Add to your shell profile:").dim()
));
vp_shared::output::print_stdout_line(format_args!(" . \"{env_path}/env\""));
vp_shared::output::print_stdout_line(format_args!(
" {}",
style("Then restart your IDE to apply changes.").dim()
));
}
}

Expand Down
10 changes: 5 additions & 5 deletions crates/vp_global_cli/src/commands/env/lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ pub(crate) async fn install(
}
};
if let Some((version, from_session_override)) = resolved {
println!("Installing Node.js v{version}...");
vp_shared::output::print_stdout_line(format_args!("Installing Node.js v{version}..."));
vp_js_runtime::download_runtime(vp_js_runtime::JsRuntimeType::Node, &version).await?;
println!("Installed Node.js v{version}");
vp_shared::output::print_stdout_line(format_args!("Installed Node.js v{version}"));
if from_session_override {
eprintln!("Note: Installed from session override.");
eprintln!("Run `vp env use --unset` to revert to project version resolution.");
Expand Down Expand Up @@ -83,9 +83,9 @@ pub(crate) async fn install(
})
};
if let Some((kind, version, hash)) = requested {
println!("Installing {kind} v{version}...");
vp_shared::output::print_stdout_line(format_args!("Installing {kind} v{version}..."));
download_package_manager(kind, &version, hash.as_deref()).await?;
println!("Installed {kind} v{version}");
vp_shared::output::print_stdout_line(format_args!("Installed {kind} v{version}"));
}
}

Expand Down Expand Up @@ -133,7 +133,7 @@ pub(crate) async fn uninstall(specs: Vec<String>) -> Result<ExitStatus, Error> {
}
for (label, target) in targets {
tokio::fs::remove_dir_all(target.as_path()).await?;
println!("Uninstalled {label}");
vp_shared::output::print_stdout_line(format_args!("Uninstalled {label}"));
}
Ok(ExitStatus::default())
}
Loading
Loading