From d44041040d755306c39d6de8da5b42d7ded6808c Mon Sep 17 00:00:00 2001 From: fxqnlr Date: Wed, 25 Sep 2024 15:13:34 +0200 Subject: added notifications and improved stuff --- Cargo.lock | 958 ++++++++++++++++++++++++++++++++++++++++++++++++-------- Cargo.toml | 38 +-- assets/icon.png | Bin 0 -> 34190 bytes src/backup.rs | 37 ++- src/cli.rs | 7 +- src/config.rs | 28 +- src/error.rs | 17 + src/main.rs | 47 ++- src/packages.rs | 13 +- src/pathinfo.rs | 110 +++---- 10 files changed, 992 insertions(+), 263 deletions(-) create mode 100644 assets/icon.png diff --git a/Cargo.lock b/Cargo.lock index fd46c42..fc3874e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,21 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "aho-corasick" version = "1.1.3" @@ -80,10 +65,10 @@ name = "arbs" version = "0.1.0" dependencies = [ "clap", - "color-eyre", "config", "dirs", "gethostname", + "notify-rust", "serde", "serde_json", "thiserror", @@ -95,10 +80,107 @@ dependencies = [ ] [[package]] -name = "async-trait" -version = "0.1.82" +name = "async-broadcast" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-fs" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" +dependencies = [ + "async-lock", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-io" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" +dependencies = [ + "async-lock", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" +dependencies = [ + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix", + "tracing", +] + +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", @@ -106,20 +188,52 @@ dependencies = [ ] [[package]] -name = "backtrace" -version = "0.3.71" +name = "async-signal" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" dependencies = [ - "addr2line", - "cc", + "async-io", + "async-lock", + "atomic-waker", "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + [[package]] name = "base64" version = "0.21.7" @@ -135,6 +249,12 @@ dependencies = [ "serde", ] +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + [[package]] name = "block-buffer" version = "0.10.4" @@ -144,11 +264,30 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "cc" -version = "1.1.16" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9d013ecb737093c0e86b151a7b837993cf9ec6c502946cfb44bedc392421e0b" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" dependencies = [ "shlex", ] @@ -159,11 +298,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "clap" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" +checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" dependencies = [ "clap_builder", "clap_derive", @@ -171,9 +316,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" +checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" dependencies = [ "anstream", "anstyle", @@ -183,9 +328,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", @@ -200,38 +345,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] -name = "color-eyre" -version = "0.6.3" +name = "colorchoice" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" -dependencies = [ - "backtrace", - "color-spantrace", - "eyre", - "indenter", - "once_cell", - "owo-colors", - "tracing-error", -] +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] -name = "color-spantrace" -version = "0.2.1" +name = "concurrent-queue" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ - "once_cell", - "owo-colors", - "tracing-core", - "tracing-error", + "crossbeam-utils", ] -[[package]] -name = "colorchoice" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" - [[package]] name = "config" version = "0.14.0" @@ -249,6 +376,7 @@ dependencies = [ "serde", "serde_json", "toml", + "yaml-rust", ] [[package]] @@ -282,9 +410,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -348,6 +476,16 @@ dependencies = [ "dirs-sys", ] +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + [[package]] name = "dirs-sys" version = "0.4.1" @@ -360,6 +498,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dlv-list" version = "0.5.2" @@ -369,6 +518,33 @@ dependencies = [ "const-random", ] +[[package]] +name = "endi" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" + +[[package]] +name = "enumflags2" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -386,13 +562,83 @@ dependencies = [ ] [[package]] -name = "eyre" -version = "0.6.12" +name = "event-listener" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ - "indenter", - "once_cell", + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "fastrand" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", ] [[package]] @@ -426,12 +672,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - [[package]] name = "hashbrown" version = "0.13.2" @@ -451,10 +691,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] -name = "indenter" -version = "0.3.3" +name = "hermit-abi" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "indexmap" @@ -497,9 +743,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.158" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libredox" @@ -511,6 +757,12 @@ dependencies = [ "libc", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -523,6 +775,28 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "mac-notification-sys" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce8f34f3717aa37177e723df6c1fc5fb02b2a1087374ea3fe0ea42316dc8f91" +dependencies = [ + "cc", + "dirs-next", + "objc-foundation", + "objc_id", + "time", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + [[package]] name = "matchers" version = "0.1.0" @@ -538,6 +812,15 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -545,12 +828,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] -name = "miniz_oxide" -version = "0.7.4" +name = "nix" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "adler", + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", + "memoffset", ] [[package]] @@ -563,6 +850,19 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "notify-rust" +version = "4.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5134a72dc570b178bff81b01e81ab14a6fcc015391ed4b3b14853090658cd3a3" +dependencies = [ + "log", + "mac-notification-sys", + "serde", + "tauri-winrt-notification", + "zbus", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -580,12 +880,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] -name = "object" -version = "0.32.2" +name = "objc" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" dependencies = [ - "memchr", + "malloc_buf", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", ] [[package]] @@ -610,6 +930,16 @@ dependencies = [ "hashbrown 0.13.2", ] +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + [[package]] name = "overload" version = "0.1.1" @@ -617,10 +947,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] -name = "owo-colors" -version = "3.5.0" +name = "parking" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "pathdiff" @@ -630,9 +960,9 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "pest" -version = "2.7.11" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" +checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" dependencies = [ "memchr", "thiserror", @@ -641,9 +971,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.11" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" +checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0" dependencies = [ "pest", "pest_generator", @@ -651,9 +981,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.11" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" +checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e" dependencies = [ "pest", "pest_meta", @@ -664,9 +994,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.11" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" +checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f" dependencies = [ "once_cell", "pest", @@ -679,12 +1009,62 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "polling" +version = "3.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "powerfmt" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -694,6 +1074,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quick-xml" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.37" @@ -703,6 +1092,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "redox_users" version = "0.4.6" @@ -780,17 +1199,11 @@ dependencies = [ "ordered-multimap", ] -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - [[package]] name = "rustix" -version = "0.38.36" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f55e80d50763938498dd5ebb18647174e0c76dc38c5505294bb224624f30f36" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags", "errno", @@ -807,18 +1220,18 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "serde" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -837,6 +1250,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde_spanned" version = "0.6.7" @@ -846,6 +1270,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sha2" version = "0.10.8" @@ -872,12 +1307,36 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.11.1" @@ -895,20 +1354,44 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tauri-winrt-notification" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f89f5fb70d6f62381f5d9b2ba9008196150b40b75f3068eb24faeddf1c686871" +dependencies = [ + "quick-xml", + "windows", + "windows-version", +] + +[[package]] +name = "tempfile" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", @@ -988,9 +1471,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "serde", @@ -1043,16 +1526,6 @@ dependencies = [ "valuable", ] -[[package]] -name = "tracing-error" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" -dependencies = [ - "tracing", - "tracing-subscriber", -] - [[package]] name = "tracing-log" version = "0.2.0" @@ -1094,17 +1567,28 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +[[package]] +name = "uds_windows" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" +dependencies = [ + "memoffset", + "tempfile", + "winapi", +] + [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "utf8parse" @@ -1161,6 +1645,59 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -1179,6 +1716,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -1210,6 +1756,15 @@ dependencies = [ "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-version" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6998aa457c9ba8ff2fb9f13e9d2a930dabcea28f1d0ab94d687d8b3654844515" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -1302,9 +1857,148 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "c52ac009d615e79296318c1bcce2d422aaca15ad08515e344feeda07df67a587" dependencies = [ "memchr", ] + +[[package]] +name = "xdg-home" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "zbus" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" +dependencies = [ + "async-broadcast", + "async-executor", + "async-fs", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "nix", + "ordered-stream", + "rand", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tracing", + "uds_windows", + "windows-sys 0.52.0", + "xdg-home", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" +dependencies = [ + "serde", + "static_assertions", + "zvariant", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zvariant" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe" +dependencies = [ + "endi", + "enumflags2", + "serde", + "static_assertions", + "zvariant_derive", +] + +[[package]] +name = "zvariant_derive" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 9fcca11..9a24ac3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,33 +3,21 @@ name = "arbs" edition = "2021" version = "0.1.0" +[features] +default = ["notifications"] +notifications = ["dep:notify-rust"] + [dependencies] -color-eyre = "0.6.3" dirs = "5.0.1" gethostname = "0.5.0" -serde_json = "1.0.128" +notify-rust = { version = "4.11.3", optional = true} +serde_json = { default-features = false, version = "1.0.128" } thiserror = "1.0.63" -toml = "0.8.19" -tracing = "0.1.40" +toml = { default-features = false, version = "0.8.19" } +tracing = { default-features = false, version = "0.1.40" } tracing-appender = "0.2.3" - -[dependencies.clap] -version = "4.5.17" -features = ["derive"] - -[dependencies.config] -version = "0.14.0" -features = ["ini", "toml", "json5", "ron", "json", "convert-case", "async"] -default-features = false - -[dependencies.serde] -version = "1.0.209" -features = ["derive"] - -[dependencies.tracing-subscriber] -version = "0.3.18" -features = ["env-filter"] - -[dependencies.uuid] -version = "1.10.0" -features = ["v4"] +clap = { version = "4.5.17", features = ["derive"] } +config = { version = "0.14.0" } +serde = { version = "1.0.209", features = ["derive"] } +tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } +uuid = { version = "1.10.0", features = ["v4"] } diff --git a/assets/icon.png b/assets/icon.png new file mode 100644 index 0000000..ae95463 Binary files /dev/null and b/assets/icon.png differ diff --git a/src/backup.rs b/src/backup.rs index 3d07ace..b468917 100644 --- a/src/backup.rs +++ b/src/backup.rs @@ -2,18 +2,18 @@ use std::{ fs::{create_dir_all, File}, io::{Read, Write}, path::PathBuf, - time::{SystemTime, UNIX_EPOCH}, + time::SystemTime, }; use serde::{Deserialize, Serialize}; -use tracing::info; +use tracing::{debug, info}; use uuid::Uuid; use crate::{ config::Config, error::{Error, Result}, - packages::{Manager, PackageList}, - pathinfo::PathInfo, + packages::PackageList, + pathinfo::PathInfo, send_notification, }; pub type Id = String; @@ -28,16 +28,20 @@ pub struct Backup { } impl Backup { - pub fn create(config: &Config, manager: Option) -> Result { + pub fn create(config: &Config) -> Result { let mut files: Vec = Vec::new(); for dir in &config.directories { files.push(PathInfo::from_path(config, dir)?); } Ok(Self { - // TODO: UUID not really needed, maybe a shorter hash id: Uuid::new_v4().to_string(), - timestamp: Self::get_timestamp(), - packages: Manager::get_manager(manager)?.get_installed()?, + timestamp: SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH)? + .as_secs(), + packages: config + .package_manager + .to_package_manager() + .get_installed()?, files, device: config.device.clone(), }) @@ -58,12 +62,14 @@ impl Backup { path.save(&backup_root)?; } + send_notification("Backup created" , "", notify_rust::Urgency::Normal)?; + Ok(()) } pub fn get_last(config: &Config) -> Result> { let backup_index_root = format!("{}/index.json", config.root); - info!(?backup_index_root, "backup index location:"); + debug!(?backup_index_root, "backup index location:"); let list: Vec = match Self::get_json_content(&backup_index_root) { Ok(list) => list, Err(err) => { @@ -74,8 +80,6 @@ impl Backup { } }; - info!(?list, "backup index:"); - Ok(Some(Self::from_index( config, &list.last().ok_or(Error::BackupNotFound)?.id, @@ -122,6 +126,8 @@ impl Backup { path.restore(config, &backup_root)?; } + send_notification("Backup restored" , "", notify_rust::Urgency::Normal)?; + Ok(()) } @@ -131,13 +137,6 @@ impl Backup { file.read_to_string(&mut content)?; Ok(serde_json::from_str(&content)?) } - - fn get_timestamp() -> u64 { - SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs() - } } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -165,7 +164,7 @@ impl IndexEntry { f.write_all(&serde_json::to_vec(&loc)?)?; } else { - create_dir_all(&config.root).unwrap(); + create_dir_all(&config.root)?; let mut f = File::create(backup_index_root)?; f.write_all(&serde_json::to_vec(&vec![self])?)?; }; diff --git a/src/cli.rs b/src/cli.rs index 1b62a84..588b6b0 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -2,8 +2,6 @@ use std::path::PathBuf; use clap::{Parser, Subcommand}; -use crate::packages::Manager; - #[derive(Parser)] pub struct Cli { #[arg(short, long)] @@ -16,10 +14,7 @@ pub struct Cli { #[derive(Subcommand)] pub enum Subcommands { GenerateConfig, - Save { - #[arg(short, long)] - package_manager: Option, - }, + Save, Restore { #[arg(short, long)] package_install: bool diff --git a/src/config.rs b/src/config.rs index 46d2204..848be19 100644 --- a/src/config.rs +++ b/src/config.rs @@ -4,6 +4,8 @@ use config::{File, Map}; use serde::{Deserialize, Serialize}; use tracing::{debug, trace}; +use crate::{error::{Error, Result}, packages::Manager}; + #[derive(Debug, Serialize, Deserialize)] #[serde(default)] pub struct Config { @@ -11,6 +13,7 @@ pub struct Config { pub directories: Vec, pub custom_directories: Map, pub device: String, + pub package_manager: Manager, } impl Default for Config { @@ -22,17 +25,18 @@ impl Default for Config { device: gethostname::gethostname() .into_string() .expect("invalid hostname string"), + package_manager: Manager::from_sys().expect("couldn't get package manager"), } } } impl Config { - pub fn load(path: Option) -> core::result::Result { + pub fn load(path: Option) -> Result { debug!("load config"); let source = if let Some(source) = path { source } else { - Self::get_location() + Self::get_location()? }; let config = config::Config::builder() @@ -40,14 +44,14 @@ impl Config { .add_source(config::Environment::with_prefix("FXBAUP").separator("_")) .build()?; - let cfg = config.try_deserialize(); + let cfg = config.try_deserialize()?; trace!(?cfg, "loaded config"); - cfg + Ok(cfg) } - pub fn generate() -> crate::error::Result<()> { - let loc = Self::get_location(); + pub fn generate() -> Result<()> { + let loc = Self::get_location()?; create_dir_all(loc.parent().unwrap())?; let mut f = std::fs::File::create(loc)?; f.write_all(toml::to_string(&Self::default())?.as_bytes())?; @@ -55,10 +59,12 @@ impl Config { Ok(()) } - fn get_location() -> PathBuf { - let mut conf_dir = dirs::config_local_dir().unwrap(); - conf_dir.push("arbs"); - conf_dir.push("config.toml"); - conf_dir + fn get_location() -> Result { + let Some(mut config_dir) = dirs::config_dir() else { + return Err(Error::NoSysDir); + }; + config_dir.push(env!("CARGO_PKG_NAME")); + config_dir.push("config.toml"); + Ok(config_dir) } } diff --git a/src/error.rs b/src/error.rs index cb57e99..8270b45 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,3 +1,5 @@ +use tracing::error; + pub type Result = std::result::Result; #[derive(Debug, thiserror::Error)] @@ -17,6 +19,10 @@ pub enum Error { #[error("Requested backup not found")] BackupNotFound, + // Utils + #[error("System directory not found")] + NoSysDir, + // Packages #[error("Unknown Package Manger Output")] UnknownOutput, @@ -25,12 +31,23 @@ pub enum Error { Unsupported, // Deps + #[error(transparent)] + Config(#[from] config::ConfigError), + #[error(transparent)] SerdeJson(#[from] serde_json::Error), #[error(transparent)] TomlSerialize(#[from] toml::ser::Error), + #[cfg(feature = "notifications")] + #[error(transparent)] + Notify(#[from] notify_rust::error::Error), + + // Rust #[error(transparent)] Io(#[from] std::io::Error), + + #[error(transparent)] + SystemTime(#[from] std::time::SystemTimeError), } diff --git a/src/main.rs b/src/main.rs index 487d095..ab23ab7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,9 @@ use backup::Backup; use clap::Parser; use cli::Subcommands; use config::Config; -use error::Error; -use tracing::{debug, level_filters::LevelFilter}; +use error::{Error, Result}; +use notify_rust::Urgency; +use tracing::{debug, error, level_filters::LevelFilter}; use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; mod backup; @@ -13,9 +14,7 @@ mod error; mod packages; mod pathinfo; -fn main() -> color_eyre::Result<()> { - color_eyre::install()?; - +fn main() -> Result<()> { let file_appender = tracing_appender::rolling::never("./", "arbs.log"); let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender); @@ -35,15 +34,27 @@ fn main() -> color_eyre::Result<()> { ) .init(); debug!("logging initialized"); + + match run_cli() { + Ok(()) => { println!("OK") ; Ok(())}, + Err(err) => { + error!(?err); + error!("{:?}", std::error::Error::source(&err)); + send_notification("Backup Error", &err.to_string(), Urgency::Critical)?; + Err(err) + } + } +} +fn run_cli() -> Result<()> { let cli = cli::Cli::parse(); let config = Config::load(cli.config)?; match cli.subcommand { Subcommands::GenerateConfig => Config::generate()?, - Subcommands::Save { package_manager } => { - let backup = Backup::create(&config, package_manager)?; + Subcommands::Save => { + let backup = Backup::create(&config)?; backup.save(&config)?; } Subcommands::Restore { package_install } => { @@ -56,7 +67,27 @@ fn main() -> color_eyre::Result<()> { } last_backup.restore(&config)?; - } + }, }; Ok(()) } + +fn send_notification(summary: &str, body: &str, urgency: Urgency) -> Result<()> { + #[cfg(feature = "notifications")] + { + let Some(mut icon) = dirs::data_dir() else { + return Err(Error::NoSysDir); + }; + icon.push(env!("CARGO_PKG_NAME")); + icon.push("icon.png"); + + notify_rust::Notification::new() + .summary(summary) + .body(body) + .icon(&icon.to_string_lossy()) + .timeout(0) + .urgency(urgency) + .show()?; + } + Ok(()) +} diff --git a/src/packages.rs b/src/packages.rs index de818f4..41b9478 100644 --- a/src/packages.rs +++ b/src/packages.rs @@ -37,15 +37,12 @@ pub enum Manager { } impl Manager { - pub fn get_manager(manager: Option) -> Result> { + pub fn from_sys() -> Result { #[cfg(not(target_os = "linux"))] return Err(Error::Unsupported); #[cfg(target_os = "linux")] { - if let Some(man) = manager { - return Ok(man.to_package_manager()); - } let mut os_release = File::open("/etc/os-release")?; let mut content = String::new(); os_release.read_to_string(&mut content)?; @@ -63,15 +60,15 @@ impl Manager { } } - fn from_str(value: &str) -> Result> { + fn from_str(value: &str) -> Result { Ok(match value { - "arch" => Box::new(Pacman), - "gentoo" => Box::new(Portage), + "arch" => Self::Pacman, + "gentoo" => Self::Portage, _ => return Err(Error::Unsupported), }) } - fn to_package_manager(&self) -> Box { + pub fn to_package_manager(&self) -> Box { match self { Self::Pacman => Box::new(Pacman), Self::Portage => Box::new(Portage), diff --git a/src/pathinfo.rs b/src/pathinfo.rs index 1231ff8..009f46a 100644 --- a/src/pathinfo.rs +++ b/src/pathinfo.rs @@ -6,7 +6,7 @@ use std::{ }; use serde::{Deserialize, Serialize}; -use tracing::{debug, info}; +use tracing::{debug, info, trace}; use crate::{ backup::{Backup, Id}, @@ -35,7 +35,7 @@ impl PathInfo { rel_location: &str, location_root: &LocationRoot, ) -> Result { - info!("Handling {rel_location}"); + trace!("Handling {rel_location}"); let path = Self::get_abs_path(&location_root.to_string(), rel_location); Ok(if path.is_dir() { let mut last_modified = Some(String::new()); @@ -83,7 +83,7 @@ impl PathInfo { ) -> Result { let last_modified = Self::compare_to_last_modified(config, location_root, rel_location)?; - info!("From file {rel_location} ({last_modified:?})"); + debug!("From file {rel_location} ({last_modified:?})"); Ok(Self { rel_location: rel_location.to_string(), @@ -301,14 +301,15 @@ mod tests { .custom_directories .insert("test".to_string(), "/usr/local/test".to_string()); - let mut values_ok: Vec<(&str, LocationRoot)> = Vec::new(); - values_ok.push(("u:test", LocationRoot::User)); - values_ok.push(("s:", LocationRoot::SystemConfig)); - values_ok.push(("r:", LocationRoot::Root)); - values_ok.push(( - "c:test", - LocationRoot::Custom("/usr/local/test".to_string()), - )); + let values_ok = vec![ + ("u:test", LocationRoot::User), + ("s:", LocationRoot::SystemConfig), + ("r:", LocationRoot::Root), + ( + "c:test", + LocationRoot::Custom("/usr/local/test".to_string()), + ), + ]; for value in values_ok { println!("Testing {value:?}"); @@ -316,18 +317,19 @@ mod tests { println!("\x1B[FTesting {value:?} ✓"); } - let mut values_err: Vec<(&str, String)> = Vec::new(); - values_err.push(( - "c:rest", - Error::CustomDirectory("rest".to_string()).to_string(), - )); - values_err.push(("t:test/", Error::InvalidIndex("t".to_string()).to_string())); - values_err.push(( - "test:test/usr", - Error::InvalidIndex("test".to_string()).to_string(), - )); - values_err.push(("/usr/local/test", Error::NoIndex.to_string())); - values_err.push(("c/usr/local/test", Error::NoIndex.to_string())); + let values_err = vec![ + ( + "c:rest", + Error::CustomDirectory("rest".to_string()).to_string(), + ), + ("t:test/", Error::InvalidIndex("t".to_string()).to_string()), + ( + "test:test/usr", + Error::InvalidIndex("test".to_string()).to_string(), + ), + ("/usr/local/test", Error::NoIndex.to_string()), + ("c/usr/local/test", Error::NoIndex.to_string()), + ]; for value in values_err { println!("Testing {value:?}"); @@ -351,47 +353,47 @@ mod tests { .custom_directories .insert("test".to_string(), "/usr/local/test".to_string()); - let mut values_ok: Vec<(&str, (String, LocationRoot))> = Vec::new(); - values_ok.push(( - "~/.config/nvim", - (".config/nvim".to_string(), LocationRoot::User), - )); - values_ok.push(( - "u:test/.config/nvim", - (".config/nvim".to_string(), LocationRoot::User), - )); - values_ok.push(( - "r:/.config/nvim", - (".config/nvim".to_string(), LocationRoot::Root), - )); - values_ok.push(( - "r:/.config/nvim", - (".config/nvim".to_string(), LocationRoot::Root), - )); - values_ok.push(( - "s:/.config/nvim", - (".config/nvim".to_string(), LocationRoot::SystemConfig), - )); - values_ok.push(( - "c:test/.config/nvim", + let values_ok = vec![ ( - ".config/nvim".to_string(), - LocationRoot::Custom("/usr/local/test".to_string()), + "~/.config/nvim", + (".config/nvim".to_string(), LocationRoot::User), + ), + ( + "u:test/.config/nvim", + (".config/nvim".to_string(), LocationRoot::User), ), - )); + ( + "r:/.config/nvim", + (".config/nvim".to_string(), LocationRoot::Root), + ), + ( + "r:/.config/nvim", + (".config/nvim".to_string(), LocationRoot::Root), + ), + ( + "s:/.config/nvim", + (".config/nvim".to_string(), LocationRoot::SystemConfig), + ), + ( + "c:test/.config/nvim", + ( + ".config/nvim".to_string(), + LocationRoot::Custom("/usr/local/test".to_string()), + ), + ), + ]; for value in values_ok { print!("Testing {value:?}"); - assert_eq!(PathInfo::parse_location(&value.0, &config)?, value.1); + assert_eq!(PathInfo::parse_location(value.0, &config)?, value.1); println!("\x1B[FTesting {value:?} ✓"); } Ok(()) } #[test] - fn compare_to_last_modified() -> color_eyre::Result<()> { - let mut config = Config::default(); - config.root = "./backup-test".to_string(); + fn compare_to_last_modified() -> Result<()> { + let mut config = Config { root: "./backup-test".to_string(), ..Default::default() }; config .directories .push("u:fx/code/proj/arbs/backup-test-dir".to_string()); @@ -404,7 +406,7 @@ mod tests { let mut f = File::create("./backup-test-dir/nothing.txt")?; f.write_all("unmodified".as_bytes())?; - let backup = Backup::create(&config, None)?; + let backup = Backup::create(&config)?; backup.save(&config)?; let mut f = File::create("./backup-test-dir/size.txt")?; -- cgit v1.2.3