fix: Enable quit on Docker connect error screen
This commit is contained in:
@@ -420,7 +420,7 @@ impl fmt::Display for State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Items for the container control list
|
/// Items for the container control list
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub enum DockerCommand {
|
pub enum DockerCommand {
|
||||||
Pause,
|
Pause,
|
||||||
Restart,
|
Restart,
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ use crate::app_data::DockerCommand;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
/// app errors to set in global state
|
/// app errors to set in global state
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub enum AppError {
|
pub enum AppError {
|
||||||
DockerCommand(DockerCommand),
|
DockerCommand(DockerCommand),
|
||||||
DockerExec,
|
DockerExec,
|
||||||
|
|||||||
+15
-11
@@ -42,15 +42,17 @@ fn setup_tracing() {
|
|||||||
tracing_subscriber::fmt().with_max_level(Level::INFO).init();
|
tracing_subscriber::fmt().with_max_level(Level::INFO).init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read the optional docker_host path, the DOCKER_HOST env take priority over cli or config
|
/// Read the optional docker_host path
|
||||||
/// Bollard will use DOCKER_HOST env, so might be pointless here, although it will fix it's priority over any config setting
|
/// Bollard will use DOCKER_HOST env, so might be pointless here, although it will fix it's priority over any config setting
|
||||||
fn read_docker_host(config: &Config) -> Option<String> {
|
fn read_docker_host(config: &Config) -> Option<String> {
|
||||||
if let Ok(env) = std::env::var(DOCKER_HOST)
|
if let Some(x) = &config.host {
|
||||||
|
Some(x.to_string())
|
||||||
|
} else if let Ok(env) = std::env::var(DOCKER_HOST)
|
||||||
&& !env.trim().is_empty()
|
&& !env.trim().is_empty()
|
||||||
{
|
{
|
||||||
Some(env)
|
Some(env)
|
||||||
} else {
|
} else {
|
||||||
config.host.as_ref().cloned()
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,23 +176,24 @@ mod tests {
|
|||||||
/// Default test config, has timestamps turned off
|
/// Default test config, has timestamps turned off
|
||||||
pub fn gen_config() -> Config {
|
pub fn gen_config() -> Config {
|
||||||
Config {
|
Config {
|
||||||
|
app_colors: AppColors::new(),
|
||||||
color_logs: false,
|
color_logs: false,
|
||||||
|
dir_save: None,
|
||||||
|
dir_config: None,
|
||||||
docker_interval_ms: 1000,
|
docker_interval_ms: 1000,
|
||||||
gui: true,
|
gui: true,
|
||||||
host: None,
|
host: None,
|
||||||
show_std_err: false,
|
|
||||||
in_container: false,
|
in_container: false,
|
||||||
save_dir: None,
|
keymap: Keymap::new(),
|
||||||
log_search_case_sensitive: true,
|
log_search_case_sensitive: true,
|
||||||
raw_logs: false,
|
raw_logs: false,
|
||||||
show_self: false,
|
|
||||||
app_colors: AppColors::new(),
|
|
||||||
keymap: Keymap::new(),
|
|
||||||
timestamp_format: "HH:MM:SS.NNNNN dd-mm-yyyy".to_owned(),
|
|
||||||
show_timestamp: false,
|
|
||||||
use_cli: false,
|
|
||||||
show_logs: true,
|
show_logs: true,
|
||||||
|
show_self: false,
|
||||||
|
show_std_err: false,
|
||||||
|
show_timestamp: false,
|
||||||
|
timestamp_format: "HH:MM:SS.NNNNN dd-mm-yyyy".to_owned(),
|
||||||
timezone: None,
|
timezone: None,
|
||||||
|
use_cli: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,6 +219,7 @@ mod tests {
|
|||||||
containers: StatefulList::new(containers.to_vec()),
|
containers: StatefulList::new(containers.to_vec()),
|
||||||
hidden_containers: vec![],
|
hidden_containers: vec![],
|
||||||
current_sorted_id: vec![],
|
current_sorted_id: vec![],
|
||||||
|
inspect_data: None,
|
||||||
error: None,
|
error: None,
|
||||||
sorted_by: None,
|
sorted_by: None,
|
||||||
rerender: Arc::new(Rerender::new()),
|
rerender: Arc::new(Rerender::new()),
|
||||||
|
|||||||
+20
-15
@@ -32,19 +32,21 @@ pub fn draw(
|
|||||||
.title_alignment(Alignment::Center)
|
.title_alignment(Alignment::Center)
|
||||||
.borders(Borders::ALL);
|
.borders(Borders::ALL);
|
||||||
|
|
||||||
let to_push = if matches!(error, AppError::DockerConnect) {
|
let mut text = format!("\n{error}");
|
||||||
|
|
||||||
|
if error == &AppError::DockerConnect {
|
||||||
let s = if let Some(host) = host {
|
let s = if let Some(host) = host {
|
||||||
format!(" @ \"{host}\"")
|
format!(" @ \"{host}\"")
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
String::new()
|
||||||
};
|
};
|
||||||
format!(
|
text.push_str(&format!(
|
||||||
"{}\n\n {}::v{} closing in {:02} seconds",
|
"{}\n\n {}::v{} closing in {:02} seconds",
|
||||||
s,
|
s,
|
||||||
NAME,
|
NAME,
|
||||||
VERSION,
|
VERSION,
|
||||||
seconds.unwrap_or(5),
|
seconds.unwrap_or(5),
|
||||||
)
|
))
|
||||||
} else {
|
} else {
|
||||||
let clear_text = if keymap.clear == Keymap::new().clear {
|
let clear_text = if keymap.clear == Keymap::new().clear {
|
||||||
format!("( {} ) {SUFFIX_CLEAR}", keymap.clear.0)
|
format!("( {} ) {SUFFIX_CLEAR}", keymap.clear.0)
|
||||||
@@ -53,6 +55,8 @@ pub fn draw(
|
|||||||
} else {
|
} else {
|
||||||
format!(" ( {} ) {SUFFIX_CLEAR}", keymap.clear.0)
|
format!(" ( {} ) {SUFFIX_CLEAR}", keymap.clear.0)
|
||||||
};
|
};
|
||||||
|
text.push_str(&format!("\n\n{clear_text}"));
|
||||||
|
}
|
||||||
|
|
||||||
let quit_text = if keymap.quit == Keymap::new().quit {
|
let quit_text = if keymap.quit == Keymap::new().quit {
|
||||||
format!("( {} ) {SUFFIX_QUIT}", keymap.quit.0)
|
format!("( {} ) {SUFFIX_QUIT}", keymap.quit.0)
|
||||||
@@ -61,12 +65,7 @@ pub fn draw(
|
|||||||
} else {
|
} else {
|
||||||
format!(" ( {} ) {SUFFIX_QUIT}", keymap.quit.0)
|
format!(" ( {} ) {SUFFIX_QUIT}", keymap.quit.0)
|
||||||
};
|
};
|
||||||
format!("\n\n{clear_text}\n\n{quit_text}")
|
text.push_str(&format!("\n\n{quit_text}"));
|
||||||
};
|
|
||||||
|
|
||||||
let mut text = format!("\n{error}");
|
|
||||||
|
|
||||||
text.push_str(to_push.as_str());
|
|
||||||
|
|
||||||
// Find the maximum line width & height
|
// Find the maximum line width & height
|
||||||
let padded_width = max_line_width(&text) + 8;
|
let padded_width = max_line_width(&text) + 8;
|
||||||
@@ -113,7 +112,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
/// Test that the error popup is centered, red background, white border, white text, and displays the correct text
|
/// Test that the error popup is centered, red background, white border, white text, and displays the correct text
|
||||||
fn test_draw_blocks_error_docker_connect_error() {
|
fn test_draw_blocks_error_docker_connect_error() {
|
||||||
let mut setup = test_setup(46, 9, true, true);
|
let mut setup = test_setup(50, 11, true, true);
|
||||||
setup
|
setup
|
||||||
.terminal
|
.terminal
|
||||||
.draw(|f| {
|
.draw(|f| {
|
||||||
@@ -130,21 +129,24 @@ mod tests {
|
|||||||
assert_snapshot!(setup.terminal.backend());
|
assert_snapshot!(setup.terminal.backend());
|
||||||
for (row_index, result_row) in get_result(&setup) {
|
for (row_index, result_row) in get_result(&setup) {
|
||||||
for (result_cell_index, result_cell) in result_row.iter().enumerate() {
|
for (result_cell_index, result_cell) in result_row.iter().enumerate() {
|
||||||
if let (0 | 8, _) = (row_index, result_cell_index) {
|
match (row_index, result_cell_index) {
|
||||||
|
(0 | 10, _) | (_, 0 | 49) => {
|
||||||
assert_eq!(result_cell.bg, Color::Reset);
|
assert_eq!(result_cell.bg, Color::Reset);
|
||||||
assert_eq!(result_cell.fg, Color::Reset);
|
assert_eq!(result_cell.fg, Color::Reset);
|
||||||
} else {
|
}
|
||||||
|
_ => {
|
||||||
assert_eq!(result_cell.bg, Color::Red);
|
assert_eq!(result_cell.bg, Color::Red);
|
||||||
assert_eq!(result_cell.fg, Color::White);
|
assert_eq!(result_cell.fg, Color::White);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
/// Test that the error popup is centered, red background, white border, white text, and displays the correct text with the custom docker host address
|
/// Test that the error popup is centered, red background, white border, white text, and displays the correct text with the custom docker host address
|
||||||
fn test_draw_blocks_error_docker_connect_error_custom_host() {
|
fn test_draw_blocks_error_docker_connect_error_custom_host() {
|
||||||
let mut setup = test_setup(46, 9, true, true);
|
let mut setup = test_setup(60, 11, true, true);
|
||||||
|
|
||||||
setup
|
setup
|
||||||
.terminal
|
.terminal
|
||||||
@@ -162,16 +164,19 @@ mod tests {
|
|||||||
assert_snapshot!(setup.terminal.backend());
|
assert_snapshot!(setup.terminal.backend());
|
||||||
for (row_index, result_row) in get_result(&setup) {
|
for (row_index, result_row) in get_result(&setup) {
|
||||||
for (result_cell_index, result_cell) in result_row.iter().enumerate() {
|
for (result_cell_index, result_cell) in result_row.iter().enumerate() {
|
||||||
if let (0 | 8, _) = (row_index, result_cell_index) {
|
match (row_index, result_cell_index) {
|
||||||
|
(0 | 10, _) | (_, 0 | 59) => {
|
||||||
assert_eq!(result_cell.bg, Color::Reset);
|
assert_eq!(result_cell.bg, Color::Reset);
|
||||||
assert_eq!(result_cell.fg, Color::Reset);
|
assert_eq!(result_cell.fg, Color::Reset);
|
||||||
} else {
|
}
|
||||||
|
_ => {
|
||||||
assert_eq!(result_cell.bg, Color::Red);
|
assert_eq!(result_cell.bg, Color::Red);
|
||||||
assert_eq!(result_cell.fg, Color::White);
|
assert_eq!(result_cell.fg, Color::White);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
/// Test that the clearable error popup is centered, red background, white border, white text, and displays the correct text
|
/// Test that the clearable error popup is centered, red background, white border, white text, and displays the correct text
|
||||||
|
|||||||
+9
-7
@@ -3,11 +3,13 @@ source: src/ui/draw_blocks/error.rs
|
|||||||
expression: setup.terminal.backend()
|
expression: setup.terminal.backend()
|
||||||
---
|
---
|
||||||
" "
|
" "
|
||||||
"╭────────────────── Error ───────────────────╮"
|
" ╭─────────────────── Error ────────────────────╮ "
|
||||||
"│ │"
|
" │ │ "
|
||||||
"│ Unable to access docker daemon │"
|
" │ Unable to access docker daemon │ "
|
||||||
"│ │"
|
" │ │ "
|
||||||
"│ oxker::v0.00.000 closing in 04 seconds │"
|
" │ oxker::v0.00.000 closing in 04 seconds │ "
|
||||||
"│ │"
|
" │ │ "
|
||||||
"╰────────────────────────────────────────────╯"
|
" │ ( q ) quit oxker │ "
|
||||||
|
" │ │ "
|
||||||
|
" ╰──────────────────────────────────────────────╯ "
|
||||||
" "
|
" "
|
||||||
|
|||||||
+9
-7
@@ -3,11 +3,13 @@ source: src/ui/draw_blocks/error.rs
|
|||||||
expression: setup.terminal.backend()
|
expression: setup.terminal.backend()
|
||||||
---
|
---
|
||||||
" "
|
" "
|
||||||
"╭────────────────── Error ───────────────────╮"
|
" ╭──────────────────────── Error ─────────────────────────╮ "
|
||||||
"│ │"
|
" │ │ "
|
||||||
"│Unable to access docker daemon @ "/test/host│"
|
" │ Unable to access docker daemon @ "/test/host.sock" │ "
|
||||||
"│ │"
|
" │ │ "
|
||||||
"│ oxker::v0.00.000 closing in 04 seconds │"
|
" │ oxker::v0.00.000 closing in 04 seconds │ "
|
||||||
"│ │"
|
" │ │ "
|
||||||
"╰────────────────────────────────────────────╯"
|
" │ ( q ) quit oxker │ "
|
||||||
|
" │ │ "
|
||||||
|
" ╰────────────────────────────────────────────────────────╯ "
|
||||||
" "
|
" "
|
||||||
|
|||||||
+14
-4
@@ -131,12 +131,12 @@ impl Ui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Draw the the error message ui, for 5 seconds, with a countdown
|
/// Draw the the error message ui, for 5 seconds, with a countdown
|
||||||
fn err_loop(&mut self, host: Option<String>) -> Result<(), AppError> {
|
async fn err_loop(&mut self, host: Option<String>) -> Result<(), AppError> {
|
||||||
let mut seconds = 5;
|
let mut seconds = 5;
|
||||||
let colors = self.app_data.lock().config.app_colors;
|
let colors = self.app_data.lock().config.app_colors;
|
||||||
let keymap = self.app_data.lock().config.keymap.clone();
|
let keymap = self.app_data.lock().config.keymap.clone();
|
||||||
let mut redraw = true;
|
let mut redraw = true;
|
||||||
loop {
|
while self.is_running.load(Ordering::SeqCst) {
|
||||||
if self.now.elapsed() >= std::time::Duration::from_secs(1) {
|
if self.now.elapsed() >= std::time::Duration::from_secs(1) {
|
||||||
seconds -= 1;
|
seconds -= 1;
|
||||||
self.now = Instant::now();
|
self.now = Instant::now();
|
||||||
@@ -163,8 +163,18 @@ impl Ui {
|
|||||||
{
|
{
|
||||||
return Err(AppError::Terminal);
|
return Err(AppError::Terminal);
|
||||||
}
|
}
|
||||||
|
if crossterm::event::poll(POLL_RATE).unwrap_or(false)
|
||||||
|
&& let Ok(event) = event::read()
|
||||||
|
&& let Event::Key(key) = event
|
||||||
|
&& key.kind == event::KeyEventKind::Press
|
||||||
|
{
|
||||||
|
self.input_tx
|
||||||
|
.send(InputMessages::ButtonPress((key.code, key.modifiers)))
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
redraw = false;
|
redraw = false;
|
||||||
std::thread::sleep(POLL_RATE);
|
// std::thread::sleep(POLL_RATE);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -278,7 +288,7 @@ impl Ui {
|
|||||||
.iter()
|
.iter()
|
||||||
.find(|s| matches!(s, Status::DockerConnect(_)))
|
.find(|s| matches!(s, Status::DockerConnect(_)))
|
||||||
{
|
{
|
||||||
self.err_loop(msg.clone())?;
|
self.err_loop(msg.clone()).await?;
|
||||||
} else {
|
} else {
|
||||||
self.gui_loop().await?;
|
self.gui_loop().await?;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user