WIP signal handling
This commit is contained in:
parent
424520b2c1
commit
ac8ba06f4c
7 changed files with 50 additions and 27 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -2242,6 +2242,18 @@ dependencies = [
|
||||||
"libc",
|
"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]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
|
@ -2423,6 +2435,8 @@ dependencies = [
|
||||||
"reqwest-tracing",
|
"reqwest-tracing",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"signal-hook",
|
||||||
|
"signal-hook-tokio",
|
||||||
"sled",
|
"sled",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
|
|
@ -22,6 +22,8 @@ reqwest-retry = "0.4.0"
|
||||||
reqwest-tracing = "0.4.8"
|
reqwest-tracing = "0.4.8"
|
||||||
serde = { version = "1.0.197", features = ["derive"] }
|
serde = { version = "1.0.197", features = ["derive"] }
|
||||||
serde_json = "1.0.114"
|
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"
|
sled = "0.34.7"
|
||||||
tokio = { version = "1.36.0", features = ["full"] }
|
tokio = { version = "1.36.0", features = ["full"] }
|
||||||
tracing = "0.1.40"
|
tracing = "0.1.40"
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub struct MeArgs {}
|
||||||
|
|
||||||
impl MeArgs {
|
impl MeArgs {
|
||||||
pub async fn me(&self, tasks: SharedTasks) -> Result<()> {
|
pub async fn me(&self, tasks: SharedTasks) -> Result<()> {
|
||||||
println!("{:?}", tasks.gitlab()?.me().await?);
|
println!("{:#?}", tasks.gitlab()?.me().await?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,14 @@ use crate::cli::prelude::*;
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
Issue(IssueArgs),
|
Issue(IssueArgs),
|
||||||
|
Me(MeArgs),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
pub async fn exec(&self, tasks: SharedTasks) -> Result<()> {
|
pub async fn exec(&self, tasks: SharedTasks) -> Result<()> {
|
||||||
match self {
|
match self {
|
||||||
Command::Issue(args) => args.issue(tasks).await,
|
Command::Issue(args) => args.issue(tasks).await,
|
||||||
|
Command::Me(args) => args.me(tasks).await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,11 +20,18 @@ pub struct IssueArgs {
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
pub key: String,
|
pub key: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IssueArgs {
|
impl IssueArgs {
|
||||||
pub async fn issue(&self, tasks: SharedTasks) -> Result<()> {
|
pub async fn issue(&self, tasks: SharedTasks) -> Result<()> {
|
||||||
let issue = tasks.jira()?.issue(&self.key).await?;
|
println!("{:#?}", tasks.jira()?.issue(&self.key).await?);
|
||||||
println!("{issue:?}");
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Args)]
|
||||||
|
pub struct MeArgs {}
|
||||||
|
impl MeArgs {
|
||||||
|
pub async fn me(&self, tasks: SharedTasks) -> Result<()> {
|
||||||
|
println!("{:#?}", tasks.jira()?.me().await?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ mod task;
|
||||||
mod tasks;
|
mod tasks;
|
||||||
mod tui;
|
mod tui;
|
||||||
|
|
||||||
|
use crate::cli::{Cli, Commands};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use cli::{Cli, Commands};
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
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
|
// 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)?;
|
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 tasks = Arc::new(crate::tasks::Tasks::try_new(cli.data_directory)?);
|
||||||
|
|
||||||
let result = match cli.command {
|
let result = match cli.command {
|
||||||
|
|
|
@ -63,7 +63,7 @@ impl Display for Task {
|
||||||
description,
|
description,
|
||||||
jira_key,
|
jira_key,
|
||||||
merge_requests,
|
merge_requests,
|
||||||
jira_priority,
|
jira_priority: _,
|
||||||
local_priority,
|
local_priority,
|
||||||
status,
|
status,
|
||||||
tags,
|
tags,
|
||||||
|
@ -79,7 +79,7 @@ impl Display for Task {
|
||||||
"".into()
|
"".into()
|
||||||
};
|
};
|
||||||
f.write_fmt(format_args!(
|
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}",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
36
src/tui.rs
36
src/tui.rs
|
@ -1,16 +1,19 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::task;
|
|
||||||
|
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
event::{self, KeyCode, KeyEventKind},
|
event::{self, KeyCode, KeyEventKind, KeyModifiers},
|
||||||
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
||||||
ExecutableCommand,
|
ExecutableCommand,
|
||||||
};
|
};
|
||||||
|
use futures::stream::StreamExt;
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
prelude::{CrosstermBackend, Stylize, Terminal},
|
prelude::{CrosstermBackend, Stylize, Terminal},
|
||||||
widgets::Paragraph,
|
widgets::Paragraph,
|
||||||
};
|
};
|
||||||
|
use signal_hook::consts::*;
|
||||||
|
use signal_hook_tokio::Signals;
|
||||||
use std::io::stdout;
|
use std::io::stdout;
|
||||||
|
use tokio::task::JoinHandle;
|
||||||
|
|
||||||
pub struct Tui {
|
pub struct Tui {
|
||||||
tasks: SharedTasks,
|
tasks: SharedTasks,
|
||||||
|
@ -22,22 +25,6 @@ impl Tui {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run(&self) -> Result<()> {
|
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
|
self.tui().await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +33,8 @@ impl Tui {
|
||||||
enable_raw_mode()?;
|
enable_raw_mode()?;
|
||||||
let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
|
let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
|
||||||
terminal.clear()?;
|
terminal.clear()?;
|
||||||
|
let mut signals = Signals::new(&[SIGHUP, SIGTERM, SIGINT, SIGQUIT])?;
|
||||||
|
let handle = signals.handle();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
terminal.draw(|frame| {
|
terminal.draw(|frame| {
|
||||||
|
@ -57,14 +46,25 @@ impl Tui {
|
||||||
})?;
|
})?;
|
||||||
if event::poll(std::time::Duration::from_millis(10))? {
|
if event::poll(std::time::Duration::from_millis(10))? {
|
||||||
if let event::Event::Key(key) = event::read()? {
|
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') {
|
if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
println!("Waiting for signal...");
|
||||||
|
if signals.next().await.is_some() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// TODO main loop
|
// TODO main loop
|
||||||
|
|
||||||
|
handle.close();
|
||||||
stdout().execute(LeaveAlternateScreen)?;
|
stdout().execute(LeaveAlternateScreen)?;
|
||||||
disable_raw_mode()?;
|
disable_raw_mode()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in a new issue