Skip to content

Commit

Permalink
feat: streamline dfx new output
Browse files Browse the repository at this point in the history
  • Loading branch information
ericswanson-dfinity committed Jan 22, 2025
1 parent 9900826 commit 6644f4b
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 32 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
71 changes: 44 additions & 27 deletions src/dfx/src/commands/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -675,42 +675,62 @@ 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(())
}

fn warn_on_post_create_error(
log: &Logger,
status: Result<ExitStatus, Error>,
output: Result<Output, Error>,
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,
Expand All @@ -730,13 +750,10 @@ fn warn_on_post_create_error(
}
}

fn fail_on_post_create_error(
command: String,
status: Result<ExitStatus, Error>,
) -> Result<(), Error> {
let status = status?;
if !status.success() {
match status.code() {
fn fail_on_post_create_error(command: String, output: Result<Output, Error>) -> 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}.")
}
Expand Down
6 changes: 5 additions & 1 deletion src/dfx/src/config/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,11 @@ pub fn install_version(v: &str, force: bool) -> Result<PathBuf, InstallCacheErro

if dfx_core::fs::rename(temp_p.as_path(), &p).is_ok() {
if let Some(b) = b {
b.finish_with_message(format!("Installed dfx {} to cache.", v));
if force {
b.finish_with_message(format!("Installed dfx {} to cache.", v));
} else {
b.finish_and_clear();
}
}
} else {
dfx_core::fs::remove_dir_all(temp_p.as_path())?;
Expand Down
1 change: 0 additions & 1 deletion src/dfx/src/lib/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ pub fn get_latest_version(
let manifest_url = url
.join("manifest.json")
.map_err(|e| error_invalid_argument!("invalid manifest URL: {}", e))?;
println!("Fetching manifest {}", manifest_url);

let b = ProgressBar::new_spinner();
b.set_draw_target(ProgressDrawTarget::stderr());
Expand Down
8 changes: 5 additions & 3 deletions src/dfx/src/lib/progress_bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ pub struct ProgressBar {
}

macro_rules! forward_fn_impl {
($name: ident) => {
($(#[$meta:meta])* $name: ident) => {
$(#[$meta])*
pub fn $name(&self) {
if let Some(ref progress_bar) = self.bar {
progress_bar.$name();
}
}
};

($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,)+ );
Expand All @@ -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 }
Expand Down

0 comments on commit 6644f4b

Please sign in to comment.