Skip to content

Commit fa47570

Browse files
committed
feat: add notification support to --ask flags
Change-Id: I6a6a69642ac3443525df583fd200827414801d41
1 parent 19179ac commit fa47570

File tree

9 files changed

+166
-56
lines changed

9 files changed

+166
-56
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ hostname = "0.4.1"
3838
humantime = "2.3.0"
3939
inquire = { default-features = false, version = "0.9.1", features = [ "crossterm" ] }
4040
nix = { default-features = false, features = [ "fs", "user" ], version = "0.30.1" }
41-
yansi = "1.0.1"
42-
regex = "1.11.3"
4341
notify-rust = "4.11.7"
42+
regex = "1.11.3"
4443
reqwest = { default-features = false, features = [
4544
"rustls-tls-native-roots",
4645
"blocking",
@@ -58,6 +57,7 @@ thiserror = "2.0.17"
5857
tracing = "0.1.41"
5958
tracing-subscriber = { features = [ "env-filter", "registry", "std" ], version = "0.3.20" }
6059
which = "8.0.0"
60+
yansi = "1.0.1"
6161

6262
[target.'cfg(target_os="macos")'.dependencies]
6363
system-configuration = "0.6.1"

src/clean.rs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ use yansi::{Color, Paint};
2020
use crate::{
2121
Result,
2222
commands::{Command, ElevationStrategy},
23-
interface,
23+
interface::{self, NotifyAskMode},
2424
nh_info,
25+
notify::NotificationSender,
2526
};
2627

2728
// Nix impl:
@@ -250,7 +251,7 @@ impl interface::CleanMode {
250251
Err(err) => {
251252
warn!(?err, ?now, "Failed to compare time!");
252253
},
253-
Ok(val) if val <= args.keep_since.into() => {
254+
Ok(val) if val <= std::time::Duration::from(args.keep_since) => {
254255
gcroots_tagged.insert(dst, false);
255256
},
256257
Ok(_) => {
@@ -334,12 +335,26 @@ impl interface::CleanMode {
334335
}
335336

336337
// Clean the paths
337-
if args.ask
338-
&& !Confirm::new("Confirm the cleanup plan?")
339-
.with_default(false)
340-
.prompt()?
341-
{
342-
bail!("User rejected the cleanup plan");
338+
if let Some(ask) = &args.ask {
339+
let confirmation = match ask {
340+
NotifyAskMode::Prompt => {
341+
Confirm::new("Confirm the cleanup plan?")
342+
.with_default(false)
343+
.prompt()?
344+
},
345+
#[cfg(all(unix, not(target_os = "macos")))]
346+
NotifyAskMode::Notify => {
347+
NotificationSender::new(
348+
"nh clean",
349+
"Do you want to confirm the cleanup plan?",
350+
)
351+
.ask()
352+
},
353+
};
354+
355+
if !confirmation {
356+
bail!("User rejected the cleanup plan");
357+
}
343358
}
344359

345360
if !args.dry {
@@ -489,7 +504,7 @@ fn cleanable_generations(
489504
Err(err) => {
490505
warn!(?err, ?now, ?generation, "Failed to compare time!");
491506
},
492-
Ok(val) if val <= keep_since.into() => {
507+
Ok(val) if val <= std::time::Duration::from(keep_since) => {
493508
*tbr = false;
494509
},
495510
Ok(_) => {},

src/darwin.rs

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{env, path::PathBuf};
1+
use std::{env, fmt, path::PathBuf};
22

33
use color_eyre::eyre::{Context, bail, eyre};
44
use tracing::{debug, warn};
@@ -14,8 +14,10 @@ use crate::{
1414
DarwinReplArgs,
1515
DarwinSubcommand,
1616
DiffType,
17+
NotifyAskMode,
1718
},
1819
nixos::toplevel_for,
20+
notify::NotificationSender,
1921
update::update,
2022
util::{get_hostname, print_dix_diff},
2123
};
@@ -34,7 +36,7 @@ impl DarwinArgs {
3436
match self.subcommand {
3537
DarwinSubcommand::Switch(args) => args.rebuild(&Switch, elevation),
3638
DarwinSubcommand::Build(args) => {
37-
if args.common.ask || args.common.dry {
39+
if args.common.ask.is_some() || args.common.dry {
3840
warn!("`--ask` and `--dry` have no effect for `nh darwin build`");
3941
}
4042
args.rebuild(&Build, elevation)
@@ -49,6 +51,16 @@ enum DarwinRebuildVariant {
4951
Build,
5052
}
5153

54+
impl fmt::Display for DarwinRebuildVariant {
55+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56+
let s = match self {
57+
DarwinRebuildVariant::Build => "build",
58+
DarwinRebuildVariant::Switch => "switch",
59+
};
60+
write!(f, "{s}")
61+
}
62+
}
63+
5264
impl DarwinRebuildArgs {
5365
fn rebuild(
5466
self,
@@ -144,13 +156,27 @@ impl DarwinRebuildArgs {
144156
let _ = print_dix_diff(&PathBuf::from(CURRENT_PROFILE), &target_profile);
145157
}
146158

147-
if self.common.ask && !self.common.dry && !matches!(variant, Build) {
148-
let confirmation = inquire::Confirm::new("Apply the config?")
149-
.with_default(false)
150-
.prompt()?;
159+
if !self.common.dry && !matches!(variant, Build) {
160+
if let Some(ask) = self.common.ask {
161+
let confirmation = match ask {
162+
NotifyAskMode::Prompt => {
163+
inquire::Confirm::new("Apply the config?")
164+
.with_default(false)
165+
.prompt()?
166+
},
167+
#[cfg(all(unix, not(target_os = "macos")))]
168+
NotifyAskMode::Notify => {
169+
NotificationSender::new(
170+
&format!("nh darwin {variant}"),
171+
"Do you want to apply the Darwin configuration?",
172+
)
173+
.ask()
174+
},
175+
};
151176

152-
if !confirmation {
153-
bail!("User rejected the new config");
177+
if !confirmation {
178+
bail!("User rejected the new config");
179+
}
154180
}
155181
}
156182

src/home.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,16 @@ use crate::{
1010
commands,
1111
commands::Command,
1212
installable::Installable,
13-
interface::{self, DiffType, HomeRebuildArgs, HomeReplArgs, HomeSubcommand},
13+
interface::{
14+
self,
15+
DiffType,
16+
HomeRebuildArgs,
17+
HomeReplArgs,
18+
HomeSubcommand,
19+
NotifyAskMode,
20+
},
1421
nh_info,
22+
notify::NotificationSender,
1523
update::update,
1624
util::{get_hostname, print_dix_diff},
1725
};
@@ -27,7 +35,7 @@ impl interface::HomeArgs {
2735
match self.subcommand {
2836
HomeSubcommand::Switch(args) => args.rebuild(&Switch),
2937
HomeSubcommand::Build(args) => {
30-
if args.common.ask || args.common.dry {
38+
if args.common.ask.is_some() || args.common.dry {
3139
warn!("`--ask` and `--dry` have no effect for `nh home build`");
3240
}
3341
args.rebuild(&Build)
@@ -151,16 +159,28 @@ impl HomeRebuildArgs {
151159
}
152160

153161
if self.common.dry || matches!(variant, Build) {
154-
if self.common.ask {
162+
if self.common.ask.is_some() {
155163
warn!("--ask has no effect as dry run was requested");
156164
}
157165
return Ok(());
158166
}
159167

160-
if self.common.ask {
161-
let confirmation = inquire::Confirm::new("Apply the config?")
162-
.with_default(false)
163-
.prompt()?;
168+
if let Some(ask) = &self.common.ask {
169+
let confirmation = match ask {
170+
NotifyAskMode::Prompt => {
171+
inquire::Confirm::new("Apply the config?")
172+
.with_default(false)
173+
.prompt()?
174+
},
175+
#[cfg(all(unix, not(target_os = "macos")))]
176+
NotifyAskMode::Notify => {
177+
NotificationSender::new(
178+
"nh home switch",
179+
"Do you want to apply the Home Manager configuration?",
180+
)
181+
.ask()
182+
},
183+
};
164184

165185
if !confirmation {
166186
bail!("User rejected the new config");

src/interface.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,15 +264,24 @@ pub enum DiffType {
264264
Never,
265265
}
266266

267+
#[derive(Debug, Clone, ValueEnum, PartialEq)]
268+
pub enum NotifyAskMode {
269+
/// Ask in the terminal (stdin prompt)
270+
Prompt,
271+
/// Ask via a desktop notification action
272+
#[cfg(all(unix, not(target_os = "macos")))]
273+
Notify,
274+
}
275+
267276
#[derive(Debug, Args)]
268277
pub struct OsRollbackArgs {
269278
/// Only print actions, without performing them
270279
#[arg(long, short = 'n')]
271280
pub dry: bool,
272281

273282
/// Ask for confirmation
274-
#[arg(long, short)]
275-
pub ask: bool,
283+
#[arg(long, short, value_enum, default_missing_value = "prompt", num_args = 0..=1)]
284+
pub ask: Option<NotifyAskMode>,
276285

277286
/// Explicitly select some specialisation
278287
#[arg(long, short)]
@@ -303,8 +312,8 @@ pub struct CommonRebuildArgs {
303312
pub dry: bool,
304313

305314
/// Ask for confirmation
306-
#[arg(long, short)]
307-
pub ask: bool,
315+
#[arg(long, short, default_missing_value = "prompt", num_args = 0..=1)]
316+
pub ask: Option<NotifyAskMode>,
308317

309318
#[command(flatten)]
310319
pub installable: Installable,
@@ -435,8 +444,8 @@ pub struct CleanArgs {
435444
pub dry: bool,
436445

437446
/// Ask for confirmation
438-
#[arg(long, short)]
439-
pub ask: bool,
447+
#[arg(long, short, default_missing_value = "prompt", num_args = 0..=1)]
448+
pub ask: Option<NotifyAskMode>,
440449

441450
/// Don't run nix store --gc
442451
#[arg(long = "no-gc", alias = "nogc")]

src/logging.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ where
3131

3232
match *level {
3333
Level::ERROR => {
34-
write!(writer, "{} ", Paint::new("ERROR").fg(Color::Red))?
34+
write!(writer, "{} ", Paint::new("ERROR").fg(Color::Red))?;
3535
},
3636
Level::WARN => write!(writer, "{} ", Paint::new("!").fg(Color::Yellow))?,
3737
Level::INFO => write!(writer, "{} ", Paint::new(">").fg(Color::Green))?,
3838
Level::DEBUG => {
39-
write!(writer, "{} ", Paint::new("DEBUG").fg(Color::Blue))?
39+
write!(writer, "{} ", Paint::new("DEBUG").fg(Color::Blue))?;
4040
},
4141
Level::TRACE => {
42-
write!(writer, "{} ", Paint::new("TRACE").fg(Color::Cyan))?
42+
write!(writer, "{} ", Paint::new("TRACE").fg(Color::Cyan))?;
4343
},
4444
}
4545

@@ -99,7 +99,7 @@ pub fn setup_logging(
9999
macro_rules! nh_info {
100100
($($arg:tt)*) => {{
101101
use notify_rust::Urgency;
102-
use crate::notify::NotificationSender;
102+
use $crate::notify::NotificationSender;
103103
let message = format!($($arg)*);
104104
tracing::info!($($arg)*);
105105
NotificationSender::new("nh info", &message).urgency(Urgency::Normal).send().unwrap();
@@ -110,7 +110,7 @@ macro_rules! nh_info {
110110
macro_rules! nh_warn {
111111
($($arg:tt)*) => {{
112112
use notify_rust::Urgency;
113-
use crate::notify::NotificationSender;
113+
use $crate::notify::NotificationSender;
114114
let message = format!($($arg)*);
115115
tracing::warn!($($arg)*);
116116
NotificationSender::new("nh warn", &message).urgency(Urgency::Normal).send().unwrap();

0 commit comments

Comments
 (0)