Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: pretty colors, ascii, and helpful intro to the CLI #70

Merged
merged 5 commits into from
Nov 27, 2024
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
5 changes: 4 additions & 1 deletion clients/cli/src/analytics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ pub fn track(
description: String,
ws_addr_string: &str,
event_properties: Value,
print_description: bool,
) {
println!("{}", description);
if print_description {
println!("{}", description);
}

let firebase_app_id = analytics_id(ws_addr_string);
let firebase_api_key = analytics_api_key(ws_addr_string);
Expand Down
6 changes: 6 additions & 0 deletions clients/cli/src/connection.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::analytics::track;
use colored::Colorize;
use serde_json::json;
use tokio::net::TcpStream;
use tokio_tungstenite::{MaybeTlsStream, WebSocketStream};
Expand All @@ -25,11 +26,14 @@ pub async fn connect_to_orchestrator_with_infinite_retry(
loop {
match connect_to_orchestrator(ws_addr).await {
Ok(client) => {
println!("\t✓ Connected to Nexus Network.");

track(
"connected".into(),
"Connected.".into(),
ws_addr,
json!({"prover_id": prover_id}),
false,
);
return client;
}
Expand Down Expand Up @@ -68,7 +72,9 @@ pub async fn connect_to_orchestrator_with_limited_retry(
"Connected.".into(),
ws_addr,
json!({"prover_id": prover_id}),
false,
);
println!("{}", "✓ Success! Connected to Nexus Network.\n".green());
return Ok(client);
}
Err(e) => {
Expand Down
47 changes: 44 additions & 3 deletions clients/cli/src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::connection::{
};

use clap::Parser;
use colored::Colorize;
use futures::{SinkExt, StreamExt};

use generated::pb::ClientProgramProofRequest;
Expand Down Expand Up @@ -85,9 +86,12 @@ fn get_file_as_byte_vec(filename: &str) -> Vec<u8> {
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Print the banner at startup
utils::ascii_art::print_banner();
utils::cli_branding::print_banner();

// Check for CLI updates periodically
println!(
"\n===== {}...\n",
"Setting up CLI configuration".bold().underline()
);

// Configure the tracing subscriber
tracing_subscriber::fmt()
Expand Down Expand Up @@ -119,27 +123,49 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// get or generate the prover id
let prover_id = prover_id_manager::get_or_generate_prover_id();

println!(
"\n===== {}...\n",
"Connecting to Nexus Network".bold().underline()
);

track(
"connect".into(),
format!("Connecting to {}...", &ws_addr_string),
&ws_addr_string,
json!({"prover_id": prover_id}),
false,
);

// Connect to the Orchestrator with exponential backoff
let mut client = connect_to_orchestrator_with_infinite_retry(&ws_addr_string, &prover_id).await;

println!(
"\t✔ Your current prover identifier is {}",
prover_id.bright_cyan()
);

println!(
"\n{}",
"Success! Connection complete!\n".green().bold().underline()
);

track(
"register".into(),
format!("Your current prover identifier is {}.", prover_id),
&ws_addr_string,
json!({"ws_addr_string": ws_addr_string, "prover_id": prover_id}),
false,
);

let mut queued_proof_duration_millis = 0;
let mut queued_steps_proven: i32 = 0;
let mut timer_since_last_orchestrator_update = Instant::now();

println!(
"\n===== {}...\n",
"Starting proof generation for programs".bold().underline()
);

loop {
// Create the inputs for the program
use rand::Rng; // Required for .gen() methods
Expand Down Expand Up @@ -169,6 +195,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut completed_fraction = 0.0;
let mut steps_proven = 0;

println!(
"Program trace is {} steps. Proving {} steps starting at {}...",
total_steps, steps_to_prove, start
);

track(
"progress".into(),
format!(
Expand All @@ -185,6 +216,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
"k": k,
"prover_id": prover_id,
}),
false,
);
let start_time = Instant::now();
let mut progress_time = start_time;
Expand All @@ -211,6 +243,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
cli_prover_id: Some(prover_id.clone()),
};

// Print the proof progress in green or blue depending on the step number
println!(
"\t✓ Proved step {} at {:.2} proof cycles/sec.",
step, proof_cycles_hertz
);

track(
"progress".into(),
format!(
Expand All @@ -229,6 +267,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
"proof_cycles_hertz": proof_cycles_hertz,
"prover_id": prover_id,
}),
false,
);
progress_time = Instant::now();

Expand Down Expand Up @@ -340,7 +379,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
if args.just_once {
break;
} else {
println!("\n\nWaiting for a new program to prove...");
println!("\n\nWaiting for a new program to prove...\n");
}
}

Expand All @@ -359,6 +398,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
"prover_id": &prover_id,
"error": e.to_string(),
}),
true,
);
format!("Failed to close WebSocket connection: {}", e)
})?;
Expand All @@ -367,6 +407,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
"Sent proof and closed connection...".into(),
&ws_addr_string,
json!({ "prover_id": prover_id }),
true,
);
Ok(())
}
17 changes: 15 additions & 2 deletions clients/cli/src/prover_id_manager.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use colored::Colorize;
use rand::RngCore;
use random_word::Lang;
use std::{fs, path::Path};
Expand Down Expand Up @@ -30,7 +31,13 @@ pub fn get_or_generate_prover_id() -> String {
},
// 2. If file doesn't exist or can't be read:
Err(e) => {
eprintln!("Could not read prover-id file: {}", e);
eprintln!(
"{}: {}",
"Warning: Could not read prover-id file"
.to_string()
.yellow(),
e
);

// if the error is because the file doesn't exist
// Try to save the generated prover-id to the file
Expand All @@ -46,7 +53,13 @@ pub fn get_or_generate_prover_id() -> String {
}
}
Err(e) => {
eprintln!("Failed to create .nexus directory: {}", e);
eprintln!(
"{}: {}",
"Warning: Failed to create .nexus directory"
.to_string()
.yellow(),
e
);
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions clients/cli/src/updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub fn spawn_auto_update_thread(
updater_config: &UpdaterConfig,
) -> Result<(), Box<dyn std::error::Error>> {
println!(
"{}[auto-updater thread]{} Starting periodic CLI updates...",
"{}[auto-updater]{} Starting periodic CLI updates...",
BLUE, RESET
);

Expand All @@ -40,7 +40,7 @@ pub fn spawn_auto_update_thread(
// Spawn the update checker thread
thread::spawn(move || {
println!(
"{}[auto-updater thread]{} Update checker thread started!",
"{}[auto-updater]{} Update checker thread started!",
BLUE, RESET
);

Expand All @@ -53,27 +53,27 @@ pub fn spawn_auto_update_thread(
VersionStatus::UpdateAvailable(new_version) => {
if let Err(e) = version_manager_thread.apply_update(&new_version) {
eprintln!(
"{}[auto-updater thread]{} Failed to update CLI: {}",
"{}[auto-updater]{} Failed to update CLI: {}",
BLUE, RESET, e
);
}
}
// ... No update needed
VersionStatus::UpToDate => {
println!("{}[auto-updater thread]{} CLI is up to date", BLUE, RESET);
println!("{}[auto-updater]{} CLI is up to date", BLUE, RESET);
}
},
Err(e) => {
eprintln!(
"{}[auto-updater thread]{} Failed to check version: {}",
"{}[auto-updater]{} Failed to check version: {}",
BLUE, RESET, e
);
}
}

// Wait for the next update check
println!(
"{}[auto-updater thread]{} Next update check in {} seconds...",
"{}[auto-updater]{} Next update check in {} seconds...\n",
BLUE, RESET, update_interval
);
thread::sleep(Duration::from_secs(update_interval));
Expand Down
29 changes: 0 additions & 29 deletions clients/cli/src/utils/ascii_art.rs

This file was deleted.

70 changes: 70 additions & 0 deletions clients/cli/src/utils/cli_branding.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use colored::Colorize;

pub const LOGO: &str = r#"
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%/*/(#&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%******/((((((&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@&#**********/////////((%@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@&/***************/////////////(#@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@%**********,,,,,,,,,*****////////////((#&@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@%***********,,,,,,,,,,,,***********////////(((((&@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@* .********,,,,,,,,,,,,,,,,,,***********///////(((#%&@@@@@@@@@@@@@
@@@@@@@@@@@@@@* ,*,,,,,,,,,,,......,,,,,,,,,*******///(#%%%%%&@@@@@@@@@@@@@
@@@@@@@@@@@@@@* ,,,,,,............,,,,,,,,****/#####%%%%%&@@@@@@@@@@@@@
@@@@@@@@@@@@@@* ..................,,,,/#########%%%%%&@@@@@@@@@@@@@
@@@@@@@@@@@@@@* .. . ...../(((###########%%%%&@@@@@@@@@@@@@
@@@@@@@@@@@@@@* ./((((((((##########%%%%&@@@@@@@@@@@@@
@@@@@@@@@@@@@@* /(((((((((((##########%%%%&@@@@@@@@@@@@@
@@@@@@@@@@@@@@* /#####(((((###########%%%%&@@@@@@@@@@@@@
@@@@@@@@@@@@@@* /####################%%%%%&@@@@@@@@@@@@@
@@@@@@@@@@@@@@* /###########%%######%%%%%%&@@@@@@@@@@@@@
@@@@@@@@@@@@@@* ..... /########%%%%%%%%%%%%%%%%%&@@@@@@@@@@@@@
@@@@@@@@@@@@@@* ............ (####%%%%%%%%%%%%%%%%%%%%%&@@@@@@@@@@@@@
@@@@@@@@@@@@@@@&,................ (%%%%%%%%%%%%%%%%%%%%%%%&@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@&/...................(%%%%%%%%%%%%%%%%%%%&@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@&#...............(%%%%%%%%%%%%%%%&@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@%,..........(%%%%%%%%%%&@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&*......(%%%%%%&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&/..(%%&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
"#;

pub const BANNER: &str = r#"
===========================================================================
███╗ ██╗███████╗██╗ ██╗██╗ ██╗███████╗
████╗ ██║██╔════╝╚██╗██╔╝██║ ██║██╔════╝
██╔██╗ ██║█████╗ ╚███╔╝ ██║ ██║███████╗
██║╚██╗██║██╔══╝ ██╔██╗ ██║ ██║╚════██║
██║ ╚████║███████╗██╔╝ ██╗╚██████╔╝███████║
╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝
===========================================================================
"#;

pub fn print_banner() {
println!("{}", BANNER.bright_cyan());
println!("{}", LOGO.bright_cyan());
println!(
"{} {}\n",
"Welcome to the".bright_white(),
"Nexus Network CLI".bright_cyan().bold()
);
println!(
"{}",
"The Nexus network is a massively-parallelized proof network for executing and proving the \x1b]8;;https://docs.nexus.org\x1b\\Nexus zkVM\x1b]8;;\x1b\\.\n\n"
.bright_white()
);
}

pub fn print_success(message: &str) {
println!("✨ {}", message.green());
}

pub fn print_error(message: &str) {
println!("❌ {}", message.red());
}
2 changes: 1 addition & 1 deletion clients/cli/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pub mod ascii_art;
pub mod cli_branding;
pub mod updater;
Loading