Skip to content
This repository has been archived by the owner on Aug 28, 2024. It is now read-only.

Commit

Permalink
feat(zk_toolbox): use low level command for running verbose command" (m…
Browse files Browse the repository at this point in the history
…atter-labs#2358)

## What ❔

<!-- What are the changes this PR brings about? -->
<!-- Example: This PR adds a PR template to the repo. -->
<!-- (For bigger PRs adding more context is appreciated) -->

## Why ❔

<!-- Why are these changes done? What goal do they contribute to? What
are the principles behind them? -->
<!-- Example: PR templates ensure PR reviewers, observers, and future
iterators are in context about the evolution of repos. -->

## Checklist

<!-- Check your PR fulfills the following items. -->
<!-- For draft PRs check the boxes as you complete them. -->

- [ ] PR title corresponds to the body of PR (we generate changelog
entries from PRs).
- [ ] Tests for the changes have been added / updated.
- [ ] Documentation comments have been added / updated.
- [ ] Code has been formatted via `zk fmt` and `zk lint`.

---------

Signed-off-by: Danil <[email protected]>
  • Loading branch information
Deniallugo authored and irnb committed Jul 12, 2024
1 parent 24aaf0c commit 5283a06
Show file tree
Hide file tree
Showing 11 changed files with 577 additions and 482 deletions.
920 changes: 475 additions & 445 deletions zk_toolbox/Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions zk_toolbox/crates/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ tokio.workspace = true
toml.workspace = true
url.workspace = true
xshell.workspace = true
thiserror = "1.0.57"
116 changes: 90 additions & 26 deletions zk_toolbox/crates/common/src/cmd.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use std::{ffi::OsStr, process::Output};
use std::{
ffi::OsStr,
io,
process::{Command, Output, Stdio},
string::FromUtf8Error,
};

use anyhow::bail;
use console::style;

use crate::{
Expand All @@ -16,6 +20,42 @@ pub struct Cmd<'a> {
force_run: bool,
}

#[derive(thiserror::Error, Debug)]
#[error("Cmd error: {source} {stderr:?}")]
pub struct CmdError {
stderr: Option<String>,
source: anyhow::Error,
}

impl From<xshell::Error> for CmdError {
fn from(value: xshell::Error) -> Self {
Self {
stderr: None,
source: value.into(),
}
}
}

impl From<io::Error> for CmdError {
fn from(value: io::Error) -> Self {
Self {
stderr: None,
source: value.into(),
}
}
}

impl From<FromUtf8Error> for CmdError {
fn from(value: FromUtf8Error) -> Self {
Self {
stderr: None,
source: value.into(),
}
}
}

pub type CmdResult<T> = Result<T, CmdError>;

