From dd2d82d114537e09dbeb12f360157f0e68e7846e Mon Sep 17 00:00:00 2001 From: Jack Wills <32690432+mrjackwills@users.noreply.github.com> Date: Thu, 28 Jul 2022 17:18:00 +0000 Subject: [PATCH 01/11] fix: toml keywords --- .vscode/launch.json | 45 +++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 +- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..660f195 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'oxker'", + "cargo": { + "args": [ + "build", + "--bin=oxker", + "--package=oxker" + ], + "filter": { + "name": "oxker", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in executable 'oxker'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=oxker", + "--package=oxker" + ], + "filter": { + "name": "oxker", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 3e5be83..0f0a62d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ repository = "https://github.com/mrjackwills/oxker" homepage = "https://github.com/mrjackwills/oxker" license = "MIT" readme = "README.md" -keywords = ["docker", "tui", "tui-rs", "tokio"] +keywords = ["docker", "tui", "tui-rs", "tokio", "terminal", "podman", "container"] categories = ["command-line-utilities"] [dependencies] From d9801cdf372521fe5624a8d68fac83ed39ef81f4 Mon Sep 17 00:00:00 2001 From: Jack Wills <32690432+mrjackwills@users.noreply.github.com> Date: Thu, 4 Aug 2022 11:34:07 +0000 Subject: [PATCH 02/11] fix: dependencies update update colorize_logs with updated cansi methods --- src/ui/color_match.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ui/color_match.rs b/src/ui/color_match.rs index 14543b6..58fe50d 100644 --- a/src/ui/color_match.rs +++ b/src/ui/color_match.rs @@ -1,6 +1,6 @@ pub mod log_sanitizer { - use cansi::{categorise_text, Color as CansiColor, Intensity}; + use cansi::{v3::categorise_text, Color as CansiColor, Intensity}; use tui::{ style::{Color, Modifier, Style}, text::{Span, Spans}, @@ -12,25 +12,25 @@ pub mod log_sanitizer { categorise_text(&input) .into_iter() .map(|i| { - let fg_color = color_ansi_to_tui(i.fg_colour); - let bg_color = color_ansi_to_tui(i.bg_colour); + let fg_color = color_ansi_to_tui(i.fg.unwrap_or(CansiColor::White)); + let bg_color = color_ansi_to_tui(i.bg.unwrap_or(CansiColor::Black)); let style = Style::default().bg(bg_color).fg(fg_color); - if i.blink { + if i.blink.is_some() { style.add_modifier(Modifier::SLOW_BLINK); } - if i.underline { + if i.underline.is_some() { style.add_modifier(Modifier::UNDERLINED); } - if i.reversed { + if i.reversed.is_some() { style.add_modifier(Modifier::REVERSED); } - if i.intensity == Intensity::Bold { + if i.intensity == Some(Intensity::Bold) { style.add_modifier(Modifier::BOLD); } - if i.hidden { + if i.hidden.is_some() { style.add_modifier(Modifier::HIDDEN); } - if i.strikethrough { + if i.strikethrough.is_some() { style.add_modifier(Modifier::CROSSED_OUT); } Span::styled(i.text.to_owned(), style) From 44f8140eaec330abe5a94f3ddae9e8b223688aa8 Mon Sep 17 00:00:00 2001 From: Jack Wills <32690432+mrjackwills@users.noreply.github.com> Date: Thu, 4 Aug 2022 11:34:50 +0000 Subject: [PATCH 03/11] feat: build all production targets on release Imitate github workflows --- create_release.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/create_release.sh b/create_release.sh index 50a90e9..349293e 100755 --- a/create_release.sh +++ b/create_release.sh @@ -179,11 +179,23 @@ cargo_test () { ask_continue } +# Build all releases that GitHub workflow would +# This will download GB's of docker images +cargo_build () { + cargo install cross + cargo build --release + cross build --target aarch64-unknown-linux-musl --release + cross build --target arm-unknown-linux-musleabihf --release + cross build --target x86_64-pc-windows-gnu --release + ask_continue +} + # Full flow to create a new release release_flow() { check_git get_git_remote_url cargo_test + cargo_build cd "${CWD}" || error_close "Can't find ${CWD}" check_tag From ca3315a69f593ad705eb637f227f195edd7781b2 Mon Sep 17 00:00:00 2001 From: Jack Wills <32690432+mrjackwills@users.noreply.github.com> Date: Thu, 4 Aug 2022 11:47:45 +0000 Subject: [PATCH 04/11] chore: lint unused unwraps --- src/app_data/mod.rs | 3 ++- src/main.rs | 43 +++++++++++++++++++++++++++++-------------- src/ui/color_match.rs | 2 +- src/ui/mod.rs | 11 ++++++++--- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/app_data/mod.rs b/src/app_data/mod.rs index e2ed0da..4a415ff 100644 --- a/src/app_data/mod.rs +++ b/src/app_data/mod.rs @@ -87,7 +87,8 @@ impl AppData { } } - // Current time as unix timestamp + /// Current time as unix timestamp + #[allow(clippy::expect_used)] fn get_systemtime(&self) -> u64 { SystemTime::now() .duration_since(UNIX_EPOCH) diff --git a/src/main.rs b/src/main.rs index 30c2141..cb34c34 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,13 @@ +#![forbid(unsafe_code)] +#![warn(clippy::unused_async, clippy::unwrap_used, clippy::expect_used)] +// Wanring - These are indeed pedantic +// #![warn(clippy::pedantic)] +// #![warn(clippy::nursery)] +// #![allow(clippy::module_name_repetitions, clippy::doc_markdown)] + +// Only allow when debugging +// #![allow(unused)] + use app_data::AppData; use app_error::AppError; use bollard::Docker; @@ -35,23 +45,28 @@ async fn main() { let (docker_sx, docker_rx) = tokio::sync::mpsc::channel(16); // Create docker daemon handler, and only spawn up the docker data handler if ping returns non-error - let docker = Arc::new(Docker::connect_with_socket_defaults().unwrap()); - match docker.ping().await { - Ok(_) => { - let docker = Arc::clone(&docker); - let is_running = Arc::clone(&is_running); - tokio::spawn(DockerData::init( - docker_args, - docker_app_data, - docker, - docker_gui_state, - docker_rx, - is_running, - )); + + match Docker::connect_with_socket_defaults() { + Ok(docker) => { + let docker = Arc::new(docker); + match docker.ping().await { + Ok(_) => { + let docker = Arc::clone(&docker); + let is_running = Arc::clone(&is_running); + tokio::spawn(DockerData::init( + docker_args, + docker_app_data, + docker, + docker_gui_state, + docker_rx, + is_running, + )); + } + Err(_) => app_data.lock().set_error(AppError::DockerConnect), + } } Err(_) => app_data.lock().set_error(AppError::DockerConnect), } - let input_app_data = Arc::clone(&app_data); let (input_sx, input_rx) = tokio::sync::mpsc::channel(16); diff --git a/src/ui/color_match.rs b/src/ui/color_match.rs index 58fe50d..cf69f1a 100644 --- a/src/ui/color_match.rs +++ b/src/ui/color_match.rs @@ -24,7 +24,7 @@ pub mod log_sanitizer { if i.reversed.is_some() { style.add_modifier(Modifier::REVERSED); } - if i.intensity == Some(Intensity::Bold) { + if i.intensity == Some(Intensity::Bold) { style.add_modifier(Modifier::BOLD); } if i.hidden.is_some() { diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 8b7504a..71c090a 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -94,9 +94,12 @@ async fn run_app( is_running.store(false, Ordering::SeqCst); break; } - terminal + if terminal .draw(|f| draw_error(f, AppError::DockerConnect, Some(seconds))) - .unwrap(); + .is_err() + { + return Err(AppError::Terminal); + } tokio::time::sleep(std::time::Duration::from_secs(1)).await; seconds -= 1; } @@ -104,7 +107,9 @@ async fn run_app( } else { let mut now = Instant::now(); loop { - terminal.draw(|f| ui(f, &app_data, &gui_state)).unwrap(); + if terminal.draw(|f| ui(f, &app_data, &gui_state)).is_err() { + return Err(AppError::Terminal); + } if crossterm::event::poll(input_poll_rate).unwrap_or_default() { if let Ok(event) = event::read() { if let Event::Key(key) = event { From 1263662bd9412afacddbc10721bf216ae3a843f1 Mon Sep 17 00:00:00 2001 From: Jack Wills <32690432+mrjackwills@users.noreply.github.com> Date: Thu, 4 Aug 2022 12:56:45 +0000 Subject: [PATCH 05/11] chore: linting pedantic --- src/app_data/container_state.rs | 4 +- src/app_data/mod.rs | 65 ++++++++++++++------------- src/docker_data/mod.rs | 60 ++++++++++++------------- src/input_handler/mod.rs | 12 ++--- src/main.rs | 20 ++++----- src/ui/color_match.rs | 16 +++---- src/ui/draw_blocks.rs | 78 +++++++++++++++++---------------- src/ui/gui_state.rs | 10 ++--- src/ui/mod.rs | 27 ++++++------ 9 files changed, 144 insertions(+), 148 deletions(-) diff --git a/src/app_data/container_state.rs b/src/app_data/container_state.rs index 4dbb32b..e81ee5a 100644 --- a/src/app_data/container_state.rs +++ b/src/app_data/container_state.rs @@ -352,7 +352,7 @@ impl ContainerItem { /// Find the max value in the last 30 items in the cpu stats vec fn max_cpu_stats(&self) -> CpuStats { match self.cpu_stats.iter().max() { - Some(value) => value.to_owned(), + Some(value) => value.clone(), None => CpuStats::new(0.0), } } @@ -360,7 +360,7 @@ impl ContainerItem { /// Find the max value in the last 30 items in the mem stats vec fn max_mem_stats(&self) -> ByteStats { match self.mem_stats.iter().max() { - Some(value) => value.to_owned(), + Some(value) => value.clone(), None => ByteStats::new(0), } } diff --git a/src/app_data/mod.rs b/src/app_data/mod.rs index 4a415ff..678ce41 100644 --- a/src/app_data/mod.rs +++ b/src/app_data/mod.rs @@ -71,7 +71,7 @@ impl AppData { self.containers .items .iter() - .position(|i| Some(i.id.to_owned()) == id), + .position(|i| Some(i.id.clone()) == id), ); } /// Generate a default app_state @@ -89,7 +89,7 @@ impl AppData { /// Current time as unix timestamp #[allow(clippy::expect_used)] - fn get_systemtime(&self) -> u64 { + fn get_systemtime() -> u64 { SystemTime::now() .duration_since(UNIX_EPOCH) .expect("In our known reality, this error should never occur") @@ -107,7 +107,7 @@ impl AppData { .selected() { output = - Some(self.containers.items[index].docker_controls.items[control_index].clone()) + Some(self.containers.items[index].docker_controls.items[control_index].clone()); } } output @@ -116,28 +116,28 @@ impl AppData { /// Change selected choice of docker commands of selected container pub fn docker_command_next(&mut self) { if let Some(index) = self.containers.state.selected() { - self.containers.items[index].docker_controls.next() + self.containers.items[index].docker_controls.next(); } } /// Change selected choice of docker commands of selected container pub fn docker_command_previous(&mut self) { if let Some(index) = self.containers.state.selected() { - self.containers.items[index].docker_controls.previous() + self.containers.items[index].docker_controls.previous(); } } /// Change selected choice of docker commands of selected container pub fn docker_command_start(&mut self) { if let Some(index) = self.containers.state.selected() { - self.containers.items[index].docker_controls.start() + self.containers.items[index].docker_controls.start(); } } /// Change selected choice of docker commands of selected container pub fn docker_command_end(&mut self) { if let Some(index) = self.containers.state.selected() { - self.containers.items[index].docker_controls.end() + self.containers.items[index].docker_controls.end(); } } @@ -168,9 +168,9 @@ impl AppData { .iter() .skip(index) .take(1) - .map(|i| i.id.to_owned()) + .map(|i| i.id.clone()) .collect::(); - output = Some(id) + output = Some(id); } output } @@ -226,7 +226,7 @@ impl AppData { Header::Image => match so { SortedOrder::Asc => self.containers.items.sort_by(|a, b| a.image.cmp(&b.image)), SortedOrder::Desc => { - self.containers.items.sort_by(|a, b| b.image.cmp(&a.image)) + self.containers.items.sort_by(|a, b| b.image.cmp(&a.image)); } }, Header::Name => match so { @@ -269,28 +269,28 @@ impl AppData { /// select next selected log line pub fn log_next(&mut self) { if let Some(index) = self.get_selected_log_index() { - self.containers.items[index].logs.next() + self.containers.items[index].logs.next(); } } /// select previous selected log line pub fn log_previous(&mut self) { if let Some(index) = self.get_selected_log_index() { - self.containers.items[index].logs.previous() + self.containers.items[index].logs.previous(); } } /// select last selected log line pub fn log_end(&mut self) { if let Some(index) = self.get_selected_log_index() { - self.containers.items[index].logs.end() + self.containers.items[index].logs.end(); } } /// select first selected log line pub fn log_start(&mut self) { if let Some(index) = self.get_selected_log_index() { - self.containers.items[index].logs.start() + self.containers.items[index].logs.start(); } } @@ -316,7 +316,7 @@ impl AppData { let mut output = Columns::new(); let count = |x: &String| x.chars().count(); - for container in self.containers.items.iter() { + for container in &self.containers.items { let cpu_count = count( &container .cpu_stats @@ -370,7 +370,7 @@ impl AppData { self.containers .items .iter() - .map(|i| i.id.to_owned()) + .map(|i| i.id.clone()) .collect::>() } @@ -382,14 +382,14 @@ impl AppData { /// Update container mem, cpu, & network stats, in single function so only need to call .lock() once pub fn update_stats( &mut self, - id: String, + id: &str, cpu_stat: Option, mem_stat: Option, mem_limit: u64, rx: u64, tx: u64, ) { - if let Some(container) = self.get_container_by_id(&id) { + if let Some(container) = self.get_container_by_id(id) { if container.cpu_stats.len() >= 60 { container.cpu_stats.pop_front(); } @@ -444,7 +444,7 @@ impl AppData { .unwrap_or(&vec!["".to_owned()]) .get(0) .unwrap_or(&String::from("")) - .to_owned(); + .clone(); if let Some(c) = name.chars().next() { if c == '/' { name.remove(0); @@ -461,10 +461,10 @@ impl AppData { let image = i.image.as_ref().unwrap_or(&"".to_owned()).trim().to_owned(); if let Some(current_container) = self.get_container_by_id(id) { if current_container.name != name { - current_container.name = name + current_container.name = name; }; if current_container.status != status { - current_container.status = status + current_container.status = status; }; if current_container.state != state { current_container.docker_controls.items = DockerControls::gen_vec(&state); @@ -472,18 +472,17 @@ impl AppData { // Update the list state, needs to be None if the gen_vec returns an empty vec match state { State::Removing | State::Restarting | State::Unknown => { - current_container.docker_controls.state.select(None) + current_container.docker_controls.state.select(None); } _ => current_container.docker_controls.start(), }; current_container.state = state; }; if current_container.image != image { - current_container.image = image + current_container.image = image; }; } else { - let mut container = - ContainerItem::new(id.to_owned(), status, image, state, name); + let mut container = ContainerItem::new(id.clone(), status, image, state, name); container.logs.end(); self.containers.items.push(container); } @@ -492,25 +491,25 @@ impl AppData { } /// update logs of a given container, based on id - pub fn update_log_by_id(&mut self, output: Vec, id: String) { - let tz = self.get_systemtime(); + pub fn update_log_by_id(&mut self, output: &[String], id: &str) { + let tz = Self::get_systemtime(); let color = self.args.color; let raw = self.args.raw; - if let Some(container) = self.get_container_by_id(&id) { + if let Some(container) = self.get_container_by_id(id) { container.last_updated = tz; let current_len = container.logs.items.len(); - output.iter().for_each(|i| { + for i in output.iter() { let lines = if color { - log_sanitizer::colorize_logs(i.to_owned()) + log_sanitizer::colorize_logs(i) } else if raw { - log_sanitizer::raw(i.to_owned()) + log_sanitizer::raw(i.clone()) } else { - log_sanitizer::remove_ansi(i.to_owned()) + log_sanitizer::remove_ansi(i) }; container.logs.items.push(ListItem::new(lines)); - }); + } if container.logs.state.selected().is_none() || container.logs.state.selected().unwrap_or_default() + 1 == current_len diff --git a/src/docker_data/mod.rs b/src/docker_data/mod.rs index 4e09a9a..2aeb49d 100644 --- a/src/docker_data/mod.rs +++ b/src/docker_data/mod.rs @@ -103,7 +103,7 @@ impl DockerData { let mem_limit = stats.memory_stats.limit.unwrap_or(0); let some_key = if let Some(networks) = &stats.networks { - networks.keys().next().map(|x| x.to_owned()) + networks.keys().next().cloned() } else { None }; @@ -122,7 +122,7 @@ impl DockerData { if is_running { app_data.lock().update_stats( - id.clone(), + &id, Some(cpu_stats), Some(mem_stat), mem_limit, @@ -132,10 +132,9 @@ impl DockerData { } else { app_data .lock() - .update_stats(id.clone(), None, None, mem_limit, rx, tx); + .update_stats(&id, None, None, mem_limit, rx, tx); } - let key = SpawnId::Stats(id.to_owned()); - spawns.lock().remove(&key); + spawns.lock().remove(&SpawnId::Stats(id.clone())); } } @@ -146,13 +145,13 @@ impl DockerData { let app_data = Arc::clone(&self.app_data); let spawns = Arc::clone(&self.spawns); let is_running = *is_running; - let id = id.to_owned(); + let id = id.clone(); - let key = SpawnId::Stats(id.to_owned()); + let key = SpawnId::Stats(id.clone()); let spawn_contains_id = spawns.lock().contains_key(&key); let s = tokio::spawn(Self::update_container_stat( docker, - id.to_owned(), + id.clone(), app_data, is_running, spawns, @@ -180,7 +179,7 @@ impl DockerData { containers .iter() .filter(|i| i.id.is_some()) - .for_each(|c| output.push(c.to_owned())); + .for_each(|c| output.push(c.clone())); self.app_data.lock().update_containers(&output); @@ -193,7 +192,7 @@ impl DockerData { i.id.as_ref().map(|id| { ( i.state.as_ref().unwrap_or(&String::new()) == "running", - id.to_owned(), + id.clone(), ) }) }) @@ -230,9 +229,8 @@ impl DockerData { } } } - let key = SpawnId::Log(id.to_owned()); - spawns.lock().remove(&key); - app_data.lock().update_log_by_id(output, id.to_owned()); + spawns.lock().remove(&SpawnId::Log(id.clone())); + app_data.lock().update_log_by_id(&output, &id); } /// Update all logs, spawn each container into own tokio::spawn thread @@ -240,10 +238,10 @@ impl DockerData { for (_, id) in all_ids.iter() { let docker = Arc::clone(&self.docker); let timestamps = self.timestamps; - let id = id.to_owned(); + let id = id.clone(); let app_data = Arc::clone(&self.app_data); let spawns = Arc::clone(&self.spawns); - let key = SpawnId::Log(id.to_owned()); + let key = SpawnId::Log(id.clone()); let s = tokio::spawn(Self::update_log( docker, id, timestamps, 0, app_data, spawns, )); @@ -256,9 +254,9 @@ impl DockerData { let all_ids = self.update_all_containers().await; let optional_index = self.app_data.lock().get_selected_log_index(); if let Some(index) = optional_index { - let id = self.app_data.lock().containers.items[index].id.to_owned(); + let id = self.app_data.lock().containers.items[index].id.clone(); - let key = SpawnId::Log(id.to_owned()); + let key = SpawnId::Log(id.clone()); let running = self.spawns.lock().contains_key(&key); if !running { @@ -290,7 +288,7 @@ impl DockerData { } /// Stop the loading_spin function, and reset gui loading status - fn stop_loading_spin(&mut self, handle: JoinHandle<()>) { + fn stop_loading_spin(&mut self, handle: &JoinHandle<()>) { handle.abort(); self.gui_state.lock().reset_loading(); } @@ -315,7 +313,7 @@ impl DockerData { self.initialised = self.app_data.lock().initialised(&all_ids); } self.app_data.lock().init = true; - self.stop_loading_spin(loading_spin); + self.stop_loading_spin(&loading_spin); } /// Handle incoming messages, container controls & all container information update @@ -329,9 +327,9 @@ impl DockerData { docker.pause_container(&id).await.unwrap_or_else(|_| { app_data .lock() - .set_error(AppError::DockerCommand(DockerControls::Pause)) + .set_error(AppError::DockerCommand(DockerControls::Pause)); }); - self.stop_loading_spin(loading_spin); + self.stop_loading_spin(&loading_spin); } DockerMessage::Restart(id) => { let loading_spin = self.loading_spin().await; @@ -341,9 +339,9 @@ impl DockerData { .unwrap_or_else(|_| { app_data .lock() - .set_error(AppError::DockerCommand(DockerControls::Restart)) + .set_error(AppError::DockerCommand(DockerControls::Restart)); }); - self.stop_loading_spin(loading_spin); + self.stop_loading_spin(&loading_spin); } DockerMessage::Start(id) => { let loading_spin = self.loading_spin().await; @@ -353,28 +351,28 @@ impl DockerData { .unwrap_or_else(|_| { app_data .lock() - .set_error(AppError::DockerCommand(DockerControls::Start)) + .set_error(AppError::DockerCommand(DockerControls::Start)); }); - self.stop_loading_spin(loading_spin); + self.stop_loading_spin(&loading_spin); } DockerMessage::Stop(id) => { let loading_spin = self.loading_spin().await; docker.stop_container(&id, None).await.unwrap_or_else(|_| { app_data .lock() - .set_error(AppError::DockerCommand(DockerControls::Stop)) + .set_error(AppError::DockerCommand(DockerControls::Stop)); }); - self.stop_loading_spin(loading_spin); + self.stop_loading_spin(&loading_spin); } DockerMessage::Unpause(id) => { let loading_spin = self.loading_spin().await; docker.unpause_container(&id).await.unwrap_or_else(|_| { app_data .lock() - .set_error(AppError::DockerCommand(DockerControls::Unpause)) + .set_error(AppError::DockerCommand(DockerControls::Unpause)); }); - self.stop_loading_spin(loading_spin); - self.update_everything().await + self.stop_loading_spin(&loading_spin); + self.update_everything().await; } DockerMessage::Update => self.update_everything().await, DockerMessage::Quit => { @@ -382,7 +380,7 @@ impl DockerData { .lock() .values() .into_iter() - .for_each(|i| i.abort()); + .for_each(tokio::task::JoinHandle::abort); self.is_running.store(false, Ordering::SeqCst); } } diff --git a/src/input_handler/mod.rs b/src/input_handler/mod.rs index 9bbdbcc..97d49ee 100644 --- a/src/input_handler/mod.rs +++ b/src/input_handler/mod.rs @@ -110,7 +110,7 @@ impl InputHandler { // Show the info box - with "mouse capture enabled / disabled", for 4000 ms self.info_sleep = Some(tokio::spawn(async move { tokio::time::sleep(std::time::Duration::from_millis(4000)).await; - gui_state.lock().reset_info_box() + gui_state.lock().reset_info_box(); })); self.mouse_capture = !self.mouse_capture; @@ -118,14 +118,14 @@ impl InputHandler { /// Sort containers based on a given header, switch asc to desc if already sorted, else always desc fn sort(&self, header: Header) { - let mut output = Some((header.to_owned(), SortedOrder::Desc)); + let mut output = Some((header.clone(), SortedOrder::Desc)); let mut locked_data = self.app_data.lock(); if let Some((h, order)) = locked_data.get_sorted().as_ref() { if &SortedOrder::Desc == order && h == &header { - output = Some((header, SortedOrder::Asc)) + output = Some((header, SortedOrder::Asc)); } } - locked_data.set_sorted(output) + locked_data.set_sorted(output); } /// Send a quit message to docker, to abort all spawns, if error, quit here instead @@ -219,13 +219,13 @@ impl InputHandler { KeyCode::Up | KeyCode::Char('k') => self.previous(), KeyCode::PageUp => { for _ in 0..=6 { - self.previous() + self.previous(); } } KeyCode::Down | KeyCode::Char('j') => self.next(), KeyCode::PageDown => { for _ in 0..=6 { - self.next() + self.next(); } } KeyCode::Enter => { diff --git a/src/main.rs b/src/main.rs index cb34c34..fec5651 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,9 @@ #![forbid(unsafe_code)] #![warn(clippy::unused_async, clippy::unwrap_used, clippy::expect_used)] // Wanring - These are indeed pedantic -// #![warn(clippy::pedantic)] +#![warn(clippy::pedantic)] // #![warn(clippy::nursery)] -// #![allow(clippy::module_name_repetitions, clippy::doc_markdown)] +#![allow(clippy::module_name_repetitions, clippy::doc_markdown)] // Only allow when debugging // #![allow(unused)] @@ -85,13 +85,8 @@ async fn main() { )); // Debug mode for testing, mostly pointless, doesn't take terminal nor draw gui - if !args.gui { - loop { - info!("in debug mode"); - tokio::time::sleep(std::time::Duration::from_millis(5000)).await; - } - } else { - let update_duration = std::time::Duration::from_millis(args.docker_interval as u64); + if args.gui { + let update_duration = std::time::Duration::from_millis(u64::from(args.docker_interval)); create_ui( app_data, input_sx, @@ -101,6 +96,11 @@ async fn main() { update_duration, ) .await - .unwrap_or(()) + .unwrap_or(()); + } else { + loop { + info!("in debug mode"); + tokio::time::sleep(std::time::Duration::from_millis(5000)).await; + } } } diff --git a/src/ui/color_match.rs b/src/ui/color_match.rs index cf69f1a..5bf4ce1 100644 --- a/src/ui/color_match.rs +++ b/src/ui/color_match.rs @@ -7,9 +7,9 @@ pub mod log_sanitizer { }; /// Attempt to colorize the given string to tui-rs standars - pub fn colorize_logs(input: String) -> Vec> { + pub fn colorize_logs(input: &str) -> Vec> { vec![Spans::from( - categorise_text(&input) + categorise_text(input) .into_iter() .map(|i| { let fg_color = color_ansi_to_tui(i.fg.unwrap_or(CansiColor::White)); @@ -40,10 +40,10 @@ pub mod log_sanitizer { } /// Remove all ansi formatting from a given string and create tui-rs spans - pub fn remove_ansi(input: String) -> Vec> { + pub fn remove_ansi(input: &str) -> Vec> { let mut output = String::from(""); - for i in categorise_text(&input) { - output.push_str(i.text) + for i in categorise_text(input) { + output.push_str(i.text); } raw(output) } @@ -56,22 +56,20 @@ pub mod log_sanitizer { /// Change from ansi to tui colors fn color_ansi_to_tui(color: CansiColor) -> Color { match color { - CansiColor::Black => Color::Black, + CansiColor::Black | CansiColor::BrightBlack => Color::Black, CansiColor::Red => Color::Red, CansiColor::Green => Color::Green, CansiColor::Yellow => Color::Yellow, CansiColor::Blue => Color::Blue, CansiColor::Magenta => Color::Magenta, CansiColor::Cyan => Color::Cyan, - CansiColor::White => Color::White, - CansiColor::BrightBlack => Color::Black, + CansiColor::White | CansiColor::BrightWhite => Color::White, CansiColor::BrightRed => Color::LightRed, CansiColor::BrightGreen => Color::LightGreen, CansiColor::BrightYellow => Color::LightYellow, CansiColor::BrightBlue => Color::LightBlue, CansiColor::BrightMagenta => Color::LightMagenta, CansiColor::BrightCyan => Color::LightCyan, - CansiColor::BrightWhite => Color::White, } } } diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs index 3e4b86c..01e82aa 100644 --- a/src/ui/draw_blocks.rs +++ b/src/ui/draw_blocks.rs @@ -64,7 +64,7 @@ fn generate_block<'a>( SelectablePanel::Logs => { format!(" {} {} ", panel.title(), app_data.lock().get_log_title()) } - _ => String::from(""), + SelectablePanel::Commands => String::from(""), }; block = block.title(title); if current_selected_panel == panel { @@ -74,7 +74,7 @@ fn generate_block<'a>( } /// Draw the command panel -pub fn draw_commands( +pub fn commands( app_data: &Arc>, area: Rect, f: &mut Frame<'_, B>, @@ -111,12 +111,12 @@ pub fn draw_commands( let paragraph = Paragraph::new(debug_text) .block(block) .alignment(Alignment::Center); - f.render_widget(paragraph, area) + f.render_widget(paragraph, area); } } /// Draw the containers panel -pub fn draw_containers( +pub fn containers( app_data: &Arc>, area: Rect, f: &mut Frame<'_, B>, @@ -196,7 +196,7 @@ pub fn draw_containers( let paragraph = Paragraph::new(debug_text) .block(block) .alignment(Alignment::Center); - f.render_widget(paragraph, area) + f.render_widget(paragraph, area); } else { let items = List::new(items) .block(block) @@ -208,13 +208,13 @@ pub fn draw_containers( } /// Draw the logs panel -pub fn draw_logs( +pub fn logs( app_data: &Arc>, area: Rect, f: &mut Frame<'_, B>, gui_state: &Arc>, index: Option, - loading_icon: String, + loading_icon: &str, ) { let block = generate_block(app_data, area, gui_state, SelectablePanel::Logs); @@ -225,14 +225,14 @@ pub fn draw_logs( .style(Style::default()) .block(block) .alignment(Alignment::Center); - f.render_widget(paragraph, area) + f.render_widget(paragraph, area); } else if let Some(index) = index { let items = app_data.lock().containers.items[index] .logs .items .iter() .enumerate() - .map(|i| i.1.to_owned()) + .map(|i| i.1.clone()) .collect::>(); let items = List::new(items) @@ -249,12 +249,12 @@ pub fn draw_logs( let paragraph = Paragraph::new(debug_text) .block(block) .alignment(Alignment::Center); - f.render_widget(paragraph, area) + f.render_widget(paragraph, area); } } /// Draw the cpu + mem charts -pub fn draw_chart( +pub fn chart( f: &mut Frame<'_, B>, area: Rect, app_data: &Arc>, @@ -279,19 +279,21 @@ pub fn draw_chart( .style(Style::default().fg(Color::Cyan)) .graph_type(GraphType::Line) .data(&mem.0)]; + let cpu_stats = CpuStats::new(cpu.0.last().unwrap_or(&(0.00, 0.00)).1); + let mem_stats = ByteStats::new(mem.0.last().unwrap_or(&(0.0, 0.0)).1 as u64); let cpu_chart = make_chart( - cpu.2, - String::from("cpu"), + &cpu.2, + "cpu", cpu_dataset, - CpuStats::new(cpu.0.last().unwrap_or(&(0.00, 0.00)).1), - cpu.1, + &cpu_stats, + &cpu.1, ); let mem_chart = make_chart( - mem.2, - String::from("memory"), + &mem.2, + "memory", mem_dataset, - ByteStats::new(mem.0.last().unwrap_or(&(0.0, 0.0)).1 as u64), - mem.1, + &mem_stats, + &mem.1, ); f.render_widget(cpu_chart, area[0]); @@ -301,13 +303,13 @@ pub fn draw_chart( } /// Create charts -fn make_chart( - state: State, - name: String, - dataset: Vec, - current: T, - max: T, -) -> Chart { +fn make_chart<'a, T: Stats + Display>( + state: &State, + name: &'a str, + dataset: Vec>, + current: &'a T, + max: &'a T, +) -> Chart<'a> { let title_color = match state { State::Running => Color::Green, _ => state.get_color(), @@ -351,13 +353,13 @@ fn make_chart( } /// Draw heading bar at top of program, always visible -pub fn draw_heading_bar( +pub fn heading_bar( area: Rect, columns: &Columns, f: &mut Frame<'_, B>, has_containers: bool, - loading_icon: String, - sorted_by: Option<(Header, SortedOrder)>, + loading_icon: &str, + sorted_by: &Option<(Header, SortedOrder)>, gui_state: &Arc>, ) { let block = || Block::default().style(Style::default().bg(Color::Magenta).fg(Color::Black)); @@ -377,7 +379,7 @@ pub fn draw_heading_bar( SortedOrder::Desc => suffix = " ⌄", } suffix_margin = 2; - color = Color::White + color = Color::White; }; }; ( @@ -441,7 +443,7 @@ pub fn draw_heading_bar( let header_block = gen_header(&i.0, i.1); ( header_block.0, - i.0.to_owned(), + i.0.clone(), Constraint::Max(header_block.1), ) }) @@ -500,7 +502,7 @@ fn max_line_width(text: &str) -> usize { } /// Draw the help box in the centre of the screen -pub fn draw_help_box(f: &mut Frame<'_, B>) { +pub fn help_box(f: &mut Frame<'_, B>) { let title = format!(" {} ", VERSION); let description_text = format!("\n{}", DESCRIPTION); @@ -550,7 +552,7 @@ pub fn draw_help_box(f: &mut Frame<'_, B>) { .border_type(BorderType::Rounded) .border_style(Style::default().fg(Color::Black)); - let area = draw_popup( + let area = popup( lines as u16, max_line_width as u16, f.size(), @@ -578,7 +580,7 @@ pub fn draw_help_box(f: &mut Frame<'_, B>) { } /// Draw an error popup over whole screen -pub fn draw_error(f: &mut Frame<'_, B>, error: AppError, seconds: Option) { +pub fn error(f: &mut Frame<'_, B>, error: &AppError, seconds: Option) { let block = Block::default() .title(" Error ") .border_type(BorderType::Rounded) @@ -614,7 +616,7 @@ pub fn draw_error(f: &mut Frame<'_, B>, error: AppError, seconds: Op .block(block) .alignment(Alignment::Center); - let area = draw_popup( + let area = popup( lines as u16, max_line_width as u16, f.size(), @@ -625,7 +627,7 @@ pub fn draw_error(f: &mut Frame<'_, B>, error: AppError, seconds: Op } /// Draw info box in one of the 9 BoxLocations -pub fn draw_info(f: &mut Frame<'_, B>, text: String) { +pub fn info(f: &mut Frame<'_, B>, text: String) { let block = Block::default() .title("") .title_alignment(Alignment::Center) @@ -643,7 +645,7 @@ pub fn draw_info(f: &mut Frame<'_, B>, text: String) { .block(block) .alignment(Alignment::Center); - let area = draw_popup( + let area = popup( lines as u16, max_line_width as u16, f.size(), @@ -654,7 +656,7 @@ pub fn draw_info(f: &mut Frame<'_, B>, text: String) { } /// draw a box in the one of the BoxLocations, based on max line width + number of lines -fn draw_popup(text_lines: u16, text_width: u16, r: Rect, box_location: BoxLocation) -> Rect { +fn popup(text_lines: u16, text_width: u16, r: Rect, box_location: BoxLocation) -> Rect { // Make sure blank_space can't be an negative, as will crash let blank_vertical = if r.height > text_lines { (r.height - text_lines) / 2 diff --git a/src/ui/gui_state.rs b/src/ui/gui_state.rs index 34add3e..0eec348 100644 --- a/src/ui/gui_state.rs +++ b/src/ui/gui_state.rs @@ -30,7 +30,7 @@ pub enum BoxLocation { } impl BoxLocation { - pub fn get_indexes(&self) -> (usize, usize) { + pub fn get_indexes(self) -> (usize, usize) { match self { Self::TopLeft => (0, 0), Self::TopCentre => (0, 1), @@ -46,7 +46,7 @@ impl BoxLocation { // Should combine and just return a tuple? pub fn get_horizontal_constraints( - &self, + self, blank_vertical: u16, text_width: u16, ) -> [Constraint; 3] { @@ -69,7 +69,7 @@ impl BoxLocation { } } pub fn get_vertical_constraints( - &self, + self, blank_vertical: u16, number_lines: u16, ) -> [Constraint; 3] { @@ -147,7 +147,7 @@ impl SelectablePanel { match self { Self::Containers => "Containers", Self::Logs => "Logs", - _ => "", + Self::Commands => "", } } pub fn next(self) -> Self { @@ -221,7 +221,7 @@ impl GuiState { .filter(|i| i.1.intersects(rect)) .collect::>() .get(0) - .map(|data| data.0.to_owned()) + .map(|data| data.0.clone()) } /// Insert, or updatem header area panel into heading_map diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 71c090a..7d16f7f 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -30,7 +30,6 @@ use crate::{ app_data::AppData, app_error::AppError, docker_data::DockerMessage, input_handler::InputMessages, }; -use draw_blocks::*; /// Take control of the terminal in order to draw gui pub async fn create_ui( @@ -95,7 +94,7 @@ async fn run_app( break; } if terminal - .draw(|f| draw_error(f, AppError::DockerConnect, Some(seconds))) + .draw(|f| draw_blocks::error(f, &AppError::DockerConnect, Some(seconds))) .is_err() { return Err(AppError::Terminal); @@ -152,7 +151,7 @@ fn ui( if height < 12 { height += 4; } else { - height = 12 + height = 12; } let column_widths = app_data.lock().get_width(); @@ -199,47 +198,47 @@ fn ui( .constraints(lower_split.as_ref()) .split(upper_main[1]); - draw_containers(app_data, top_panel[0], f, gui_state, &column_widths); + draw_blocks::containers(app_data, top_panel[0], f, gui_state, &column_widths); if has_containers { - draw_commands(app_data, top_panel[1], f, gui_state, log_index); + draw_blocks::commands(app_data, top_panel[1], f, gui_state, log_index); } - draw_logs( + draw_blocks::logs( app_data, lower_main[0], f, gui_state, log_index, - loading_icon.to_owned(), + &loading_icon, ); - draw_heading_bar( + draw_blocks::heading_bar( whole_layout[0], &column_widths, f, has_containers, - loading_icon, - sorted_by, + &loading_icon, + &sorted_by, gui_state, ); // only draw charts if there are containers if has_containers { - draw_chart(f, lower_main[1], app_data, log_index); + draw_blocks::chart(f, lower_main[1], app_data, log_index); } if let Some(info) = info_text { - draw_info(f, info); + draw_blocks::info(f, info); } // Check if error, and show popup if so if show_help { - draw_help_box(f); + draw_blocks::help_box(f); } if let Some(error) = has_error { app_data.lock().show_error = true; - draw_error(f, error, None); + draw_blocks::error(f, &error, None); } } From 1bd61d4ce8b369d6d078201add3eea0f59fe0dea Mon Sep 17 00:00:00 2001 From: Jack Wills <32690432+mrjackwills@users.noreply.github.com> Date: Thu, 4 Aug 2022 13:01:16 +0000 Subject: [PATCH 06/11] chore: linting nursery --- src/app_data/container_state.rs | 22 +++++++++------------- src/app_data/mod.rs | 6 +----- src/docker_data/mod.rs | 6 +----- src/main.rs | 4 ++-- src/parse_args/mod.rs | 2 +- src/ui/color_match.rs | 2 +- src/ui/gui_state.rs | 14 +++++++------- src/ui/mod.rs | 2 +- 8 files changed, 23 insertions(+), 35 deletions(-) diff --git a/src/app_data/container_state.rs b/src/app_data/container_state.rs index e81ee5a..4d91c22 100644 --- a/src/app_data/container_state.rs +++ b/src/app_data/container_state.rs @@ -68,15 +68,11 @@ impl StatefulList { String::from("") } else { let len = self.items.len(); - let c = if let Some(value) = self.state.selected() { - if len > 0 { + let c = self.state.selected().map_or(0, |value| if len > 0 { value + 1 } else { value - } - } else { - 0 - }; + }); format!("{}/{}", c, self.items.len()) } } @@ -95,7 +91,7 @@ pub enum State { } impl State { - pub fn get_color(&self) -> Color { + pub const fn get_color(&self) -> Color { match self { Self::Running => Color::Green, Self::Removing => Color::LightRed, @@ -105,7 +101,7 @@ impl State { } } // Dirty way to create order for the state, rather than impl Ord - pub fn order(&self) -> &'static str { + pub const fn order(&self) -> &'static str { match self { Self::Running => "a", Self::Paused => "b", @@ -158,7 +154,7 @@ pub enum DockerControls { } impl DockerControls { - pub fn get_color(&self) -> Color { + pub const fn get_color(&self) -> Color { match self { Self::Start => Color::Green, Self::Stop => Color::Red, @@ -205,7 +201,7 @@ pub struct CpuStats { } impl CpuStats { - pub fn new(value: f64) -> Self { + pub const fn new(value: f64) -> Self { Self { value } } } @@ -276,7 +272,7 @@ impl Ord for ByteStats { } impl ByteStats { - pub fn new(value: u64) -> Self { + pub const fn new(value: u64) -> Self { Self { value } } pub fn update(&mut self, value: u64) { @@ -423,8 +419,8 @@ pub struct Columns { } impl Columns { - // (Column titles, minimum header string length) - pub fn new() -> Self { + /// (Column titles, minimum header string length) + pub const fn new() -> Self { Self { state: (Header::State, 11), status: (Header::Status, 16), diff --git a/src/app_data/mod.rs b/src/app_data/mod.rs index 678ce41..d725393 100644 --- a/src/app_data/mod.rs +++ b/src/app_data/mod.rs @@ -259,11 +259,7 @@ impl AppData { /// Get the title for log panel for selected container /// will be "logs x/x" pub fn get_log_title(&self) -> String { - if let Some(index) = self.get_selected_log_index() { - self.containers.items[index].logs.get_state_title() - } else { - String::from("") - } + self.get_selected_log_index().map_or_else(|| String::from(""), |index| self.containers.items[index].logs.get_state_title()) } /// select next selected log line diff --git a/src/docker_data/mod.rs b/src/docker_data/mod.rs index 2aeb49d..0fc4a72 100644 --- a/src/docker_data/mod.rs +++ b/src/docker_data/mod.rs @@ -102,11 +102,7 @@ impl DockerData { let mem_stat = stats.memory_stats.usage.unwrap_or(0); let mem_limit = stats.memory_stats.limit.unwrap_or(0); - let some_key = if let Some(networks) = &stats.networks { - networks.keys().next().cloned() - } else { - None - }; + let some_key = stats.networks.as_ref().and_then(|networks| networks.keys().next().cloned()); let cpu_stats = Self::calculate_usage(&stats); diff --git a/src/main.rs b/src/main.rs index fec5651..12a74b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,8 @@ #![forbid(unsafe_code)] #![warn(clippy::unused_async, clippy::unwrap_used, clippy::expect_used)] // Wanring - These are indeed pedantic -#![warn(clippy::pedantic)] -// #![warn(clippy::nursery)] +// #![warn(clippy::pedantic)] +#![warn(clippy::nursery)] #![allow(clippy::module_name_repetitions, clippy::doc_markdown)] // Only allow when debugging diff --git a/src/parse_args/mod.rs b/src/parse_args/mod.rs index d76f88a..a115aed 100644 --- a/src/parse_args/mod.rs +++ b/src/parse_args/mod.rs @@ -31,7 +31,7 @@ pub struct CliArgs { impl CliArgs { /// Parse cli arguments pub fn new() -> Self { - let args = CliArgs::parse(); + let args = Self::parse(); // Quit the program if the docker update argument is 0 // Should maybe change it to check if less than 100 diff --git a/src/ui/color_match.rs b/src/ui/color_match.rs index 5bf4ce1..149d74a 100644 --- a/src/ui/color_match.rs +++ b/src/ui/color_match.rs @@ -54,7 +54,7 @@ pub mod log_sanitizer { } /// Change from ansi to tui colors - fn color_ansi_to_tui(color: CansiColor) -> Color { + const fn color_ansi_to_tui(color: CansiColor) -> Color { match color { CansiColor::Black | CansiColor::BrightBlack => Color::Black, CansiColor::Red => Color::Red, diff --git a/src/ui/gui_state.rs b/src/ui/gui_state.rs index 0eec348..5711148 100644 --- a/src/ui/gui_state.rs +++ b/src/ui/gui_state.rs @@ -30,7 +30,7 @@ pub enum BoxLocation { } impl BoxLocation { - pub fn get_indexes(self) -> (usize, usize) { + pub const fn get_indexes(self) -> (usize, usize) { match self { Self::TopLeft => (0, 0), Self::TopCentre => (0, 1), @@ -45,7 +45,7 @@ impl BoxLocation { } // Should combine and just return a tuple? - pub fn get_horizontal_constraints( + pub const fn get_horizontal_constraints( self, blank_vertical: u16, text_width: u16, @@ -68,7 +68,7 @@ impl BoxLocation { ], } } - pub fn get_vertical_constraints( + pub const fn get_vertical_constraints( self, blank_vertical: u16, number_lines: u16, @@ -108,7 +108,7 @@ pub enum Loading { } impl Loading { - pub fn next(&self) -> Self { + pub const fn next(&self) -> Self { match self { Self::One => Self::Two, Self::Two => Self::Three, @@ -143,21 +143,21 @@ impl fmt::Display for Loading { } impl SelectablePanel { - pub fn title(self) -> &'static str { + pub const fn title(self) -> &'static str { match self { Self::Containers => "Containers", Self::Logs => "Logs", Self::Commands => "", } } - pub fn next(self) -> Self { + pub const fn next(self) -> Self { match self { Self::Containers => Self::Commands, Self::Commands => Self::Logs, Self::Logs => Self::Containers, } } - pub fn prev(self) -> Self { + pub const fn prev(self) -> Self { match self { Self::Containers => Self::Logs, Self::Commands => Self::Containers, diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 7d16f7f..55e3d50 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -72,7 +72,7 @@ pub async fn create_ui( } /// Run a loop to draw the gui -async fn run_app( +async fn run_app( terminal: &mut Terminal, app_data: Arc>, sender: Sender, From 0e11767db8bd230c1ad33f180d377cf33093c8b2 Mon Sep 17 00:00:00 2001 From: Jack Wills <32690432+mrjackwills@users.noreply.github.com> Date: Thu, 4 Aug 2022 13:18:27 +0000 Subject: [PATCH 07/11] chore: cargo fmt --- src/app_data/container_state.rs | 9 ++++----- src/app_data/mod.rs | 5 ++++- src/docker_data/mod.rs | 5 ++++- src/ui/draw_blocks.rs | 26 +++++--------------------- 4 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/app_data/container_state.rs b/src/app_data/container_state.rs index 4d91c22..37b35fd 100644 --- a/src/app_data/container_state.rs +++ b/src/app_data/container_state.rs @@ -68,11 +68,10 @@ impl StatefulList { String::from("") } else { let len = self.items.len(); - let c = self.state.selected().map_or(0, |value| if len > 0 { - value + 1 - } else { - value - }); + let c = self + .state + .selected() + .map_or(0, |value| if len > 0 { value + 1 } else { value }); format!("{}/{}", c, self.items.len()) } } diff --git a/src/app_data/mod.rs b/src/app_data/mod.rs index d725393..da15bfe 100644 --- a/src/app_data/mod.rs +++ b/src/app_data/mod.rs @@ -259,7 +259,10 @@ impl AppData { /// Get the title for log panel for selected container /// will be "logs x/x" pub fn get_log_title(&self) -> String { - self.get_selected_log_index().map_or_else(|| String::from(""), |index| self.containers.items[index].logs.get_state_title()) + self.get_selected_log_index().map_or_else( + || String::from(""), + |index| self.containers.items[index].logs.get_state_title(), + ) } /// select next selected log line diff --git a/src/docker_data/mod.rs b/src/docker_data/mod.rs index 0fc4a72..19019ba 100644 --- a/src/docker_data/mod.rs +++ b/src/docker_data/mod.rs @@ -102,7 +102,10 @@ impl DockerData { let mem_stat = stats.memory_stats.usage.unwrap_or(0); let mem_limit = stats.memory_stats.limit.unwrap_or(0); - let some_key = stats.networks.as_ref().and_then(|networks| networks.keys().next().cloned()); + let some_key = stats + .networks + .as_ref() + .and_then(|networks| networks.keys().next().cloned()); let cpu_stats = Self::calculate_usage(&stats); diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs index 01e82aa..30d594a 100644 --- a/src/ui/draw_blocks.rs +++ b/src/ui/draw_blocks.rs @@ -279,22 +279,10 @@ pub fn chart( .style(Style::default().fg(Color::Cyan)) .graph_type(GraphType::Line) .data(&mem.0)]; - let cpu_stats = CpuStats::new(cpu.0.last().unwrap_or(&(0.00, 0.00)).1); - let mem_stats = ByteStats::new(mem.0.last().unwrap_or(&(0.0, 0.0)).1 as u64); - let cpu_chart = make_chart( - &cpu.2, - "cpu", - cpu_dataset, - &cpu_stats, - &cpu.1, - ); - let mem_chart = make_chart( - &mem.2, - "memory", - mem_dataset, - &mem_stats, - &mem.1, - ); + let cpu_stats = CpuStats::new(cpu.0.last().unwrap_or(&(0.00, 0.00)).1); + let mem_stats = ByteStats::new(mem.0.last().unwrap_or(&(0.0, 0.0)).1 as u64); + let cpu_chart = make_chart(&cpu.2, "cpu", cpu_dataset, &cpu_stats, &cpu.1); + let mem_chart = make_chart(&mem.2, "memory", mem_dataset, &mem_stats, &mem.1); f.render_widget(cpu_chart, area[0]); f.render_widget(mem_chart, area[1]); @@ -441,11 +429,7 @@ pub fn heading_bar( .iter() .map(|i| { let header_block = gen_header(&i.0, i.1); - ( - header_block.0, - i.0.clone(), - Constraint::Max(header_block.1), - ) + (header_block.0, i.0.clone(), Constraint::Max(header_block.1)) }) .collect::>(); From 258ada731bae29df157f2cbaeb46c2dccf547704 Mon Sep 17 00:00:00 2001 From: Jack Wills <32690432+mrjackwills@users.noreply.github.com> Date: Thu, 4 Aug 2022 13:29:09 +0000 Subject: [PATCH 08/11] chore: linting warns removed --- src/app_data/container_state.rs | 2 +- src/app_data/mod.rs | 12 ++++++------ src/main.rs | 4 ++-- src/ui/mod.rs | 10 +++++----- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/app_data/container_state.rs b/src/app_data/container_state.rs index 37b35fd..183186c 100644 --- a/src/app_data/container_state.rs +++ b/src/app_data/container_state.rs @@ -223,7 +223,7 @@ impl Ord for CpuStats { fn cmp(&self, other: &Self) -> Ordering { if self.value > other.value { Ordering::Greater - } else if self.value == other.value { + } else if (self.value - other.value).abs() < 0.01 { Ordering::Equal } else { Ordering::Less diff --git a/src/app_data/mod.rs b/src/app_data/mod.rs index da15bfe..39bc5ee 100644 --- a/src/app_data/mod.rs +++ b/src/app_data/mod.rs @@ -329,8 +329,8 @@ impl AppData { container.mem_limit )); - let net_rx_count = count(&container.rx.to_string()); - let net_tx_count = count(&container.tx.to_string()); + let rx_count = count(&container.rx.to_string()); + let tx_count = count(&container.tx.to_string()); let image_count = count(&container.image); let name_count = count(&container.name); let state_count = count(&container.state.to_string()); @@ -354,11 +354,11 @@ impl AppData { if status_count > output.status.1 { output.status.1 = status_count; }; - if net_rx_count > output.net_rx.1 { - output.net_rx.1 = net_rx_count; + if rx_count > output.net_rx.1 { + output.net_rx.1 = rx_count; }; - if net_tx_count > output.net_tx.1 { - output.net_tx.1 = net_tx_count; + if tx_count > output.net_tx.1 { + output.net_tx.1 = tx_count; }; } output diff --git a/src/main.rs b/src/main.rs index 12a74b9..b7fda0e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,8 @@ #![warn(clippy::unused_async, clippy::unwrap_used, clippy::expect_used)] // Wanring - These are indeed pedantic // #![warn(clippy::pedantic)] -#![warn(clippy::nursery)] -#![allow(clippy::module_name_repetitions, clippy::doc_markdown)] +// #![warn(clippy::nursery)] +// #![allow(clippy::module_name_repetitions, clippy::doc_markdown)] // Only allow when debugging // #![allow(unused)] diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 55e3d50..6d59eaa 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -147,12 +147,12 @@ fn ui( gui_state: &Arc>, ) { // set max height for container section, needs +4 to deal with docker commands list and borders - let mut height = app_data.lock().get_container_len(); - if height < 12 { - height += 4; + let height = app_data.lock().get_container_len(); + let height = if height < 12 { + (height + 4) as u16 } else { - height = 12; - } + 12 + }; let column_widths = app_data.lock().get_width(); let has_containers = !app_data.lock().containers.items.is_empty(); From c19b0c08a0b5001b0d93ffaf9a1d0ab911d7e2f0 Mon Sep 17 00:00:00 2001 From: Jack Wills <32690432+mrjackwills@users.noreply.github.com> Date: Thu, 4 Aug 2022 16:47:41 +0000 Subject: [PATCH 09/11] docs: changelog --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ed95b3..4272522 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +### Chores ++ dependencies updated, [d9801cdf372521fe5624a8d68fac83ed39ef81f4] ++ linting: nursery, pedantic, unused_unwraps, [1bd61d4ce8b369d6d078201add3eea0f59fe0dea], [1263662bd9412afacddbc10721bf216ae3a843f1], [ca3315a69f593ad705eb637f227f195edd7781b2] + +### Features ++ build all production targets on release, [44f8140eaec330abe5a94f3ddae9e8b223688aa8] + +### Fixes ++ toml keywords, [dd2d82d114537e09dbeb12f360157f0e68e7846e] + # v0.1.2 ### 2022-07-23 From 965d5184df9ba8173a8da4d383008ce68dc470c6 Mon Sep 17 00:00:00 2001 From: Jack Wills <32690432+mrjackwills@users.noreply.github.com> Date: Thu, 4 Aug 2022 17:04:45 +0000 Subject: [PATCH 10/11] fix: create_release.sh typo --- create_release.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/create_release.sh b/create_release.sh index 349293e..4fe3c85 100755 --- a/create_release.sh +++ b/create_release.sh @@ -184,8 +184,11 @@ cargo_test () { cargo_build () { cargo install cross cargo build --release + ask_continue cross build --target aarch64-unknown-linux-musl --release + ask_continue cross build --target arm-unknown-linux-musleabihf --release + ask_continue cross build --target x86_64-pc-windows-gnu --release ask_continue } From 305f3ee980094fcb1f12b437d4b0d928eb12d268 Mon Sep 17 00:00:00 2001 From: Jack Wills <32690432+mrjackwills@users.noreply.github.com> Date: Thu, 4 Aug 2022 17:25:50 +0000 Subject: [PATCH 11/11] chore: release v0.1.3 --- .github/release-body.md | 11 +++++++++-- CHANGELOG.md | 11 +++++++---- Cargo.toml | 2 +- src/ui/mod.rs | 6 +----- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/.github/release-body.md b/.github/release-body.md index 6339c93..31b0f6c 100644 --- a/.github/release-body.md +++ b/.github/release-body.md @@ -1,7 +1,14 @@ -### 2022-07-23 +### 2022-08-04 + +### Chores ++ dependencies updated, [d9801cdf372521fe5624a8d68fac83ed39ef81f4] ++ linting: nursery, pedantic, unused_unwraps, [1bd61d4ce8b369d6d078201add3eea0f59fe0dea], [1263662bd9412afacddbc10721bf216ae3a843f1], [ca3315a69f593ad705eb637f227f195edd7781b2] + +### Features ++ build all production targets on release, [44f8140eaec330abe5a94f3ddae9e8b223688aa8] ### Fixes -+ remove reqwest dependency, [10ff8bab5f01f097fd6cdec60b2be947f238197b] ++ toml keywords, [dd2d82d114537e09dbeb12f360157f0e68e7846e] see CHANGELOG.md for more details diff --git a/CHANGELOG.md b/CHANGELOG.md index 4272522..602b578 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,15 @@ +# v0.1.3 +### 2022-08-04 + ### Chores -+ dependencies updated, [d9801cdf372521fe5624a8d68fac83ed39ef81f4] -+ linting: nursery, pedantic, unused_unwraps, [1bd61d4ce8b369d6d078201add3eea0f59fe0dea], [1263662bd9412afacddbc10721bf216ae3a843f1], [ca3315a69f593ad705eb637f227f195edd7781b2] ++ dependencies updated, [d9801cdf](https://github.com/mrjackwills/oxker/commit/d9801cdf372521fe5624a8d68fac83ed39ef81f4), ++ linting: nursery, pedantic, unused_unwraps, [1bd61d4c](https://github.com/mrjackwills/oxker/commit/1bd61d4ce8b369d6d078201add3eea0f59fe0dea),, [1263662b](https://github.com/mrjackwills/oxker/commit/1263662bd9412afacddbc10721bf216ae3a843f1),, [ca3315a6](https://github.com/mrjackwills/oxker/commit/ca3315a69f593ad705eb637f227f195edd7781b2), ### Features -+ build all production targets on release, [44f8140eaec330abe5a94f3ddae9e8b223688aa8] ++ build all production targets on release, [44f8140e](https://github.com/mrjackwills/oxker/commit/44f8140eaec330abe5a94f3ddae9e8b223688aa8), ### Fixes -+ toml keywords, [dd2d82d114537e09dbeb12f360157f0e68e7846e] ++ toml keywords, [dd2d82d1](https://github.com/mrjackwills/oxker/commit/dd2d82d114537e09dbeb12f360157f0e68e7846e), # v0.1.2 ### 2022-07-23 diff --git a/Cargo.toml b/Cargo.toml index 0f0a62d..3d7654b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxker" -version = "0.1.2" +version = "0.1.3" edition = "2021" authors = ["Jack Wills "] description = "a simple tui to view & control docker containers" diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 6d59eaa..9a529fd 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -148,11 +148,7 @@ fn ui( ) { // set max height for container section, needs +4 to deal with docker commands list and borders let height = app_data.lock().get_container_len(); - let height = if height < 12 { - (height + 4) as u16 - } else { - 12 - }; + let height = if height < 12 { (height + 4) as u16 } else { 12 }; let column_widths = app_data.lock().get_width(); let has_containers = !app_data.lock().containers.items.is_empty();