Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions src/clparse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,5 +500,6 @@ pub fn parse_command_line() -> ArgMatches<'static> {
.help("Enable transaction history (increases storage requirements)")
)
)
)
.get_matches()
}
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! OSVM CLI Library
//!
//!
//! This library provides the core functionality for the OSVM CLI.
//! It includes utilities for managing SVMs, nodes, and SSH deployments.
//!
Expand All @@ -18,6 +18,6 @@
//! - `clparse`: Command-line parsing and argument definitions
//! - `main`: Main entry point and command handlers

pub mod utils;
pub mod clparse;
pub mod prelude;
pub mod prelude;
pub mod utils;
274 changes: 164 additions & 110 deletions src/main.rs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ pub use crate::utils::dashboard;
// Example command utilities
pub use crate::utils::examples;
// Color formatting utilities
pub use crate::utils::color;
pub use crate::utils::color;
13 changes: 9 additions & 4 deletions src/utils/color.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Color utility functions for consistent CLI output formatting
//!
//!
//! This module provides standardized colors and formatting for different types of CLI output
//! such as success messages, warnings, errors, and information. It centralizes color schemes
//! to ensure consistent user experience across all commands.
Expand Down Expand Up @@ -72,7 +72,11 @@ pub fn node_status(status: &str) -> colored::ColoredString {
}

