feat: add logging for tui
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
parent
5327aff217
commit
1885a200c4
241
Cargo.lock
generated
241
Cargo.lock
generated
@ -15,6 +15,15 @@ dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.16"
|
||||
@ -211,7 +220,7 @@ checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-automata 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -237,6 +246,21 @@ version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
|
||||
|
||||
[[package]]
|
||||
name = "cassowary"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
|
||||
|
||||
[[package]]
|
||||
name = "castaway"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc"
|
||||
dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.79"
|
||||
@ -297,6 +321,19 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||
|
||||
[[package]]
|
||||
name = "compact_str"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f"
|
||||
dependencies = [
|
||||
"castaway",
|
||||
"cfg-if",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console"
|
||||
version = "0.15.8"
|
||||
@ -363,6 +400,32 @@ version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"crossterm_winapi",
|
||||
"futures-core",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm_winapi"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
@ -405,6 +468,15 @@ dependencies = [
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "directories"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "5.0.1"
|
||||
@ -804,6 +876,7 @@ dependencies = [
|
||||
"dirs",
|
||||
"dotenv",
|
||||
"hyperlog-core",
|
||||
"hyperlog-tui",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"similar-asserts",
|
||||
@ -838,6 +911,20 @@ dependencies = [
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyperlog-tui"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"crossterm",
|
||||
"directories",
|
||||
"hyperlog-core",
|
||||
"ratatui",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.4.0"
|
||||
@ -858,6 +945,12 @@ dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indoc"
|
||||
version = "2.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.11"
|
||||
@ -966,6 +1059,24 @@ version = "0.4.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
|
||||
|
||||
[[package]]
|
||||
name = "lru"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||
dependencies = [
|
||||
"regex-automata 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchit"
|
||||
version = "0.7.0"
|
||||
@ -1007,6 +1118,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
@ -1281,6 +1393,26 @@ dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ratatui"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a564a852040e82671dc50a37d88f3aa83bbc690dfc6844cfe7a2591620206a80"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"cassowary",
|
||||
"compact_str",
|
||||
"crossterm",
|
||||
"indoc",
|
||||
"itertools",
|
||||
"lru",
|
||||
"paste",
|
||||
"stability",
|
||||
"strum",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.3.5"
|
||||
@ -1301,11 +1433,49 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata 0.3.7",
|
||||
"regex-syntax 0.7.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||
dependencies = [
|
||||
"regex-syntax 0.6.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax 0.7.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
@ -1509,6 +1679,27 @@ dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-mio"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.1"
|
||||
@ -1827,6 +2018,22 @@ dependencies = [
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stability"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ff9eaf853dec4c8802325d8b6d3dffa86cc707fd7a1a4cdbf416e13b061787a"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "stringprep"
|
||||
version = "0.1.4"
|
||||
@ -1844,6 +2051,28 @@ version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29"
|
||||
dependencies = [
|
||||
"strum_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.5.0"
|
||||
@ -2115,10 +2344,14 @@ version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"nu-ansi-term",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
@ -2156,6 +2389,12 @@ version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
|
||||
|
||||
[[package]]
|
||||
name = "unicode_categories"
|
||||
version = "0.1.1"
|
||||
|
@ -3,12 +3,13 @@ members = ["crates/*"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.dependencies]
|
||||
hyperlog-core = {path = "crates/hyperlog-core"}
|
||||
hyperlog-core = { path = "crates/hyperlog-core" }
|
||||
hyperlog-tui = { path = "crates/hyperlog-tui" }
|
||||
|
||||
anyhow = { version = "1" }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tracing = { version = "0.1", features = ["log"] }
|
||||
tracing-subscriber = { version = "0.3.18" }
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||
clap = { version = "4", features = ["derive", "env"] }
|
||||
dotenv = { version = "0.15" }
|
||||
axum = { version = "0.7" }
|
||||
|
@ -13,7 +13,13 @@ dotenv.workspace = true
|
||||
axum.workspace = true
|
||||
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
sqlx = { version = "0.7.3", features = ["runtime-tokio", "tls-rustls", "postgres", "uuid", "time"] }
|
||||
sqlx = { version = "0.7.3", features = [
|
||||
"runtime-tokio",
|
||||
"tls-rustls",
|
||||
"postgres",
|
||||
"uuid",
|
||||
"time",
|
||||
] }
|
||||
uuid = { version = "1.7.0", features = ["v4"] }
|
||||
tower-http = { version = "0.5.2", features = ["cors", "trace"] }
|
||||
serde_json = "1.0.116"
|
||||
|
@ -14,9 +14,18 @@ impl Querier {
|
||||
root: &str,
|
||||
path: impl IntoIterator<Item = impl Into<String>>,
|
||||
) -> Option<GraphItem> {
|
||||
let path = path.into_iter().map(|i| i.into()).collect::<Vec<String>>();
|
||||
let path = path
|
||||
.into_iter()
|
||||
.map(|i| i.into())
|
||||
.filter(|i| !i.is_empty())
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
tracing::debug!("quering: {}, len: ({}))", path.join("."), path.len());
|
||||
tracing::debug!(
|
||||
"quering: root:({}), path:({}), len: ({}))",
|
||||
root,
|
||||
path.join("."),
|
||||
path.len()
|
||||
);
|
||||
|
||||
self.engine
|
||||
.get(root, &path.iter().map(|i| i.as_str()).collect::<Vec<_>>())
|
||||
|
@ -10,6 +10,7 @@ pub struct LockFile(PathBuf);
|
||||
|
||||
impl Drop for LockFile {
|
||||
fn drop(&mut self) {
|
||||
tracing::debug!("removing lockfile");
|
||||
std::fs::remove_file(&self.0).expect("to be able to delete lockfile")
|
||||
}
|
||||
}
|
||||
@ -76,6 +77,14 @@ impl Storage {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn clear_lock_file(self) {
|
||||
let mut lock_file = self.lock_file.lock().unwrap();
|
||||
|
||||
if lock_file.is_some() {
|
||||
*lock_file = None;
|
||||
}
|
||||
}
|
||||
|
||||
fn state(&self) -> anyhow::Result<PathBuf> {
|
||||
self.cache().map(|c| c.join("graph.json"))
|
||||
}
|
||||
|
16
crates/hyperlog-tui/Cargo.toml
Normal file
16
crates/hyperlog-tui/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "hyperlog-tui"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
hyperlog-core.workspace = true
|
||||
|
||||
anyhow.workspace = true
|
||||
tokio.workspace = true
|
||||
tracing.workspace = true
|
||||
tracing-subscriber.workspace = true
|
||||
|
||||
ratatui = "0.26.2"
|
||||
crossterm = { version = "0.27.0", features = ["event-stream"] }
|
||||
directories = "5.0.1"
|
138
crates/hyperlog-tui/src/lib.rs
Normal file
138
crates/hyperlog-tui/src/lib.rs
Normal file
@ -0,0 +1,138 @@
|
||||
use std::{
|
||||
io::{self, Stdout},
|
||||
ops::{Deref, DerefMut},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use crossterm::{
|
||||
event::{self, Event, KeyCode},
|
||||
execute,
|
||||
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
||||
};
|
||||
use hyperlog_core::state::State;
|
||||
use ratatui::{backend::CrosstermBackend, prelude::*, widgets::*, Frame, Terminal};
|
||||
|
||||
struct TerminalInstance {
|
||||
terminal: Terminal<CrosstermBackend<Stdout>>,
|
||||
}
|
||||
|
||||
impl TerminalInstance {
|
||||
fn new() -> Result<Self> {
|
||||
Ok(Self {
|
||||
terminal: setup_terminal().context("setup failed")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for TerminalInstance {
|
||||
type Target = Terminal<CrosstermBackend<Stdout>>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.terminal
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for TerminalInstance {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.terminal
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TerminalInstance {
|
||||
fn drop(&mut self) {
|
||||
if let Err(e) = restore_terminal(&mut self.terminal).context("restore terminal failed") {
|
||||
tracing::error!("failed to restore terminal: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn execute(state: &State) -> Result<()> {
|
||||
tracing::debug!("starting hyperlog tui");
|
||||
|
||||
logging::initialize_panic_handler()?;
|
||||
logging::initialize_logging()?;
|
||||
|
||||
let mut terminal = TerminalInstance::new()?;
|
||||
run(&mut terminal, state).context("app loop failed")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run(terminal: &mut Terminal<CrosstermBackend<Stdout>>, state: &State) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(|f| crate::render_app(f, &state))?;
|
||||
if should_quit()? {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn render_app(frame: &mut Frame, state: &State) {
|
||||
let chunks =
|
||||
Layout::vertical(vec![Constraint::Length(2), Constraint::Min(0)]).split(frame.size());
|
||||
|
||||
let heading = Paragraph::new(text::Line::from(
|
||||
Span::styled("hyperlog", Style::default()).fg(Color::Green),
|
||||
));
|
||||
let block_heading = Block::default().borders(Borders::BOTTOM);
|
||||
|
||||
frame.render_widget(heading.block(block_heading), chunks[0]);
|
||||
|
||||
let Rect { width, height, .. } = chunks[1];
|
||||
|
||||
let height = height as usize;
|
||||
let width = width as usize;
|
||||
|
||||
let mut lines = Vec::new();
|
||||
for y in 0..height {
|
||||
if !y % 2 == 0 {
|
||||
lines.push(text::Line::default());
|
||||
} else {
|
||||
lines.push(text::Line::raw(" ~ ".repeat(width / 3)));
|
||||
}
|
||||
}
|
||||
let background = Paragraph::new(lines);
|
||||
|
||||
let bg_block = Block::default()
|
||||
.fg(Color::DarkGray)
|
||||
.bold()
|
||||
.padding(Padding {
|
||||
left: 4,
|
||||
right: 4,
|
||||
top: 2,
|
||||
bottom: 2,
|
||||
});
|
||||
|
||||
if let Some(graph) = state.querier.get("something", Vec::<String>::new()) {}
|
||||
|
||||
frame.render_widget(background.block(bg_block), chunks[1]);
|
||||
}
|
||||
|
||||
fn should_quit() -> Result<bool> {
|
||||
if event::poll(Duration::from_millis(250)).context("event poll failed")? {
|
||||
if let Event::Key(key) = event::read().context("event read failed")? {
|
||||
return Ok(KeyCode::Char('q') == key.code);
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn setup_terminal() -> Result<Terminal<CrosstermBackend<Stdout>>> {
|
||||
let mut stdout = io::stdout();
|
||||
enable_raw_mode().context("failed to enable raw mode")?;
|
||||
execute!(stdout, EnterAlternateScreen).context("unable to enter alternate screen")?;
|
||||
Terminal::new(CrosstermBackend::new(stdout)).context("creating terminal failed")
|
||||
}
|
||||
|
||||
/// Restore the terminal. This is where you disable raw mode, leave the alternate screen, and show
|
||||
/// the cursor.
|
||||
fn restore_terminal(terminal: &mut Terminal<CrosstermBackend<Stdout>>) -> Result<()> {
|
||||
disable_raw_mode().context("failed to disable raw mode")?;
|
||||
execute!(terminal.backend_mut(), LeaveAlternateScreen)
|
||||
.context("unable to switch to main screen")?;
|
||||
terminal.show_cursor().context("unable to show cursor")
|
||||
}
|
||||
|
||||
mod logging;
|
77
crates/hyperlog-tui/src/logging.rs
Normal file
77
crates/hyperlog-tui/src/logging.rs
Normal file
@ -0,0 +1,77 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use directories::ProjectDirs;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, Layer};
|
||||
|
||||
pub fn initialize_logging() -> anyhow::Result<()> {
|
||||
let project = match ProjectDirs::from("io", "kjuulh", env!("CARGO_PKG_NAME")) {
|
||||
Some(p) => p.data_local_dir().to_path_buf(),
|
||||
None => PathBuf::from(".").join(".data"),
|
||||
};
|
||||
|
||||
std::fs::create_dir_all(&project)?;
|
||||
let log_path = project.join("hyperlog.log");
|
||||
|
||||
//println!("logging to: {}", log_path.display());
|
||||
|
||||
let log_file = std::fs::File::create(log_path)?;
|
||||
std::env::set_var(
|
||||
"RUST_LOG",
|
||||
std::env::var("RUST_LOG")
|
||||
.or_else(|_| std::env::var("HYPERLOG_LOG_LEVEL"))
|
||||
.unwrap_or_else(|_| format!("{}=info", env!("CARGO_CRATE_NAME"))),
|
||||
);
|
||||
|
||||
let file_subscriber = tracing_subscriber::fmt::layer()
|
||||
.with_file(true)
|
||||
.with_line_number(true)
|
||||
.with_writer(log_file)
|
||||
.with_target(false)
|
||||
.with_ansi(false)
|
||||
.with_filter(tracing_subscriber::filter::EnvFilter::from_default_env());
|
||||
tracing_subscriber::registry()
|
||||
.with(file_subscriber)
|
||||
//.with(ErrorLayer::default())
|
||||
.init();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn initialize_panic_handler() -> anyhow::Result<()> {
|
||||
std::panic::set_hook(Box::new(move |panic_info| {
|
||||
// if let Ok(mut t) = crate::tui::Tui::new() {
|
||||
// if let Err(r) = t.exit() {
|
||||
// tracing::error!("Unable to exit Terminal: {:?}", r);
|
||||
// }
|
||||
// }
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
use human_panic::{handle_dump, print_msg, Metadata};
|
||||
let meta = Metadata {
|
||||
version: env!("CARGO_PKG_VERSION").into(),
|
||||
name: env!("CARGO_PKG_NAME").into(),
|
||||
authors: env!("CARGO_PKG_AUTHORS").replace(':', ", ").into(),
|
||||
homepage: env!("CARGO_PKG_HOMEPAGE").into(),
|
||||
};
|
||||
|
||||
let file_path = handle_dump(&meta, panic_info);
|
||||
// prints human-panic message
|
||||
print_msg(file_path, &meta)
|
||||
.expect("human-panic: printing error message to console failed");
|
||||
//eprintln!("{}", panic_hook.panic_report(panic_info)); // prints color-eyre stack trace to stderr
|
||||
}
|
||||
let msg = format!("{}", panic_info);
|
||||
tracing::error!("Error: {}", msg);
|
||||
|
||||
// #[cfg(debug_assertions)]
|
||||
// {
|
||||
// // Better Panic stacktrace that is only enabled when debugging.
|
||||
// better_panic::Settings::auto()
|
||||
// .most_recent_first(false)
|
||||
// .lineno_suffix(true)
|
||||
// .verbosity(better_panic::Verbosity::Full)
|
||||
// .create_panic_handler()(panic_info);
|
||||
// }
|
||||
}));
|
||||
Ok(())
|
||||
}
|
@ -5,6 +5,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
hyperlog-core.workspace = true
|
||||
hyperlog-tui.workspace = true
|
||||
|
||||
anyhow.workspace = true
|
||||
tokio.workspace = true
|
||||
@ -15,7 +16,13 @@ dotenv.workspace = true
|
||||
axum.workspace = true
|
||||
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
sqlx = { version = "0.7.3", features = ["runtime-tokio", "tls-rustls", "postgres", "uuid", "time"] }
|
||||
sqlx = { version = "0.7.3", features = [
|
||||
"runtime-tokio",
|
||||
"tls-rustls",
|
||||
"postgres",
|
||||
"uuid",
|
||||
"time",
|
||||
] }
|
||||
uuid = { version = "1.7.0", features = ["v4"] }
|
||||
tower-http = { version = "0.5.2", features = ["cors", "trace"] }
|
||||
serde_json = "1.0.116"
|
||||
|
77
crates/hyperlog/screens/outer-focus.md
Normal file
77
crates/hyperlog/screens/outer-focus.md
Normal file
@ -0,0 +1,77 @@
|
||||
hyperlog
|
||||
--------
|
||||
kjuulh:
|
||||
- (summary: items(10)) -> projects/**
|
||||
- [ ] wash the dishes
|
||||
|
||||
...
|
||||
|
||||
- project A
|
||||
|
||||
- sub project B (items: 10)
|
||||
|
||||
...
|
||||
|
||||
- sub project C (items: 0)
|
||||
|
||||
- project B
|
||||
|
||||
- sub project A
|
||||
|
||||
- project C
|
||||
|
||||
- sub project A
|
||||
|
||||
- project D
|
||||
|
||||
- sub project A
|
||||
|
||||
---
|
||||
|
||||
Traversing into the nested section
|
||||
|
||||
hyperlog
|
||||
--------
|
||||
kjuulh:
|
||||
- (summary: items(10)) -> projects/**
|
||||
- **project A**
|
||||
|
||||
- sub project B (items: 10)
|
||||
- [ ] Something
|
||||
- [ ] Something B (High priority, due wednesday)
|
||||
- [ ] Something C
|
||||
|
||||
...
|
||||
|
||||
- sub project C (items: 0)
|
||||
|
||||
- [ ] Something
|
||||
- [ ] Something B (High priority, due wednesday)
|
||||
- [ ] Something C
|
||||
- [ ] Something D
|
||||
- [ ] Something E
|
||||
|
||||
...
|
||||
|
||||
- project B
|
||||
|
||||
|
||||
---
|
||||
|
||||
Traversing into the final section
|
||||
|
||||
hyperlog
|
||||
--------
|
||||
- **project A**
|
||||
|
||||
- **sub project B (items: 10)**
|
||||
|
||||
- [ ] Something
|
||||
- [ ] Something B (High priority, due wednesday)
|
||||
- [ ] Something C
|
||||
- [ ] Something E
|
||||
- [ ] Something D
|
||||
|
||||
- sub project C (items: 0)
|
||||
|
||||
...
|
@ -6,7 +6,7 @@ use hyperlog_core::{commander, state};
|
||||
use crate::server::serve;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(author, version, about, long_about = None, subcommand_required = true)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Command {
|
||||
#[command(subcommand)]
|
||||
command: Option<Commands>,
|
||||
@ -27,6 +27,8 @@ enum Commands {
|
||||
commands: QueryCommands,
|
||||
},
|
||||
Info {},
|
||||
|
||||
ClearLock {},
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
@ -59,6 +61,10 @@ enum QueryCommands {
|
||||
pub async fn execute() -> anyhow::Result<()> {
|
||||
let cli = Command::parse();
|
||||
|
||||
if cli.command.is_some() {
|
||||
tracing_subscriber::fmt::init();
|
||||
}
|
||||
|
||||
let state = state::State::new()?;
|
||||
|
||||
match cli.command {
|
||||
@ -100,8 +106,13 @@ pub async fn execute() -> anyhow::Result<()> {
|
||||
Some(Commands::Info {}) => {
|
||||
println!("graph stored at: {}", state.storage.info()?)
|
||||
}
|
||||
|
||||
None => {}
|
||||
Some(Commands::ClearLock {}) => {
|
||||
state.storage.clear_lock_file();
|
||||
println!("cleared lock file");
|
||||
}
|
||||
None => {
|
||||
hyperlog_tui::execute(&state).await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -5,7 +5,6 @@ pub(crate) mod state;
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
dotenv::dotenv().ok();
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
cli::execute().await?;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user