impl<'a> Cmd<'a> {
/// Create a new `Cmd` instance.
pub fn new(cmd: xshell::Cmd<'a>) -> Self {
Expand All @@ -38,31 +78,30 @@ impl<'a> Cmd<'a> {
}

/// Run the command without capturing its output.
pub fn run(&mut self) -> anyhow::Result<()> {
if global_config().verbose || self.force_run {
pub fn run(mut self) -> CmdResult<()> {
let command_txt = self.inner.to_string();
let output = if global_config().verbose || self.force_run {
logger::debug(format!("Running: {}", self.inner));
logger::new_empty_line();
self.inner.run()?;
logger::new_empty_line();
logger::new_line();
run_low_level_process_command(self.inner.into())?
} else {
// Command will be logged manually.
self.inner.set_quiet(true);
// Error will be handled manually.
self.inner.set_ignore_status(true);
let output = self.inner.output()?;
self.check_output_status(&output)?;
}
self.inner.output()?
};

check_output_status(&command_txt, &output)?;
if global_config().verbose {
logger::debug(format!("Command completed: {}", self.inner));
logger::debug(format!("Command completed: {}", command_txt));
}

Ok(())
}

/// Run the command and return its output.
pub fn run_with_output(&mut self) -> anyhow::Result<Output> {
pub fn run_with_output(&mut self) -> CmdResult<std::process::Output> {
if global_config().verbose || self.force_run {
logger::debug(format!("Running: {}", self.inner));
logger::new_empty_line();
Expand All @@ -79,28 +118,53 @@ impl<'a> Cmd<'a> {

Ok(output)
}
}

fn check_output_status(&self, output: &std::process::Output) -> anyhow::Result<()> {
if !output.status.success() {
logger::new_line();
logger::error_note(
&format!("Command failed to run: {}", self.inner),
&log_output(output),
);
bail!("Command failed to run: {}", self.inner);
}

Ok(())
fn check_output_status(command_text: &str, output: &std::process::Output) -> CmdResult<()> {
if !output.status.success() {
logger::new_line();
logger::error_note(
&format!("Command failed to run: {}", command_text),
&log_output(output),
);
return Err(CmdError {
stderr: Some(String::from_utf8(output.stderr.clone())?),
source: anyhow::anyhow!("Command failed to run: {}", command_text),
});
}

Ok(())
}

fn run_low_level_process_command(mut command: Command) -> io::Result<Output> {
command.stdout(Stdio::inherit());
command.stderr(Stdio::piped());
let child = command.spawn()?;
Ok(child.wait_with_output()?)
}

fn log_output(output: &std::process::Output) -> String {
let (status, stdout, stderr) = get_indented_output(output, 4, 120);
log_output_int(status, Some(stdout), Some(stderr))
}

fn log_output_int(status: String, stdout: Option<String>, stderr: Option<String>) -> String {
let status_header = style(" Status:").bold();
let stdout_header = style(" Stdout:").bold();
let stderr_header = style(" Stderr:").bold();
let stdout = if let Some(stdout) = stdout {
let stdout_header = style(" Stdout:").bold();
format!("{stdout_header}\n{stdout}\n")
} else {
String::new()
};

let stderr = if let Some(stderr) = stderr {
let stderr_header = style(" Stderr:").bold();
format!("{stderr_header}\n{stderr}\n")
} else {
String::new()
};

format!("{status_header}\n{status}\n{stdout_header}\n{stdout}\n{stderr_header}\n{stderr}")
format!("{status_header}\n{status}\n{stdout}\n{stderr}")
}

// Indent output and wrap text.
Expand Down
5 changes: 3 additions & 2 deletions zk_toolbox/crates/common/src/docker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use xshell::{cmd, Shell};
use crate::cmd::Cmd;

pub fn up(shell: &Shell, docker_compose_file: &str) -> anyhow::Result<()> {
Cmd::new(cmd!(shell, "docker compose -f {docker_compose_file} up -d")).run()
Ok(Cmd::new(cmd!(shell, "docker compose -f {docker_compose_file} up -d")).run()?)
}

pub fn down(shell: &Shell, docker_compose_file: &str) -> anyhow::Result<()> {
Cmd::new(cmd!(shell, "docker compose -f {docker_compose_file} down")).run()
Ok(Cmd::new(cmd!(shell, "docker compose -f {docker_compose_file} down")).run()?)
}
3 changes: 1 addition & 2 deletions zk_toolbox/crates/common/src/forge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ impl ForgeScript {
let _dir_guard = shell.push_dir(&self.base_path);
let script_path = self.script_path.as_os_str();
let args = self.args.build();
Cmd::new(cmd!(shell, "forge script {script_path} --legacy {args...}")).run()?;
Ok(())
Ok(Cmd::new(cmd!(shell, "forge script {script_path} --legacy {args...}")).run()?)
}

pub fn wallet_args_passed(&self) -> bool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,5 @@ pub async fn initialize_bridges(

fn build_l2_contracts(shell: &Shell, link_to_code: &Path) -> anyhow::Result<()> {
let _dir_guard = shell.push_dir(link_to_code.join("contracts"));
Cmd::new(cmd!(shell, "yarn l2 build")).run()
Ok(Cmd::new(cmd!(shell, "yarn l2 build")).run()?)
}
4 changes: 2 additions & 2 deletions zk_toolbox/crates/zk_inception/src/commands/ecosystem/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,10 +354,10 @@ async fn deploy_ecosystem_inner(

fn install_yarn_dependencies(shell: &Shell, link_to_code: &Path) -> anyhow::Result<()> {
let _dir_guard = shell.push_dir(link_to_code);
Cmd::new(cmd!(shell, "yarn install")).run()
Ok(Cmd::new(cmd!(shell, "yarn install")).run()?)
}

fn build_system_contracts(shell: &Shell, link_to_code: &Path) -> anyhow::Result<()> {
let _dir_guard = shell.push_dir(link_to_code.join("contracts"));
Cmd::new(cmd!(shell, "yarn sc build")).run()
Ok(Cmd::new(cmd!(shell, "yarn sc build")).run()?)
}
2 changes: 1 addition & 1 deletion zk_toolbox/crates/zk_inception/src/commands/prover/gcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub(crate) fn create_gcs_bucket(
let bucket_name = config.bucket_name;
let location = config.location;
let project_id = config.project_id;
let mut cmd = Cmd::new(cmd!(
let cmd = Cmd::new(cmd!(
shell,
"gcloud storage buckets create gs://{bucket_name} --location={location} --project={project_id}"
));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub(crate) async fn run(shell: &Shell) -> anyhow::Result<()> {
shell.change_dir(&link_to_prover);

let spinner = Spinner::new(MSG_GENERATING_SK_SPINNER);
let mut cmd = Cmd::new(cmd!(
let cmd = Cmd::new(cmd!(
shell,
"cargo run --features gpu --release --bin key_generator --
generate-sk all --recompute-if-missing
Expand Down
2 changes: 1 addition & 1 deletion zk_toolbox/crates/zk_inception/src/commands/prover/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ fn download_setup_key(
.clone();
let url = compressor_config.universal_setup_download_url;

let mut cmd = Cmd::new(cmd!(shell, "wget {url} -P {path}"));
let cmd = Cmd::new(cmd!(shell, "wget {url} -P {path}"));
cmd.run()?;
spinner.finish();
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion zk_toolbox/crates/zk_inception/src/external_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl RunExternalNode {
if let Some(components) = self.components() {
additional_args.push(format!("--components={}", components))
}
let mut cmd = Cmd::new(
let cmd = Cmd::new(
cmd!(
shell,
"cargo run --release --bin zksync_external_node --
Expand Down

0 comments on commit 5283a06

Please sign in to comment.