diff --git a/workshop-baker/src/prebake.rs b/workshop-baker/src/prebake.rs index b214ee0..a902a58 100644 --- a/workshop-baker/src/prebake.rs +++ b/workshop-baker/src/prebake.rs @@ -154,7 +154,8 @@ pub async fn prebake( .map(|c| c.repology_endpoint) .unwrap_or(workshop_engine::RepologyEndpoint::Default); - let pm_name = dependencies.system + let pm_name = dependencies + .system .as_ref() .and_then(|sys| sys.keys().next().cloned()); diff --git a/workshop-baker/src/prebake/error.rs b/workshop-baker/src/prebake/error.rs index 2656f38..9581377 100644 --- a/workshop-baker/src/prebake/error.rs +++ b/workshop-baker/src/prebake/error.rs @@ -64,4 +64,4 @@ pub enum BootstrapError { #[error("Invalid bootstrap configuration: {0}")] InvalidConfig(String), - } +} diff --git a/workshop-baker/src/prebake/stage/bootstrap.rs b/workshop-baker/src/prebake/stage/bootstrap.rs index 104d725..d2c1fd5 100644 --- a/workshop-baker/src/prebake/stage/bootstrap.rs +++ b/workshop-baker/src/prebake/stage/bootstrap.rs @@ -57,7 +57,10 @@ pub async fn bootstrap( match BootstrapSource::parse(&raw) { BootstrapSource::Inline(script) => { if ctx.dry_run { - log::info!("[DRY_RUN] User provided inline bootstrap script:\n{}", script); + log::info!( + "[DRY_RUN] User provided inline bootstrap script:\n{}", + script + ); return Ok(()); } log::debug!("Using inline bootstrap script ({} bytes)", script.len()); @@ -86,13 +89,16 @@ pub async fn bootstrap( // Should support: checksum verification, retry, timeout. log::info!("Custom bootstrap from URL: {}", url); log::info!(" Target: {}", bootstrap_path.display()); - unimplemented!("HTTP bootstrap fetching requires bakerd-level network infrastructure"); + unimplemented!( + "HTTP bootstrap fetching requires bakerd-level network infrastructure" + ); } BootstrapSource::File(path) => { // Local file copy. This is the simplest case — we can implement // this directly without bakerd infrastructure. log::info!("Custom bootstrap from local file: {}", path); - tokio::fs::copy(&path, &bootstrap_path).await + tokio::fs::copy(&path, &bootstrap_path) + .await .map_err(BootstrapError::IOError)?; } } @@ -166,7 +172,8 @@ impl BootstrapSource { if let Some(name) = raw.strip_prefix("server://") { return BootstrapSource::Server(name.to_string()); } - if let Some(url) = raw.strip_prefix("https://") + if let Some(url) = raw + .strip_prefix("https://") .or_else(|| raw.strip_prefix("http://")) { return BootstrapSource::Http(url.to_string()); @@ -325,9 +332,7 @@ fn generate_bootstrap( /// /// Returns `Some(Box)` if a configured package manager is known, /// or `None` if no package manager is configured or recognized. -fn get_package_manager( - config: &PrebakeConfig, -) -> Option> { +fn get_package_manager(config: &PrebakeConfig) -> Option> { config .dependencies .as_ref() diff --git a/workshop-engine/src/pm.rs b/workshop-engine/src/pm.rs index dd0f746..3a7f8ef 100644 --- a/workshop-engine/src/pm.rs +++ b/workshop-engine/src/pm.rs @@ -14,7 +14,6 @@ pub trait PackageManager { /// Returns the name of the package manager. fn name(&self) -> &'static str; - /// Returns the binary name of the package manager. fn binary(&self) -> &'static str; @@ -24,7 +23,6 @@ pub trait PackageManager { /// Generates commands to install the specified packages. fn install(&self, package: &[String]) -> Vec; - /// Generates commands to change the primary mirror repository. fn change_mirror(&self, repo: &str, osinfo: Option<&Info>) -> Vec; @@ -42,7 +40,6 @@ pub fn all_managers() -> Vec> { ] } - pub fn select(manager: &str) -> Option> { all_managers().into_iter().find(|pm| pm.name() == manager) } diff --git a/workshop-engine/src/pm/apk.rs b/workshop-engine/src/pm/apk.rs index 7a5d2c4..cc439f5 100644 --- a/workshop-engine/src/pm/apk.rs +++ b/workshop-engine/src/pm/apk.rs @@ -73,10 +73,8 @@ impl PackageManager for Apk { // Download and trust GPG key if provided if let Some(key_url) = &repo_cfg.key_url { let mut cmd = Command::new("sh"); - cmd.arg("-c").arg(format!( - "wget -qO- '{}' | apk keys --stdin", - key_url - )); + cmd.arg("-c") + .arg(format!("wget -qO- '{}' | apk keys --stdin", key_url)); cmds.push(cmd); } @@ -87,10 +85,8 @@ impl PackageManager for Apk { format!("{}\n", repo_cfg.url) }; let mut cmd = Command::new("sh"); - cmd.arg("-c").arg(format!( - "echo '{}' >> /etc/apk/repositories", - line.trim() - )); + cmd.arg("-c") + .arg(format!("echo '{}' >> /etc/apk/repositories", line.trim())); cmds.push(cmd); } @@ -206,9 +202,7 @@ mod tests { ), ( serde_yaml::Value::String("key_url".to_string()), - serde_yaml::Value::String( - "https://example.com/alpine-key".to_string(), - ), + serde_yaml::Value::String("https://example.com/alpine-key".to_string()), ), ] .into_iter() @@ -238,8 +232,7 @@ mod tests { ( serde_yaml::Value::String("url".to_string()), serde_yaml::Value::String( - "https://dl-cdn.alpinelinux.org/alpine/v3.19/community" - .to_string(), + "https://dl-cdn.alpinelinux.org/alpine/v3.19/community".to_string(), ), ), ( diff --git a/workshop-engine/src/pm/apt.rs b/workshop-engine/src/pm/apt.rs index 02208ac..bbb54f4 100644 --- a/workshop-engine/src/pm/apt.rs +++ b/workshop-engine/src/pm/apt.rs @@ -209,9 +209,7 @@ fn extract_codename(info: Option<&Info>) -> Option { // 2. Try to infer from version string match info.version() { - Version::Custom(v) - if !v.chars().next().map(|c| c.is_numeric()).unwrap_or(true) - => { + Version::Custom(v) if !v.chars().next().map(|c| c.is_numeric()).unwrap_or(true) => { // Some systems put codename in Custom field return Some(v.clone()); } @@ -296,9 +294,7 @@ mod tests { [ ( serde_yaml::Value::String("url".to_string()), - serde_yaml::Value::String( - "https://repo.example.com/ubuntu".to_string(), - ), + serde_yaml::Value::String("https://repo.example.com/ubuntu".to_string()), ), ( serde_yaml::Value::String("distro".to_string()), @@ -340,9 +336,7 @@ mod tests { [ ( serde_yaml::Value::String("url".to_string()), - serde_yaml::Value::String( - "https://repo.example.com/ubuntu".to_string(), - ), + serde_yaml::Value::String("https://repo.example.com/ubuntu".to_string()), ), ( serde_yaml::Value::String("distro".to_string()), @@ -350,9 +344,7 @@ mod tests { ), ( serde_yaml::Value::String("key_url".to_string()), - serde_yaml::Value::String( - "https://repo.example.com/key.gpg".to_string(), - ), + serde_yaml::Value::String("https://repo.example.com/key.gpg".to_string()), ), ] .into_iter() @@ -377,8 +369,14 @@ mod tests { #[test] fn test_sanitize_repo_name() { - assert_eq!(sanitize_repo_name("https://example.com/repo"), "example.com_repo"); - assert_eq!(sanitize_repo_name("http://mirror.tuna.tsinghua.edu.cn/ubuntu"), "mirror.tuna.tsinghua.edu.cn_ubuntu"); + assert_eq!( + sanitize_repo_name("https://example.com/repo"), + "example.com_repo" + ); + assert_eq!( + sanitize_repo_name("http://mirror.tuna.tsinghua.edu.cn/ubuntu"), + "mirror.tuna.tsinghua.edu.cn_ubuntu" + ); assert_eq!(sanitize_repo_name("ppa:user/name"), "user_name"); } @@ -401,9 +399,7 @@ mod tests { serde_yaml::Value::Mapping( [( serde_yaml::Value::String("url".to_string()), - serde_yaml::Value::String( - "https://repo.example.com/ubuntu".to_string(), - ), + serde_yaml::Value::String("https://repo.example.com/ubuntu".to_string()), )] .into_iter() .collect(), diff --git a/workshop-engine/src/pm/dnf.rs b/workshop-engine/src/pm/dnf.rs index 18f5045..dc2ee86 100644 --- a/workshop-engine/src/pm/dnf.rs +++ b/workshop-engine/src/pm/dnf.rs @@ -96,17 +96,17 @@ impl PackageManager for Dnf { // Download and import the GPG key let mut key_cmd = Command::new("sh"); - key_cmd.arg("-c").arg(format!( - "rpm --import '{}'", - gpgkey - )); + key_cmd.arg("-c").arg(format!("rpm --import '{}'", gpgkey)); cmds.push(key_cmd); } else { content.push_str("gpgcheck=0\n"); } // Write the .repo file - let repo_path = format!("/etc/yum.repos.d/{}.repo", sanitize_repo_name(&repo_cfg.name)); + let repo_path = format!( + "/etc/yum.repos.d/{}.repo", + sanitize_repo_name(&repo_cfg.name) + ); let mut cmd = Command::new("sh"); cmd.arg("-c").arg(format!( "cat > '{}' << 'DNF_EOF'\n{}DNF_EOF", @@ -200,9 +200,7 @@ mod tests { ), ( serde_yaml::Value::String("baseurl".to_string()), - serde_yaml::Value::String( - "https://repo.example.com/fedora".to_string(), - ), + serde_yaml::Value::String("https://repo.example.com/fedora".to_string()), ), ] .into_iter() @@ -236,15 +234,11 @@ mod tests { ), ( serde_yaml::Value::String("baseurl".to_string()), - serde_yaml::Value::String( - "https://repo.example.com/fedora".to_string(), - ), + serde_yaml::Value::String("https://repo.example.com/fedora".to_string()), ), ( serde_yaml::Value::String("gpgkey".to_string()), - serde_yaml::Value::String( - "https://repo.example.com/gpg".to_string(), - ), + serde_yaml::Value::String("https://repo.example.com/gpg".to_string()), ), ] .into_iter() diff --git a/workshop-engine/src/pm/pacman.rs b/workshop-engine/src/pm/pacman.rs index 901fa13..691ea35 100644 --- a/workshop-engine/src/pm/pacman.rs +++ b/workshop-engine/src/pm/pacman.rs @@ -77,7 +77,6 @@ impl PackageManager for Pacman { "pacman" } - fn binary(&self) -> &'static str { "pacman" } @@ -198,7 +197,6 @@ mod tests { assert_eq!(pacman.binary(), "pacman"); } - #[test] fn test_update_command_contents() { let cmds = Pacman.update(); diff --git a/workshop-engine/src/types.rs b/workshop-engine/src/types.rs index 0f1c521..c1a77df 100644 --- a/workshop-engine/src/types.rs +++ b/workshop-engine/src/types.rs @@ -27,7 +27,6 @@ pub struct DeltaExecutionContext { pub timeout: Option, } - impl Default for ExecutionContext { fn default() -> Self { Self { diff --git a/workshop-engine/src/upm.rs b/workshop-engine/src/upm.rs index 49d0d18..b1d0979 100644 --- a/workshop-engine/src/upm.rs +++ b/workshop-engine/src/upm.rs @@ -47,7 +47,12 @@ pub trait UserPackageManager { /// Returns a list of all available user package managers. pub fn all_managers() -> Vec> { - vec![Box::new(rust::Rust), Box::new(python::Python), Box::new(go::Go), Box::new(custom::Custom)] + vec![ + Box::new(rust::Rust), + Box::new(python::Python), + Box::new(go::Go), + Box::new(custom::Custom), + ] } /// Selects a user package manager by name. diff --git a/workshop-engine/src/upm/go.rs b/workshop-engine/src/upm/go.rs index d92717d..3f25a7d 100644 --- a/workshop-engine/src/upm/go.rs +++ b/workshop-engine/src/upm/go.rs @@ -84,11 +84,7 @@ impl UserPackageManager for Go { for mod_path in &cfg.modules { let dir = mod_path.parent().unwrap_or(mod_path); let cmd = "go mod download".to_string(); - log::info!( - "Go UPM executing: cd {} && {}", - dir.display(), - cmd - ); + log::info!("Go UPM executing: cd {} && {}", dir.display(), cmd); let cd_delta = DeltaExecutionContext { working_dir: Some(dir.to_path_buf()), @@ -166,7 +162,10 @@ env: "#; let cfg: GoConfig = serde_yaml::from_str(yaml).unwrap(); assert_eq!(cfg.proxy.as_deref(), Some("https://goproxy.cn,direct")); - assert_eq!(cfg.packages, vec!["honnef.co/go/tools/cmd/staticcheck@latest"]); + assert_eq!( + cfg.packages, + vec!["honnef.co/go/tools/cmd/staticcheck@latest"] + ); assert_eq!(cfg.modules, vec![PathBuf::from("/workspace/server/go.mod")]); assert_eq!( cfg.env_.get("GOMODCACHE").and_then(|v| v.as_deref()), diff --git a/workshop-engine/src/upm/python.rs b/workshop-engine/src/upm/python.rs index 6a8617c..52de6ca 100644 --- a/workshop-engine/src/upm/python.rs +++ b/workshop-engine/src/upm/python.rs @@ -123,11 +123,10 @@ impl UserPackageManager for Python { ctx: &ExecutionContext, event_tx: &EventSender, ) -> Result<(), DependencyError> { - let cfg: PythonConfig = - serde_yaml::from_value(config.clone()).map_err(|e| { - log::error!("Failed to parse user.python config: {}", e); - DependencyError::ParseError() - })?; + let cfg: PythonConfig = serde_yaml::from_value(config.clone()).map_err(|e| { + log::error!("Failed to parse user.python config: {}", e); + DependencyError::ParseError() + })?; let engine = Engine::new(); @@ -152,8 +151,7 @@ impl Python { // ── 1. venv ────────────────────────────────────────────── if let Some(ref dir) = action.directory { - let venv_cmd = - format!("{} -m venv '{}'", python_bin(action), dir.display()); + let venv_cmd = format!("{} -m venv '{}'", python_bin(action), dir.display()); log::info!("Python UPM creating venv: {}", venv_cmd); let r = engine .execute_command_with_delta(&venv_cmd, ctx, event_tx, &delta) diff --git a/workshop-engine/src/upm/rust.rs b/workshop-engine/src/upm/rust.rs index e180ff0..aea5f86 100644 --- a/workshop-engine/src/upm/rust.rs +++ b/workshop-engine/src/upm/rust.rs @@ -1,10 +1,10 @@ +use crate::error::DependencyError; +use crate::types::{DeltaExecutionContext, Engine, EventSender, ExecutionContext}; +use crate::upm::UPMSysDeps; use async_trait::async_trait; use serde::Deserialize; use std::collections::HashMap; use std::path::PathBuf; -use crate::error::DependencyError; -use crate::types::{DeltaExecutionContext, Engine, EventSender, ExecutionContext}; -use crate::upm::UPMSysDeps; use super::UserPackageManager; @@ -67,7 +67,9 @@ struct RustConfig { cargo: CargoSubConfig, } -fn default_rust_type() -> String { "rustup".to_string() } +fn default_rust_type() -> String { + "rustup".to_string() +} // ── Cargo sub-config ─────────────────────────────────────────────── @@ -134,18 +136,12 @@ impl UserPackageManager for Rust { // ── 2. rustup component add ────────────────────── if !cfg.components.is_empty() { - commands.push(format!( - "rustup component add {}", - cfg.components.join(" ") - )); + commands.push(format!("rustup component add {}", cfg.components.join(" "))); } // ── 3. rustup target add ─────────────────────── if !cfg.targets.is_empty() { - commands.push(format!( - "rustup target add {}", - cfg.targets.join(" ") - )); + commands.push(format!("rustup target add {}", cfg.targets.join(" "))); } // ── 4. cargo fetch ─────────────────────────────────────── @@ -161,11 +157,7 @@ impl UserPackageManager for Rust { } for manifest in &cargo.manifests { // Host target (no --target) - commands.push(format!( - "{} --manifest-path '{}'", - base, - manifest.display() - )); + commands.push(format!("{} --manifest-path '{}'", base, manifest.display())); // Cross-compilation targets for target in &cfg.targets { commands.push(format!(