├── .github └── dependabot.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md └── main.rs /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: weekly 7 | time: "10:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | **/*.rs.bk 3 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "alert-after" 5 | version = "1.5.1" 6 | dependencies = [ 7 | "notifica", 8 | ] 9 | 10 | [[package]] 11 | name = "arrayref" 12 | version = "0.3.5" 13 | source = "registry+https://github.com/rust-lang/crates.io-index" 14 | checksum = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" 15 | 16 | [[package]] 17 | name = "arrayvec" 18 | version = "0.5.1" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" 21 | 22 | [[package]] 23 | name = "autocfg" 24 | version = "0.1.7" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" 27 | 28 | [[package]] 29 | name = "backtrace" 30 | version = "0.3.40" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | checksum = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" 33 | dependencies = [ 34 | "backtrace-sys", 35 | "cfg-if", 36 | "libc", 37 | "rustc-demangle", 38 | ] 39 | 40 | [[package]] 41 | name = "backtrace-sys" 42 | version = "0.1.32" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | checksum = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" 45 | dependencies = [ 46 | "cc", 47 | "libc", 48 | ] 49 | 50 | [[package]] 51 | name = "base64" 52 | version = "0.10.1" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" 55 | dependencies = [ 56 | "byteorder", 57 | ] 58 | 59 | [[package]] 60 | name = "bitflags" 61 | version = "1.2.1" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 64 | 65 | [[package]] 66 | name = "blake2b_simd" 67 | version = "0.5.9" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "b83b7baab1e671718d78204225800d6b170e648188ac7dc992e9d6bddf87d0c0" 70 | dependencies = [ 71 | "arrayref", 72 | "arrayvec", 73 | "constant_time_eq", 74 | ] 75 | 76 | [[package]] 77 | name = "block" 78 | version = "0.1.6" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" 81 | 82 | [[package]] 83 | name = "byteorder" 84 | version = "1.3.2" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" 87 | 88 | [[package]] 89 | name = "cc" 90 | version = "1.0.47" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8" 93 | 94 | [[package]] 95 | name = "cfg-if" 96 | version = "0.1.10" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 99 | 100 | [[package]] 101 | name = "chrono" 102 | version = "0.4.10" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | checksum = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" 105 | dependencies = [ 106 | "num-integer", 107 | "num-traits", 108 | "time", 109 | ] 110 | 111 | [[package]] 112 | name = "cloudabi" 113 | version = "0.0.3" 114 | source = "registry+https://github.com/rust-lang/crates.io-index" 115 | checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 116 | dependencies = [ 117 | "bitflags", 118 | ] 119 | 120 | [[package]] 121 | name = "constant_time_eq" 122 | version = "0.1.4" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" 125 | 126 | [[package]] 127 | name = "crossbeam-utils" 128 | version = "0.6.6" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" 131 | dependencies = [ 132 | "cfg-if", 133 | "lazy_static", 134 | ] 135 | 136 | [[package]] 137 | name = "dbus" 138 | version = "0.6.5" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "48b5f0f36f1eebe901b0e6bee369a77ed3396334bf3f09abd46454a576f71819" 141 | dependencies = [ 142 | "libc", 143 | "libdbus-sys", 144 | ] 145 | 146 | [[package]] 147 | name = "dirs" 148 | version = "1.0.5" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" 151 | dependencies = [ 152 | "libc", 153 | "redox_users", 154 | "winapi", 155 | ] 156 | 157 | [[package]] 158 | name = "failure" 159 | version = "0.1.6" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" 162 | dependencies = [ 163 | "backtrace", 164 | "failure_derive", 165 | ] 166 | 167 | [[package]] 168 | name = "failure_derive" 169 | version = "0.1.6" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" 172 | dependencies = [ 173 | "proc-macro2", 174 | "quote", 175 | "syn", 176 | "synstructure", 177 | ] 178 | 179 | [[package]] 180 | name = "fuchsia-cprng" 181 | version = "0.1.1" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 184 | 185 | [[package]] 186 | name = "lazy_static" 187 | version = "1.4.0" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 190 | 191 | [[package]] 192 | name = "libc" 193 | version = "0.2.65" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" 196 | 197 | [[package]] 198 | name = "libdbus-sys" 199 | version = "0.2.1" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "dc12a3bc971424edbbf7edaf6e5740483444db63aa8e23d3751ff12a30f306f0" 202 | dependencies = [ 203 | "pkg-config", 204 | ] 205 | 206 | [[package]] 207 | name = "mac-notification-sys" 208 | version = "0.3.0" 209 | source = "registry+https://github.com/rust-lang/crates.io-index" 210 | checksum = "3dfb6b71a9a89cd38b395d994214297447e8e63b1ba5708a9a2b0b1048ceda76" 211 | dependencies = [ 212 | "cc", 213 | "chrono", 214 | "dirs", 215 | "objc-foundation", 216 | ] 217 | 218 | [[package]] 219 | name = "malloc_buf" 220 | version = "0.0.6" 221 | source = "registry+https://github.com/rust-lang/crates.io-index" 222 | checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" 223 | dependencies = [ 224 | "libc", 225 | ] 226 | 227 | [[package]] 228 | name = "notifica" 229 | version = "3.0.2" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "a4e81fcdf9755383979b66adf525a66a8f621b55882a820552b201839b0ce3f7" 232 | dependencies = [ 233 | "mac-notification-sys", 234 | "notify-rust", 235 | "winrt", 236 | ] 237 | 238 | [[package]] 239 | name = "notify-rust" 240 | version = "3.6.3" 241 | source = "registry+https://github.com/rust-lang/crates.io-index" 242 | checksum = "f8da29142be3f71b2165a6b3991c26045b674edbf04cdfc42f323094fc3e4b5a" 243 | dependencies = [ 244 | "dbus", 245 | "mac-notification-sys", 246 | ] 247 | 248 | [[package]] 249 | name = "num-integer" 250 | version = "0.1.41" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" 253 | dependencies = [ 254 | "autocfg", 255 | "num-traits", 256 | ] 257 | 258 | [[package]] 259 | name = "num-traits" 260 | version = "0.2.10" 261 | source = "registry+https://github.com/rust-lang/crates.io-index" 262 | checksum = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4" 263 | dependencies = [ 264 | "autocfg", 265 | ] 266 | 267 | [[package]] 268 | name = "objc" 269 | version = "0.2.7" 270 | source = "registry+https://github.com/rust-lang/crates.io-index" 271 | checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" 272 | dependencies = [ 273 | "malloc_buf", 274 | ] 275 | 276 | [[package]] 277 | name = "objc-foundation" 278 | version = "0.1.1" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" 281 | dependencies = [ 282 | "block", 283 | "objc", 284 | "objc_id", 285 | ] 286 | 287 | [[package]] 288 | name = "objc_id" 289 | version = "0.1.1" 290 | source = "registry+https://github.com/rust-lang/crates.io-index" 291 | checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" 292 | dependencies = [ 293 | "objc", 294 | ] 295 | 296 | [[package]] 297 | name = "pkg-config" 298 | version = "0.3.17" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" 301 | 302 | [[package]] 303 | name = "proc-macro2" 304 | version = "1.0.6" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" 307 | dependencies = [ 308 | "unicode-xid", 309 | ] 310 | 311 | [[package]] 312 | name = "quote" 313 | version = "1.0.2" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" 316 | dependencies = [ 317 | "proc-macro2", 318 | ] 319 | 320 | [[package]] 321 | name = "rand_core" 322 | version = "0.3.1" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 325 | dependencies = [ 326 | "rand_core 0.4.2", 327 | ] 328 | 329 | [[package]] 330 | name = "rand_core" 331 | version = "0.4.2" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 334 | 335 | [[package]] 336 | name = "rand_os" 337 | version = "0.1.3" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" 340 | dependencies = [ 341 | "cloudabi", 342 | "fuchsia-cprng", 343 | "libc", 344 | "rand_core 0.4.2", 345 | "rdrand", 346 | "winapi", 347 | ] 348 | 349 | [[package]] 350 | name = "rdrand" 351 | version = "0.4.0" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 354 | dependencies = [ 355 | "rand_core 0.3.1", 356 | ] 357 | 358 | [[package]] 359 | name = "redox_syscall" 360 | version = "0.1.56" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" 363 | 364 | [[package]] 365 | name = "redox_users" 366 | version = "0.3.1" 367 | source = "registry+https://github.com/rust-lang/crates.io-index" 368 | checksum = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d" 369 | dependencies = [ 370 | "failure", 371 | "rand_os", 372 | "redox_syscall", 373 | "rust-argon2", 374 | ] 375 | 376 | [[package]] 377 | name = "rust-argon2" 378 | version = "0.5.1" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | checksum = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" 381 | dependencies = [ 382 | "base64", 383 | "blake2b_simd", 384 | "crossbeam-utils", 385 | ] 386 | 387 | [[package]] 388 | name = "rustc-demangle" 389 | version = "0.1.16" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" 392 | 393 | [[package]] 394 | name = "syn" 395 | version = "1.0.8" 396 | source = "registry+https://github.com/rust-lang/crates.io-index" 397 | checksum = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92" 398 | dependencies = [ 399 | "proc-macro2", 400 | "quote", 401 | "unicode-xid", 402 | ] 403 | 404 | [[package]] 405 | name = "synstructure" 406 | version = "0.12.3" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" 409 | dependencies = [ 410 | "proc-macro2", 411 | "quote", 412 | "syn", 413 | "unicode-xid", 414 | ] 415 | 416 | [[package]] 417 | name = "time" 418 | version = "0.1.42" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" 421 | dependencies = [ 422 | "libc", 423 | "redox_syscall", 424 | "winapi", 425 | ] 426 | 427 | [[package]] 428 | name = "unicode-xid" 429 | version = "0.2.0" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" 432 | 433 | [[package]] 434 | name = "winapi" 435 | version = "0.3.8" 436 | source = "registry+https://github.com/rust-lang/crates.io-index" 437 | checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" 438 | dependencies = [ 439 | "winapi-i686-pc-windows-gnu", 440 | "winapi-x86_64-pc-windows-gnu", 441 | ] 442 | 443 | [[package]] 444 | name = "winapi-i686-pc-windows-gnu" 445 | version = "0.4.0" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 448 | 449 | [[package]] 450 | name = "winapi-x86_64-pc-windows-gnu" 451 | version = "0.4.0" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 454 | 455 | [[package]] 456 | name = "winrt" 457 | version = "0.6.0" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | checksum = "c248f437add7df81d305a345e9d143c8c0a9de00a51e46b42453c337181d16c9" 460 | dependencies = [ 461 | "winapi", 462 | ] 463 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "alert-after" 3 | version = "1.5.1" 4 | authors = ["Corey Farwell "] 5 | license = "MIT/Apache-2.0" 6 | description = "Get a desktop notification after a command finishes executing" 7 | repository = "https://github.com/frewsxcv/alert-after" 8 | edition = "2018" 9 | 10 | [[bin]] 11 | name = "aa" 12 | path = "main.rs" 13 | 14 | [dependencies] 15 | notifica = "3.0.2" 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # alert-after 2 | 3 | Get a desktop notification after a command finishes executing. Helpful for notifying when long running CLI tasks are completed. Works on macOS, Linux, and Windows. 4 | 5 | ![](http://i.imgur.com/XCTUJfT.gif) 6 | 7 | ## Install 8 | 9 | 1. [Install Rust](https://rustup.rs/) 10 | 2. `cargo install alert-after` 11 | 12 | If installing on Linux, [Libdbus is also required](https://github.com/diwic/dbus-rs#requirements). 13 | 14 | ## Usage 15 | 16 | ``` 17 | aa 18 | ``` 19 | 20 | Get a desktop notification after sleeping for five seconds: 21 | 22 | ``` 23 | aa sleep 5 24 | ``` 25 | 26 | Get a desktop notification after retrieving Google: 27 | 28 | ``` 29 | aa wget google.com 30 | ``` 31 | 32 | ## Upgrade 33 | 34 | ``` 35 | cargo install --force alert-after 36 | ``` 37 | -------------------------------------------------------------------------------- /main.rs: -------------------------------------------------------------------------------- 1 | extern crate notifica; 2 | 3 | use std::io::Write; 4 | use std::{borrow, env, error, io, process}; 5 | 6 | type ExitCode = i32; 7 | 8 | fn exit_status_to_message(exit_status: process::ExitStatus) -> borrow::Cow<'static, str> { 9 | match exit_status.code() { 10 | Some(0) => "Command exited successfully".into(), 11 | Some(code) => format!("Command exited with status code {}", code).into(), 12 | None => "Command exited".into(), 13 | } 14 | } 15 | 16 | fn spawn_command(args: &[String]) -> Result> { 17 | let program_name = first_arg_as_program_name(&args)?; 18 | process::Command::new(program_name.clone()) 19 | .args(&args[1..]) 20 | .spawn() 21 | .map_err(|e| format!("aa: Unknown command '{}': {}", program_name, e).into()) 22 | } 23 | 24 | fn args() -> Vec { 25 | env::args().skip(1).collect() 26 | } 27 | 28 | fn first_arg_as_program_name(args: &[String]) -> Result> { 29 | args.first() 30 | .cloned() 31 | .ok_or_else(|| "usage: aa ".into()) 32 | } 33 | 34 | fn alert_after() -> Result> { 35 | let args = args(); 36 | let mut child = spawn_command(&args)?; 37 | let exit_status = child.wait().expect("failed to wait on command"); 38 | let cmd_success = exit_status_to_message(exit_status); 39 | notifica::notify(&args.join(" "), &cmd_success); 40 | Ok(exit_status.code().unwrap_or(0)) 41 | } 42 | 43 | fn run() { 44 | match alert_after() { 45 | Ok(exit_code) => process::exit(exit_code), 46 | Err(e) => writeln!(io::stderr(), "aa: {}", e).expect("could not write to stderr"), 47 | } 48 | } 49 | 50 | fn main() { 51 | run(); 52 | } 53 | --------------------------------------------------------------------------------