From ddfcf8b76ffb0fdc7888eaba9c6dcf22ca5603c0 Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Sun, 3 Dec 2023 12:56:38 -0800 Subject: [PATCH] feat(config): add rudimentary config syntax checks This commit attempts to introduce miette to provide users with quick feedback when there may be syntax errors such as trailing commas in their komorebi.json configuration file. The lines and columns reported by serde_json don't actually line up with the visualization of where we want to indicate a syntax error on the miette Report. Some hackery has been done, but this should be improved upon. Notably, this hackery does not accurately reflect the location of a syntax error when the syntax error is a missing comma after a string value. --- Cargo.lock | 129 +++++++++++++++++++++++++++++++++++++++++- komorebic/Cargo.toml | 10 ++-- komorebic/src/main.rs | 39 +++++++++++++ 3 files changed, 173 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0c3f6147e..bd840bab1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,6 +95,15 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "backtrace-ext" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" +dependencies = [ + "backtrace", +] + [[package]] name = "base64" version = "0.21.5" @@ -166,7 +175,7 @@ dependencies = [ "anstyle", "clap_lex", "strsim", - "terminal_size", + "terminal_size 0.3.0", ] [[package]] @@ -744,6 +753,23 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "is_ci" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb" + [[package]] name = "itoa" version = "1.0.9" @@ -837,6 +863,7 @@ dependencies = [ "heck", "komorebi-core", "lazy_static", + "miette", "paste", "powershell_script", "reqwest", @@ -844,6 +871,7 @@ dependencies = [ "serde_json", "serde_yaml", "sysinfo", + "thiserror", "uds_windows", "which", "windows", @@ -928,6 +956,38 @@ dependencies = [ "autocfg", ] +[[package]] +name = "miette" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" +dependencies = [ + "backtrace", + "backtrace-ext", + "is-terminal", + "miette-derive", + "once_cell", + "owo-colors", + "supports-color", + "supports-hyperlinks", + "supports-unicode", + "terminal_size 0.1.17", + "textwrap", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "mime" version = "0.3.17" @@ -1670,6 +1730,12 @@ version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + [[package]] name = "socket2" version = "0.4.10" @@ -1718,6 +1784,34 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "supports-color" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6398cde53adc3c4557306a96ce67b302968513830a77a95b2b17305d9719a89" +dependencies = [ + "is-terminal", + "is_ci", +] + +[[package]] +name = "supports-hyperlinks" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84231692eb0d4d41e4cdd0cabfdd2e6cd9e255e65f80c9aa7c98dd502b4233d" +dependencies = [ + "is-terminal", +] + +[[package]] +name = "supports-unicode" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b6c2cb240ab5dd21ed4906895ee23fe5a48acdbd15a3ce388e7b62a9b66baf7" +dependencies = [ + "is-terminal", +] + [[package]] name = "syn" version = "1.0.109" @@ -1789,6 +1883,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "terminal_size" version = "0.3.0" @@ -1799,6 +1903,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "textwrap" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.50" @@ -2040,6 +2155,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + [[package]] name = "unicode-normalization" version = "0.1.22" @@ -2049,6 +2170,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + [[package]] name = "unsafe-libyaml" version = "0.2.9" diff --git a/komorebic/Cargo.toml b/komorebic/Cargo.toml index 369ef26ad..f346250c4 100644 --- a/komorebic/Cargo.toml +++ b/komorebic/Cargo.toml @@ -15,9 +15,13 @@ derive-ahk = { path = "../derive-ahk" } komorebi-core = { path = "../komorebi-core" } clap = { version = "4", features = ["derive", "wrap_help"] } +color-eyre = { workspace = true } +dirs = { workspace = true } +dunce = { workspace = true } fs-tail = "0.1" heck = "0.4" lazy_static = "1" +miette = { version = "5", features = ["fancy"] } paste = "1" powershell_script = "1.0" reqwest = { version = "0.11", features = ["blocking"] } @@ -25,9 +29,7 @@ serde = { version = "1", features = ["derive"] } serde_json = "1" serde_yaml = "0.9" sysinfo = "0.29" +thiserror = "1" uds_windows = "1" which = "5" -windows = { workspace = true } -color-eyre = { workspace = true } -dirs = { workspace = true } -dunce = { workspace = true } \ No newline at end of file +windows = { workspace = true } \ No newline at end of file diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index 246a2d34a..216f9e786 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -22,6 +22,10 @@ use fs_tail::TailedFile; use heck::ToKebabCase; use komorebi_core::resolve_home_path; use lazy_static::lazy_static; +use miette::NamedSource; +use miette::Report; +use miette::SourceOffset; +use miette::SourceSpan; use paste::paste; use sysinfo::SystemExt; use uds_windows::UnixListener; @@ -82,6 +86,17 @@ trait AhkFunction { fn generate_ahk_function() -> String; } +#[derive(thiserror::Error, Debug, miette::Diagnostic)] +#[error("{message}")] +#[diagnostic(code(komorebi::configuration), help("try fixing this syntax error"))] +struct ConfigurationError { + message: String, + #[source_code] + src: NamedSource, + #[label("This bit here")] + bad_bit: SourceSpan, +} + #[derive(Copy, Clone, ValueEnum)] enum BooleanState { Enable, @@ -1261,6 +1276,30 @@ fn main() -> Result<()> { .join("whkdrc"); if static_config.exists() { + let config_source = std::fs::read_to_string(&static_config)?; + let lines: Vec<_> = config_source.lines().collect(); + let parsed_config = serde_json::from_str::(&config_source); + if let Err(serde_error) = parsed_config { + let line = lines[serde_error.line() - 2]; + + let offset = SourceOffset::from_location( + config_source.clone(), + serde_error.line() - 1, + line.len(), + ); + + let error_string = serde_error.to_string(); + let msgs: Vec<_> = error_string.split(" at ").collect(); + + let diagnostic = ConfigurationError { + message: msgs[0].to_string(), + src: NamedSource::new("komorebi.json", config_source.clone()), + bad_bit: SourceSpan::new(offset, 2.into()), + }; + + println!("{:?}", Report::new(diagnostic)); + } + println!("Found komorebi.json; this file can be passed to the start command with the --config flag\n"); if config_whkd.exists() { println!("Found ~/.config/whkdrc; key bindings will be loaded from here when whkd is started, and you can start it automatically using the --whkd flag\n");