/// Format numeric value with appropriate color based on threshold
pub fn numeric_value(value: f64, warning_threshold: f64, error_threshold: f64) -> colored::ColoredString {
pub fn numeric_value(
value: f64,
warning_threshold: f64,
error_threshold: f64,
) -> colored::ColoredString {
if value >= error_threshold {
format!("{:.1}", value).red()
} else if value >= warning_threshold {
Expand All @@ -89,7 +93,8 @@ pub fn table_header(text: &str) -> colored::ColoredString {

/// Format separator line (bright black)
pub fn separator() -> colored::ColoredString {
"---------------------------------------------------------------------------------".bright_black()
"---------------------------------------------------------------------------------"
.bright_black()
}

/// Format text with custom color
Expand All @@ -110,4 +115,4 @@ pub fn italic(text: &str) -> colored::ColoredString {
/// Format text as code/monospace
pub fn code(text: &str) -> colored::ColoredString {
text.white().on_bright_black()
}
}
107 changes: 59 additions & 48 deletions src/utils/dashboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ impl Default for DashboardManager {

impl DashboardManager {
/// Create a new dashboard manager
///
///
/// # Arguments
/// * `output_dir` - Directory to save dashboard files
/// * `verbosity` - Verbosity level (0-3)
///
///
/// # Returns
/// * `DashboardManager` - Dashboard manager
pub fn new(output_dir: &str, verbosity: u8) -> Self {
Expand All @@ -69,140 +69,148 @@ impl DashboardManager {
verbosity,
}
}

/// Set dashboard title
///
///
/// # Arguments
/// * `title` - Dashboard title
///
///
/// # Returns
/// * `&mut Self` - Self reference for method chaining
pub fn with_title(&mut self, title: &str) -> &mut Self {
self.title = title.to_string();
self
}

/// Set verbosity level
///
///
/// # Arguments
/// * `verbosity` - Verbosity level (0-3)
///
///
/// # Returns
/// * `&mut Self` - Self reference for method chaining
pub fn with_verbosity(&mut self, verbosity: u8) -> &mut Self {
self.verbosity = verbosity;
self
}

/// Generate and save dashboard HTML
///
///
/// # Arguments
/// * `nodes` - List of node information
///
///
/// # Returns
/// * `Result<String, Box<dyn Error>>` - Path to the dashboard file
pub fn generate_dashboard(&self, nodes: &[NodeInfo]) -> Result<String, Box<dyn Error>> {
// Ensure output directory exists
fs::create_dir_all(&self.output_dir)?;

// Generate HTML content
// Pass verbosity level to the dashboard generator
let html_content = generate_monitoring_dashboard(nodes, self.verbosity);



// Create output file path
let file_path = format!("{}/osvm_dashboard.html", self.output_dir);

// Write HTML to file
fs::write(&file_path, html_content)?;

Ok(file_path)
}

/// Open dashboard in default browser
///
///
/// # Arguments
/// * `file_path` - Path to the dashboard HTML file
///
///
/// # Returns
/// * `Result<(), Box<dyn Error>>` - Result
pub fn open_in_browser(&self, file_path: &str) -> Result<(), Box<dyn Error>> {
// Convert to absolute path if needed
let path = Path::new(file_path);

// Get file URL
let file_url = if path.is_absolute() {
format!("file://{}", path.display())
} else {
let abs_path = fs::canonicalize(path)?;
format!("file://{}", abs_path.display())
};

// Determine the platform and open browser accordingly
#[cfg(target_os = "windows")]
{
Command::new("cmd")
.args(&["/c", "start", "", &file_url])
.spawn()
.map_err(|e| Box::new(DashboardError::BrowserError(e.to_string())) as Box<dyn Error>)?;
.map_err(|e| {
Box::new(DashboardError::BrowserError(e.to_string())) as Box<dyn Error>
})?;
}

#[cfg(target_os = "macos")]
{
Command::new("open")
.arg(&file_url)
.spawn()
.map_err(|e| Box::new(DashboardError::BrowserError(e.to_string())) as Box<dyn Error>)?;
Command::new("open").arg(&file_url).spawn().map_err(|e| {
Box::new(DashboardError::BrowserError(e.to_string())) as Box<dyn Error>
})?;
}

#[cfg(target_os = "linux")]
{
Command::new("xdg-open")
.arg(&file_url)
.spawn()
.map_err(|e| Box::new(DashboardError::BrowserError(e.to_string())) as Box<dyn Error>)?;
.map_err(|e| {
Box::new(DashboardError::BrowserError(e.to_string())) as Box<dyn Error>
})?;
}

Ok(())
}

/// Generate dashboard and open in browser
///
///
/// # Arguments
/// * `nodes` - List of node information
///
///
/// # Returns
/// * `Result<(), Box<dyn Error>>` - Result
pub fn generate_and_open(&self, nodes: &[NodeInfo]) -> Result<(), Box<dyn Error>> {
let file_path = self.generate_dashboard(nodes)?;
self.open_in_browser(&file_path)?;

Ok(())
}

/// Create a real-time dashboard server (this would require an actual implementation)
///
///
/// # Arguments
/// * `port` - Port to run the dashboard server on
///
///
/// # Returns
/// * `Result<(), Box<dyn Error>>` - Result
pub fn run_dashboard_server(&self, port: u16, verbosity: u8) -> Result<(), Box<dyn Error>> {
// This would normally start a web server that provides real-time updates
// For this prototype, we'll just print a message with detail based on verbosity
println!("Dashboard server would be running on http://localhost:{}", port);

println!(
"Dashboard server would be running on http://localhost:{}",
port
);

// Show additional details based on verbosity level
match verbosity {
0 => Ok(()), // Minimal output
1 => {
println!("(Real implementation would start an actual web server)");
Ok(())
},
}
2 => {
println!("Monitoring {} nodes with refresh rate of {} seconds", "[node_count]", 5);
println!(
"Monitoring {} nodes with refresh rate of {} seconds",
"[node_count]", 5
);
Ok(())
},
}
_ => {
println!("Starting server with detailed debug logging enabled for development");
Ok(())
Expand All @@ -212,11 +220,11 @@ impl DashboardManager {
}

/// Save a quick dashboard to the current directory and open it
///
///
/// # Arguments
/// * `nodes` - List of node information
/// * `verbosity` - Verbosity level (0-3)
///
///
/// # Returns
/// * `Result<(), Box<dyn Error>>` - Result
pub fn quick_dashboard(nodes: &[NodeInfo], verbosity: u8) -> Result<(), Box<dyn Error>> {
Expand All @@ -226,13 +234,16 @@ pub fn quick_dashboard(nodes: &[NodeInfo], verbosity: u8) -> Result<(), Box<dyn
}

/// Run the dashboard with the given RPC client and commitment config
///
///
/// # Arguments
/// * `client` - RPC client
/// * `commitment_config` - Commitment config
///
///
/// # Returns
/// * `Result<(), Box<dyn Error>>` - Result
pub fn run_dashboard(client: &RpcClient, commitment_config: CommitmentConfig) -> Result<(), Box<dyn Error>> {
pub fn run_dashboard(
client: &RpcClient,
commitment_config: CommitmentConfig,
) -> Result<(), Box<dyn Error>> {
crate::utils::nodes::run_dashboard(client, commitment_config, 1)
}
}
Loading
Loading