From ac8ba06f4c8cec6ca3c88467b563f571fc4751b6 Mon Sep 17 00:00:00 2001 From: Daniel Flanagan Date: Wed, 17 Apr 2024 17:02:03 -0500 Subject: [PATCH] WIP signal handling --- Cargo.lock | 14 ++++++++++++++ Cargo.toml | 2 ++ src/cli/gitlab.rs | 2 +- src/cli/jira.rs | 15 ++++++++++++--- src/main.rs | 4 +--- src/task.rs | 4 ++-- src/tui.rs | 36 ++++++++++++++++++------------------ 7 files changed, 50 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d4d0e4..a90346a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2242,6 +2242,18 @@ dependencies = [ "libc", ] +[[package]] +name = "signal-hook-tokio" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213241f76fb1e37e27de3b6aa1b068a2c333233b59cca6634f634b80a27ecf1e" +dependencies = [ + "futures-core", + "libc", + "signal-hook", + "tokio", +] + [[package]] name = "slab" version = "0.4.9" @@ -2423,6 +2435,8 @@ dependencies = [ "reqwest-tracing", "serde", "serde_json", + "signal-hook", + "signal-hook-tokio", "sled", "tokio", "tracing", diff --git a/Cargo.toml b/Cargo.toml index 73998b6..dc9bd1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,8 @@ reqwest-retry = "0.4.0" reqwest-tracing = "0.4.8" serde = { version = "1.0.197", features = ["derive"] } serde_json = "1.0.114" +signal-hook = "0.3.17" +signal-hook-tokio = { version = "0.3.1", features = ["futures-v0_3"] } sled = "0.34.7" tokio = { version = "1.36.0", features = ["full"] } tracing = "0.1.40" diff --git a/src/cli/gitlab.rs b/src/cli/gitlab.rs index 081a50c..16aab65 100644 --- a/src/cli/gitlab.rs +++ b/src/cli/gitlab.rs @@ -18,7 +18,7 @@ pub struct MeArgs {} impl MeArgs { pub async fn me(&self, tasks: SharedTasks) -> Result<()> { - println!("{:?}", tasks.gitlab()?.me().await?); + println!("{:#?}", tasks.gitlab()?.me().await?); Ok(()) } } diff --git a/src/cli/jira.rs b/src/cli/jira.rs index 4ccb8cd..b0fb01b 100644 --- a/src/cli/jira.rs +++ b/src/cli/jira.rs @@ -3,12 +3,14 @@ use crate::cli::prelude::*; #[derive(Subcommand)] pub enum Command { Issue(IssueArgs), + Me(MeArgs), } impl Command { pub async fn exec(&self, tasks: SharedTasks) -> Result<()> { match self { Command::Issue(args) => args.issue(tasks).await, + Command::Me(args) => args.me(tasks).await, } } } @@ -18,11 +20,18 @@ pub struct IssueArgs { #[arg(short, long)] pub key: String, } - impl IssueArgs { pub async fn issue(&self, tasks: SharedTasks) -> Result<()> { - let issue = tasks.jira()?.issue(&self.key).await?; - println!("{issue:?}"); + println!("{:#?}", tasks.jira()?.issue(&self.key).await?); + Ok(()) + } +} + +#[derive(Args)] +pub struct MeArgs {} +impl MeArgs { + pub async fn me(&self, tasks: SharedTasks) -> Result<()> { + println!("{:#?}", tasks.jira()?.me().await?); Ok(()) } } diff --git a/src/main.rs b/src/main.rs index c094ca4..cff9a0d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,8 +12,8 @@ mod task; mod tasks; mod tui; +use crate::cli::{Cli, Commands}; use crate::prelude::*; -use cli::{Cli, Commands}; #[tokio::main] async fn main() -> Result<()> { @@ -24,8 +24,6 @@ async fn main() -> Result<()> { // https://docs.rs/tracing-appender/latest/tracing_appender/non_blocking/struct.WorkerGuard.html let _log_guard = observe::setup_logging(cli.logs_directory, cli.tracing_env_filter)?; - info!("Initializing taskr..."); - println!("Initializing taskr..."); let tasks = Arc::new(crate::tasks::Tasks::try_new(cli.data_directory)?); let result = match cli.command { diff --git a/src/task.rs b/src/task.rs index ef6af1e..d274a59 100644 --- a/src/task.rs +++ b/src/task.rs @@ -63,7 +63,7 @@ impl Display for Task { description, jira_key, merge_requests, - jira_priority, + jira_priority: _, local_priority, status, tags, @@ -79,7 +79,7 @@ impl Display for Task { "".into() }; f.write_fmt(format_args!( - "{jira_key} {status:>10} {jira_priority} {description} [{tags_text}]{mr_text}", + "{jira_key} {status:>10} {local_priority} {description} [{tags_text}]{mr_text}", )) } } diff --git a/src/tui.rs b/src/tui.rs index b03238e..d561ced 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -1,16 +1,19 @@ use crate::prelude::*; -use crate::task; use crossterm::{ - event::{self, KeyCode, KeyEventKind}, + event::{self, KeyCode, KeyEventKind, KeyModifiers}, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, ExecutableCommand, }; +use futures::stream::StreamExt; use ratatui::{ prelude::{CrosstermBackend, Stylize, Terminal}, widgets::Paragraph, }; +use signal_hook::consts::*; +use signal_hook_tokio::Signals; use std::io::stdout; +use tokio::task::JoinHandle; pub struct Tui { tasks: SharedTasks, @@ -22,22 +25,6 @@ impl Tui { } pub async fn run(&self) -> Result<()> { - // print!("{ANSI_CLEAR}"); - // let gitlab_user = tasks.gitlab.me().await?; - // info!("{gitlab_user:#?}"); - // let jira_user = tasks.jira.me().await?; - // tasks.purge_all()?; - let tasks = self.tasks.all()?; - - if tasks.len() < 1 { - info!("{:?}", self.tasks.sync().await?); - } - let mut vtasks: Vec<&task::Task> = tasks.values().collect(); - vtasks.sort_unstable(); - for t in &vtasks { - info!("{}", t); - } - info!("Number of tasks: {}", vtasks.len()); self.tui().await } @@ -46,6 +33,8 @@ impl Tui { enable_raw_mode()?; let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; terminal.clear()?; + let mut signals = Signals::new(&[SIGHUP, SIGTERM, SIGINT, SIGQUIT])?; + let handle = signals.handle(); loop { terminal.draw(|frame| { @@ -57,14 +46,25 @@ impl Tui { })?; if event::poll(std::time::Duration::from_millis(10))? { if let event::Event::Key(key) = event::read()? { + if key.kind == KeyEventKind::Press + && key.code == KeyCode::Char('c') + && key.modifiers == KeyModifiers::CONTROL + { + break; + } if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') { break; } } } + println!("Waiting for signal..."); + if signals.next().await.is_some() { + break; + } } // TODO main loop + handle.close(); stdout().execute(LeaveAlternateScreen)?; disable_raw_mode()?; Ok(())