diff --git a/src/action/mod.rs b/src/action/mod.rs index b8e12d6..c372934 100644 --- a/src/action/mod.rs +++ b/src/action/mod.rs @@ -137,12 +137,31 @@ impl Planner for MyPlanner { Ok(map) } + async fn configured_settings( + &self, + ) -> Result, PlannerError> { + let default = Self::default().await?.settings()?; + let configured = self.settings()?; + + let mut settings: HashMap = HashMap::new(); + for (key, value) in configured.iter() { + if default.get(key) != Some(value) { + settings.insert(key.clone(), value.clone()); + } + } + + Ok(settings) + } + #[cfg(feature = "diagnostics")] async fn diagnostic_data(&self) -> Result { Ok(nix_installer::diagnostics::DiagnosticData::new( self.common.diagnostic_endpoint.clone(), self.typetag_name().into(), - self.configured_settings().await?, + self.configured_settings() + .await? + .into_keys() + .collect::>(), )) } } diff --git a/src/cli/subcommand/install.rs b/src/cli/subcommand/install.rs index f4245ec..c7d88b9 100644 --- a/src/cli/subcommand/install.rs +++ b/src/cli/subcommand/install.rs @@ -158,6 +158,7 @@ impl CommandExecute for Install { match interaction::prompt( install_plan .describe_install(currently_explaining) + .await .map_err(|e| eyre!(e))?, PromptChoice::Yes, currently_explaining, diff --git a/src/plan.rs b/src/plan.rs index d65e531..75af488 100644 --- a/src/plan.rs +++ b/src/plan.rs @@ -65,34 +65,55 @@ impl InstallPlan { }) } #[tracing::instrument(level = "debug", skip_all)] - pub fn describe_install(&self, explain: bool) -> Result { + pub async fn describe_install(&self, explain: bool) -> Result { let Self { planner, actions, version, .. } = self; + + let plan_settings = if explain { + // List all settings when explaining + planner.settings()? + } else { + // Otherwise, only list user-configured settings + planner.configured_settings().await? + }; + let mut plan_settings = plan_settings + .into_iter() + .map(|(k, v)| format!("* {k}: {v}", k = k.bold())) + .collect::>(); + // Stabilize output order + plan_settings.sort(); + let buf = format!( "\ Nix install plan (v{version})\n\ \n\ Planner: {planner}\n\ \n\ - Planner settings:\n\ - \n\ - {plan_settings}\n\ - \n\ + {maybe_plan_settings}\ + \ The following actions will be taken:\n\ \n\ {actions}\n\ ", planner = planner.typetag_name(), - plan_settings = planner - .settings()? - .into_iter() - .map(|(k, v)| format!("* {k}: {v}", k = k.bold())) - .collect::>() - .join("\n"), + maybe_plan_settings = if plan_settings.is_empty() { + String::new() + } else { + // TODO: "Changed planner settings"? + format!( + "\ + Planner settings:\n\ + \n\ + {plan_settings}\n\ + \n\ + ", + plan_settings = plan_settings.join("\n") + ) + }, actions = actions .iter() .map(|v| v.describe_execute()) diff --git a/src/planner/linux.rs b/src/planner/linux.rs index cd09347..7894dc4 100644 --- a/src/planner/linux.rs +++ b/src/planner/linux.rs @@ -105,12 +105,31 @@ impl Planner for Linux { Ok(map) } + async fn configured_settings( + &self, + ) -> Result, PlannerError> { + let default = Self::default().await?.settings()?; + let configured = self.settings()?; + + let mut settings: HashMap = HashMap::new(); + for (key, value) in configured.iter() { + if default.get(key) != Some(value) { + settings.insert(key.clone(), value.clone()); + } + } + + Ok(settings) + } + #[cfg(feature = "diagnostics")] async fn diagnostic_data(&self) -> Result { Ok(crate::diagnostics::DiagnosticData::new( self.settings.diagnostic_endpoint.clone(), self.typetag_name().into(), - self.configured_settings().await?, + self.configured_settings() + .await? + .into_keys() + .collect::>(), )) } } diff --git a/src/planner/macos.rs b/src/planner/macos.rs index 278d189..04cc725 100644 --- a/src/planner/macos.rs +++ b/src/planner/macos.rs @@ -175,12 +175,31 @@ impl Planner for Macos { Ok(map) } + async fn configured_settings( + &self, + ) -> Result, PlannerError> { + let default = Self::default().await?.settings()?; + let configured = self.settings()?; + + let mut settings: HashMap = HashMap::new(); + for (key, value) in configured.iter() { + if default.get(key) != Some(value) { + settings.insert(key.clone(), value.clone()); + } + } + + Ok(settings) + } + #[cfg(feature = "diagnostics")] async fn diagnostic_data(&self) -> Result { Ok(crate::diagnostics::DiagnosticData::new( self.settings.diagnostic_endpoint.clone(), self.typetag_name().into(), - self.configured_settings().await?, + self.configured_settings() + .await? + .into_keys() + .collect::>(), )) } } diff --git a/src/planner/mod.rs b/src/planner/mod.rs index 4bc28be..b63ded5 100644 --- a/src/planner/mod.rs +++ b/src/planner/mod.rs @@ -53,12 +53,31 @@ impl Planner for MyPlanner { Ok(map) } + async fn configured_settings( + &self, + ) -> Result, PlannerError> { + let default = Self::default().await?.settings()?; + let configured = self.settings()?; + + let mut settings: HashMap = HashMap::new(); + for (key, value) in configured.iter() { + if default.get(key) != Some(value) { + settings.insert(key.clone(), value.clone()); + } + } + + Ok(settings) + } + #[cfg(feature = "diagnostics")] async fn diagnostic_data(&self) -> Result { Ok(nix_installer::diagnostics::DiagnosticData::new( self.common.diagnostic_endpoint.clone(), self.typetag_name().into(), - self.configured_settings().await?, + self.configured_settings() + .await? + .into_keys() + .collect::>(), )) } } @@ -111,21 +130,8 @@ pub trait Planner: std::fmt::Debug + Send + Sync + dyn_clone::DynClone { /// The settings being used by the planner fn settings(&self) -> Result, InstallSettingsError>; - async fn configured_settings(&self) -> Result, PlannerError> - where - Self: Sized, - { - let default = Self::default().await?.settings()?; - let configured = self.settings()?; - - let mut keys: Vec = Vec::new(); - for (key, value) in configured.iter() { - if default.get(key) != Some(value) { - keys.push(key.clone()) - } - } - Ok(keys) - } + async fn configured_settings(&self) + -> Result, PlannerError>; /// A boxed, type erased planner fn boxed(self) -> Box @@ -200,7 +206,9 @@ impl BuiltinPlanner { Ok(built) } - pub async fn configured_settings(&self) -> Result, PlannerError> { + pub async fn configured_settings( + &self, + ) -> Result, PlannerError> { match self { #[cfg(target_os = "linux")] BuiltinPlanner::Linux(inner) => inner.configured_settings().await, diff --git a/src/planner/steam_deck.rs b/src/planner/steam_deck.rs index d4fbce9..2605113 100644 --- a/src/planner/steam_deck.rs +++ b/src/planner/steam_deck.rs @@ -257,12 +257,31 @@ impl Planner for SteamDeck { Ok(map) } + async fn configured_settings( + &self, + ) -> Result, PlannerError> { + let default = Self::default().await?.settings()?; + let configured = self.settings()?; + + let mut settings: HashMap = HashMap::new(); + for (key, value) in configured.iter() { + if default.get(key) != Some(value) { + settings.insert(key.clone(), value.clone()); + } + } + + Ok(settings) + } + #[cfg(feature = "diagnostics")] async fn diagnostic_data(&self) -> Result { Ok(crate::diagnostics::DiagnosticData::new( self.settings.diagnostic_endpoint.clone(), self.typetag_name().into(), - self.configured_settings().await?, + self.configured_settings() + .await? + .into_keys() + .collect::>(), )) } }