From 6644f4b554a29c9f4cc1f620a35a8e13b7a95511 Mon Sep 17 00:00:00 2001 From: Eric Swanson Date: Tue, 21 Jan 2025 16:16:46 -0800 Subject: [PATCH] feat: streamline dfx new output Fixes: https://dfinity.atlassian.net/browse/SDK-1940 --- CHANGELOG.md | 2 + src/dfx/src/commands/new.rs | 71 ++++++++++++++++++++------------- src/dfx/src/config/cache.rs | 6 ++- src/dfx/src/lib/manifest.rs | 1 - src/dfx/src/lib/progress_bar.rs | 8 ++-- 5 files changed, 56 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34ef8a43f1..d7a4c4281a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Due to the incompatibility between the APIs on the replica port and the PocketIC port, `dfx info replica-port` no longer works with PocketIC, and the PocketIC port is provided by a new command, `dfx info pocketic-config-port`. +### feat: streamlined `dfx new` output + ### test: adds playwright tests for `dfx new` project frontends The first of a suite of baseline tests to automate testing starter projects. Makes sure that sveltekit, react, vue, and vanilla frontends are compatible with other dfx or asset canister changes. diff --git a/src/dfx/src/commands/new.rs b/src/dfx/src/commands/new.rs index 81b3c28e88..ba628638ce 100644 --- a/src/dfx/src/commands/new.rs +++ b/src/dfx/src/commands/new.rs @@ -22,11 +22,11 @@ use dialoguer::{FuzzySelect, MultiSelect}; use fn_error_context::context; use indicatif::HumanBytes; use semver::Version; -use slog::{info, trace, warn, Logger}; +use slog::{debug, error, info, trace, warn, Logger}; use std::collections::{BTreeMap, HashMap}; use std::io::{self, IsTerminal, Read}; use std::path::{Path, PathBuf}; -use std::process::{Command, ExitStatus, Stdio}; +use std::process::{Command, Output, Stdio}; use std::time::Duration; use tar::Archive; use walkdir::WalkDir; @@ -200,7 +200,7 @@ pub fn init_git(log: &Logger, project_name: &Path) -> DfxResult { .status(); if init_status.is_ok() && init_status.unwrap().success() { - info!(log, "Initializing git repository..."); + debug!(log, "Initializing git repository..."); std::process::Command::new("git") .arg("add") .current_dir(project_name) @@ -675,28 +675,48 @@ fn run_post_create_command( .as_ref() .map(|msg| env.new_spinner(msg.clone().into())); - let status = cmd - .stderr(Stdio::inherit()) - .stdout(Stdio::inherit()) - .status() + let child = cmd + .stderr(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() .with_context(|| { format!( - "Failed to run post-create command '{}' for project template '{}.", + "Failed to spawn post-create command '{}' for project template '{}'.", &command, &project_template.name ) - }); + })?; + let output = child.wait_with_output().with_context(|| { + format!( + "Failed to run post-create command '{}' for project template '{}'.", + &command, &project_template.name + ) + }); if let Some(spinner) = spinner { - let message = match status { - Ok(status) if status.success() => "Done.", - _ => "Failed.", - }; - spinner.finish_with_message(message.into()); + spinner.finish_and_clear(); } + + if let Ok(output) = &output { + if !output.status.success() { + let stdout = String::from_utf8_lossy(&output.stdout); + let stderr = String::from_utf8_lossy(&output.stderr); + + let msg = format!( + "Post-create ommand '{}' failed.\n--- stdout ---\n{}\n--- stderr ---\n{}", + &command, stdout, stderr + ); + if project_template.post_create_failure_warning.is_some() { + warn!(log, "{}", msg); + } else { + error!(log, "{}", msg); + } + } + } + if let Some(warning) = &project_template.post_create_failure_warning { - warn_on_post_create_error(log, status, &command, warning); + warn_on_post_create_error(log, output, &command, warning); } else { - fail_on_post_create_error(command, status)?; + fail_on_post_create_error(command, output)?; } } Ok(()) @@ -704,13 +724,13 @@ fn run_post_create_command( fn warn_on_post_create_error( log: &Logger, - status: Result, + output: Result, command: &str, warning: &str, ) { - match status { - Ok(status) if status.success() => {} - Ok(status) => match status.code() { + match output { + Ok(output) if output.status.success() => {} + Ok(output) => match output.status.code() { Some(code) => { warn!( log, @@ -730,13 +750,10 @@ fn warn_on_post_create_error( } } -fn fail_on_post_create_error( - command: String, - status: Result, -) -> Result<(), Error> { - let status = status?; - if !status.success() { - match status.code() { +fn fail_on_post_create_error(command: String, output: Result) -> Result<(), Error> { + let output = output?; + if !output.status.success() { + match output.status.code() { Some(code) => { bail!("Post-create command '{command}' failed with exit code {code}.") } diff --git a/src/dfx/src/config/cache.rs b/src/dfx/src/config/cache.rs index 8185b6e172..d128ffef8c 100644 --- a/src/dfx/src/config/cache.rs +++ b/src/dfx/src/config/cache.rs @@ -153,7 +153,11 @@ pub fn install_version(v: &str, force: bool) -> Result { + ($(#[$meta:meta])* $name: ident) => { + $(#[$meta])* pub fn $name(&self) { if let Some(ref progress_bar) = self.bar { progress_bar.$name(); @@ -14,7 +15,8 @@ macro_rules! forward_fn_impl { } }; - ($name: ident, $( $tname: ident: $t: ty )+) => { + ($(#[$meta:meta])* $name: ident, $( $tname: ident: $t: ty )+) => { + $(#[$meta])* pub fn $name(&self, $($tname: $t,)+) { if let Some(ref progress_bar) = self.bar { progress_bar.$name( $($tname,)+ ); @@ -37,7 +39,7 @@ impl ProgressBar { } forward_fn_impl!(finish_and_clear); - forward_fn_impl!(finish_with_message, message: Cow<'static, str>); + forward_fn_impl!(#[allow(dead_code)] finish_with_message, message: Cow<'static, str>); pub fn discard() -> Self { ProgressBar { bar: None }