use config::Config; use error::{AppError, AppResult}; use scripting::{ loader::{HookType, ScriptLoader}, script::{NuScript, Script}, }; use tasks::*; pub mod config; pub mod error; pub(crate) mod scripting; pub mod tasks; pub(crate) mod utils; pub use utils::generate_script_files; macro_rules! tasks { ($($function:ident => $script:ident),+) => { $( #[tracing::instrument(level = "trace", skip(self))] pub async fn $function(&self, cfg: <$script as crate::scripting::script::Script>::Args) -> AppResult<()> { self.execute_task::<$script>(cfg).await } )+ } } pub struct TaskExecutor { config: Option, loader: ScriptLoader, } impl TaskExecutor { /// Creates a new task executor with a given config pub fn with_config(config: Config) -> Self { Self { config: Some(config), loader: ScriptLoader::new(), } } tasks!( setup_users => SetupUsersScript, configure_network => ConfigureNetworkScript, configure_unakite => ConfigureUnakiteScript, create_partitions => CreatePartitionsScript, install_base => InstallBaseScript, install_bootloader => InstallBootloaderScript, install_desktop => InstallDesktopScript, install_extra_packages => InstallExtraPackagesScript, install_flatpak => InstallFlatpakScript, install_kernels => InstallKernelsScript, install_timeshift => InstallTimeshiftScript, install_zramd => InstallZRamDScript, setup_root_user => SetupRootUserScript, configure_locale => ConfigureLocaleScript ); /// Installs the system from the given system configuration #[tracing::instrument(level = "trace", skip(self))] pub async fn install_from_config(&self) -> AppResult<()> { let config = self.config.clone().ok_or_else(|| AppError::MissingConfig)?; self.create_partitions(config.partitions).await?; self.install_base(()).await?; self.install_kernels(config.kernels).await?; self.install_bootloader(config.bootloader).await?; self.configure_locale(config.locale).await?; self.configure_network(config.network).await?; if config.enable_zramd { self.install_zramd(()).await?; } if config.enable_timeshift { self.install_timeshift(()).await?; } if config.enable_flatpak { self.install_flatpak(()).await?; } self.setup_users(config.users).await?; self.setup_root_user(config.root_user).await?; self.install_desktop(config.desktop).await?; self.install_extra_packages(config.extra_packages).await?; if let Some(unakite) = config.unakite { self.configure_unakite(unakite).await?; } Ok(()) } async fn execute_task(&self, args: S::Args) -> AppResult<()> { if let Some(pre_hook) = self.loader.load_hook::(HookType::Pre) { self.execute(pre_hook, args.clone()).await?; } let script = self.loader.load::()?; if let Some(post_hook) = self.loader.load_hook::(HookType::Post) { self.execute(script, args.clone()).await?; self.execute(post_hook, args).await?; } else { self.execute(script, args.clone()).await?; } Ok(()) } #[inline] async fn execute(&self, mut script: NuScript, args: S::Args) -> AppResult<()> { if let Some(cfg) = self.config.as_ref() { script.set_global_var("TRM_CONFIG", cfg.to_owned()) } else { script.set_global_var("TRM_CONFIG", Config::empty()) } .set_global_var("TRM_VERSION", env!("CARGO_PKG_VERSION")) .execute(args) .await } } impl Default for TaskExecutor { fn default() -> Self { Self { loader: ScriptLoader::new(), config: None, } } }