diff --git a/src/action/common/configure_nix.rs b/src/action/common/configure_nix.rs index c088c7c..214cdc1 100644 --- a/src/action/common/configure_nix.rs +++ b/src/action/common/configure_nix.rs @@ -184,4 +184,8 @@ impl Action for ConfigureNix { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } diff --git a/src/action/common/configure_nix_daemon_service.rs b/src/action/common/configure_nix_daemon_service.rs index 5e810fd..e74bd70 100644 --- a/src/action/common/configure_nix_daemon_service.rs +++ b/src/action/common/configure_nix_daemon_service.rs @@ -212,6 +212,10 @@ impl Action for ConfigureNixDaemonService { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/common/configure_shell_profile.rs b/src/action/common/configure_shell_profile.rs index f84c5dc..8a903da 100644 --- a/src/action/common/configure_shell_profile.rs +++ b/src/action/common/configure_shell_profile.rs @@ -181,6 +181,10 @@ impl Action for ConfigureShellProfile { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/common/create_directory.rs b/src/action/common/create_directory.rs index b67fe76..e40edda 100644 --- a/src/action/common/create_directory.rs +++ b/src/action/common/create_directory.rs @@ -214,6 +214,10 @@ impl Action for CreateDirectory { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/common/create_file.rs b/src/action/common/create_file.rs index 08b4c54..9b462f2 100644 --- a/src/action/common/create_file.rs +++ b/src/action/common/create_file.rs @@ -188,6 +188,10 @@ impl Action for CreateFile { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/common/create_group.rs b/src/action/common/create_group.rs index 2ac3971..4c81ff3 100644 --- a/src/action/common/create_group.rs +++ b/src/action/common/create_group.rs @@ -160,6 +160,10 @@ impl Action for CreateGroup { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/common/create_nix_tree.rs b/src/action/common/create_nix_tree.rs index ab4d1e3..c96e00e 100644 --- a/src/action/common/create_nix_tree.rs +++ b/src/action/common/create_nix_tree.rs @@ -134,6 +134,10 @@ impl Action for CreateNixTree { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/common/create_or_append_file.rs b/src/action/common/create_or_append_file.rs index 81ad802..d4c6e52 100644 --- a/src/action/common/create_or_append_file.rs +++ b/src/action/common/create_or_append_file.rs @@ -223,6 +223,10 @@ impl Action for CreateOrAppendFile { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/common/create_user.rs b/src/action/common/create_user.rs index 40a6086..589b26a 100644 --- a/src/action/common/create_user.rs +++ b/src/action/common/create_user.rs @@ -254,6 +254,10 @@ impl Action for CreateUser { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/common/create_users_and_group.rs b/src/action/common/create_users_and_group.rs index 3b2cd62..619eb3c 100644 --- a/src/action/common/create_users_and_group.rs +++ b/src/action/common/create_users_and_group.rs @@ -229,6 +229,10 @@ impl Action for CreateUsersAndGroup { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/common/fetch_nix.rs b/src/action/common/fetch_nix.rs index 47f7349..e1f111b 100644 --- a/src/action/common/fetch_nix.rs +++ b/src/action/common/fetch_nix.rs @@ -115,6 +115,10 @@ impl Action for FetchNix { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/common/move_unpacked_nix.rs b/src/action/common/move_unpacked_nix.rs index 6638cec..d545e23 100644 --- a/src/action/common/move_unpacked_nix.rs +++ b/src/action/common/move_unpacked_nix.rs @@ -106,6 +106,10 @@ impl Action for MoveUnpackedNix { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/common/place_channel_configuration.rs b/src/action/common/place_channel_configuration.rs index ca424c1..a44a5ac 100644 --- a/src/action/common/place_channel_configuration.rs +++ b/src/action/common/place_channel_configuration.rs @@ -130,6 +130,10 @@ impl Action for PlaceChannelConfiguration { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/common/place_nix_configuration.rs b/src/action/common/place_nix_configuration.rs index 1e513ef..9aa444a 100644 --- a/src/action/common/place_nix_configuration.rs +++ b/src/action/common/place_nix_configuration.rs @@ -115,6 +115,10 @@ impl Action for PlaceNixConfiguration { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/common/provision_nix.rs b/src/action/common/provision_nix.rs index 60f9302..937e74d 100644 --- a/src/action/common/provision_nix.rs +++ b/src/action/common/provision_nix.rs @@ -168,6 +168,10 @@ impl Action for ProvisionNix { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/common/setup_default_profile.rs b/src/action/common/setup_default_profile.rs index 38618f3..5e8efb3 100644 --- a/src/action/common/setup_default_profile.rs +++ b/src/action/common/setup_default_profile.rs @@ -181,6 +181,10 @@ impl Action for SetupDefaultProfile { *action_state = ActionState::Completed; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/darwin/bootstrap_volume.rs b/src/action/darwin/bootstrap_volume.rs index ecdb447..f9f0530 100644 --- a/src/action/darwin/bootstrap_volume.rs +++ b/src/action/darwin/bootstrap_volume.rs @@ -106,6 +106,10 @@ impl Action for BootstrapVolume { *action_state = ActionState::Completed; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/darwin/create_apfs_volume.rs b/src/action/darwin/create_apfs_volume.rs index 2d280fd..c6a8cf5 100644 --- a/src/action/darwin/create_apfs_volume.rs +++ b/src/action/darwin/create_apfs_volume.rs @@ -289,6 +289,10 @@ impl Action for CreateApfsVolume { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/darwin/create_synthetic_objects.rs b/src/action/darwin/create_synthetic_objects.rs index 94a43e4..97c2604 100644 --- a/src/action/darwin/create_synthetic_objects.rs +++ b/src/action/darwin/create_synthetic_objects.rs @@ -98,6 +98,10 @@ impl Action for CreateSyntheticObjects { *action_state = ActionState::Completed; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/darwin/create_volume.rs b/src/action/darwin/create_volume.rs index 49a7899..de02144 100644 --- a/src/action/darwin/create_volume.rs +++ b/src/action/darwin/create_volume.rs @@ -130,6 +130,10 @@ impl Action for CreateVolume { *action_state = ActionState::Completed; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/darwin/enable_ownership.rs b/src/action/darwin/enable_ownership.rs index 3e627ea..a1a456b 100644 --- a/src/action/darwin/enable_ownership.rs +++ b/src/action/darwin/enable_ownership.rs @@ -109,6 +109,10 @@ impl Action for EnableOwnership { *action_state = ActionState::Completed; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/darwin/encrypt_volume.rs b/src/action/darwin/encrypt_volume.rs index 8e8f5c3..d982177 100644 --- a/src/action/darwin/encrypt_volume.rs +++ b/src/action/darwin/encrypt_volume.rs @@ -86,6 +86,10 @@ impl Action for EncryptVolume { *action_state = ActionState::Completed; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/darwin/kickstart_launchctl_service.rs b/src/action/darwin/kickstart_launchctl_service.rs index c98eed8..2566ae1 100644 --- a/src/action/darwin/kickstart_launchctl_service.rs +++ b/src/action/darwin/kickstart_launchctl_service.rs @@ -96,6 +96,10 @@ impl Action for KickstartLaunchctlService { *action_state = ActionState::Completed; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/darwin/unmount_volume.rs b/src/action/darwin/unmount_volume.rs index 834cea3..70cad7c 100644 --- a/src/action/darwin/unmount_volume.rs +++ b/src/action/darwin/unmount_volume.rs @@ -117,6 +117,10 @@ impl Action for UnmountVolume { *action_state = ActionState::Completed; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/linux/create_systemd_sysext.rs b/src/action/linux/create_systemd_sysext.rs index 36c617a..c9dde74 100644 --- a/src/action/linux/create_systemd_sysext.rs +++ b/src/action/linux/create_systemd_sysext.rs @@ -185,6 +185,10 @@ impl Action for CreateSystemdSysext { *action_state = ActionState::Uncompleted; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/linux/start_systemd_unit.rs b/src/action/linux/start_systemd_unit.rs index 7f36f57..21fc16d 100644 --- a/src/action/linux/start_systemd_unit.rs +++ b/src/action/linux/start_systemd_unit.rs @@ -98,6 +98,10 @@ impl Action for StartSystemdUnit { *action_state = ActionState::Completed; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/linux/systemd_sysext_merge.rs b/src/action/linux/systemd_sysext_merge.rs index 332192f..9d74d72 100644 --- a/src/action/linux/systemd_sysext_merge.rs +++ b/src/action/linux/systemd_sysext_merge.rs @@ -102,6 +102,10 @@ impl Action for SystemdSysextMerge { *action_state = ActionState::Completed; Ok(()) } + + fn action_state(&self) -> ActionState { + self.action_state + } } #[derive(Debug, thiserror::Error)] diff --git a/src/action/mod.rs b/src/action/mod.rs index 508e49d..99ef567 100644 --- a/src/action/mod.rs +++ b/src/action/mod.rs @@ -13,11 +13,12 @@ pub trait Action: Send + Sync + std::fmt::Debug + dyn_clone::DynClone { // They should also have an `async fn plan(args...) -> Result, Box>;` async fn execute(&mut self) -> Result<(), Box>; async fn revert(&mut self) -> Result<(), Box>; + fn action_state(&self) -> ActionState; } dyn_clone::clone_trait_object!(Action); -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Copy)] pub enum ActionState { Completed, // Only applicable to meta-actions that start multiple sub-actions. diff --git a/src/cli/subcommand/install.rs b/src/cli/subcommand/install.rs index 15b0f9a..daa1f33 100644 --- a/src/cli/subcommand/install.rs +++ b/src/cli/subcommand/install.rs @@ -3,7 +3,7 @@ use std::{ process::ExitCode, }; -use crate::{plan::RECEIPT_LOCATION, BuiltinPlanner, InstallPlan, Planner}; +use crate::{plan::RECEIPT_LOCATION, BuiltinPlanner, InstallPlan, Planner, action::ActionState}; use clap::{ArgAction, Parser}; use eyre::{eyre, WrapErr}; @@ -62,11 +62,17 @@ impl CommandExecute for Install { match existing_receipt { Some(existing_receipt) => { - if existing_receipt.planner.typetag_name() == chosen_planner.typetag_name() { - existing_receipt - } else { + if existing_receipt.planner.typetag_name() != chosen_planner.typetag_name() { return Err(eyre!("Found existing plan in `/nix/receipt.json` which used a different planner, try uninstalling the existing install")) } + if existing_receipt.planner.settings().map_err(|e| eyre!(e))? != chosen_planner.settings().map_err(|e| eyre!(e))? { + return Err(eyre!("Found existing plan in `/nix/receipt.json` which used different planner settings, try uninstalling the existing install")) + } + if existing_receipt.actions.iter().all(|v| v.action_state() == ActionState::Completed) { + return Err(eyre!("Found existing plan in `/nix/receipt.json`, with the same settings, already completed, try uninstalling and reinstalling if Nix isn't working")) + } + + existing_receipt } , None => { planner.plan().await.map_err(|e| eyre!(e))? diff --git a/src/plan.rs b/src/plan.rs index eb42033..a1aaee1 100644 --- a/src/plan.rs +++ b/src/plan.rs @@ -45,7 +45,7 @@ impl InstallPlan { }, planner = planner.typetag_name(), plan_settings = planner - .describe()? + .settings()? .into_iter() .map(|(k, v)| format!("* {k}: {v}", k = k.bold().white())) .collect::>() diff --git a/src/planner/darwin/multi.rs b/src/planner/darwin/multi.rs index 08da5eb..e677b9c 100644 --- a/src/planner/darwin/multi.rs +++ b/src/planner/darwin/multi.rs @@ -98,7 +98,7 @@ impl Planner for DarwinMulti { }) } - fn describe( + fn settings( &self, ) -> Result, Box> { let Self { diff --git a/src/planner/linux/multi.rs b/src/planner/linux/multi.rs index 54aa3aa..a9f47d1 100644 --- a/src/planner/linux/multi.rs +++ b/src/planner/linux/multi.rs @@ -36,7 +36,7 @@ impl Planner for LinuxMulti { }) } - fn describe( + fn settings( &self, ) -> Result, Box> { let Self { settings } = self; diff --git a/src/planner/mod.rs b/src/planner/mod.rs index 4d4d9d0..f3a2bf0 100644 --- a/src/planner/mod.rs +++ b/src/planner/mod.rs @@ -13,7 +13,7 @@ pub trait Planner: std::fmt::Debug + Send + Sync + dyn_clone::DynClone { where Self: Sized; async fn plan(self) -> Result>; - fn describe( + fn settings( &self, ) -> Result, Box>; fn boxed(self) -> Box diff --git a/src/planner/specific/steam_deck.rs b/src/planner/specific/steam_deck.rs index 99ee2bc..9ad73a0 100644 --- a/src/planner/specific/steam_deck.rs +++ b/src/planner/specific/steam_deck.rs @@ -36,7 +36,7 @@ impl Planner for SteamDeck { }) } - fn describe( + fn settings( &self, ) -> Result, Box> { let Self { settings } = self;