use std::fs; use std::path::{Path, PathBuf}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Profile { pub packages: Vec, pub regex_packages: Vec, } impl Profile { pub fn load(path: &Path) -> Result { let profile = fs::read_to_string(path).map_err(|error| error.to_string())?; let parent = path.parent().ok_or("profile path has no parent")?; let mut packages = Vec::new(); let mut regex_packages = Vec::new(); for line in profile.lines() { let line = line.trim(); if line.is_empty() || line.starts_with('#') { continue; } if let Some(values) = line.strip_prefix("base:") { extend_words(&mut packages, values); } else if let Some(relative) = line.strip_prefix("include:") { let list = parent.join(relative.trim()); let contents = fs::read_to_string(&list) .map_err(|error| format!("{}: {error}", list.display()))?; for entry in contents.lines().map(str::trim) { if entry.is_empty() || entry.starts_with('#') { continue; } let package = entry.split('@').next().unwrap_or(entry).trim(); if !package.is_empty() { packages.push(package.to_owned()); } } } else if let Some(value) = line.strip_prefix("regex:") { regex_packages.push(value.trim().to_owned()); } else { return Err(format!("unsupported profile statement: {line}")); } } packages.sort(); packages.dedup(); regex_packages.sort(); regex_packages.dedup(); Ok(Self { packages, regex_packages }) } pub fn install_arguments(&self) -> Vec { self.regex_packages.iter().chain(self.packages.iter()).cloned().collect() } } fn extend_words(target: &mut Vec, values: &str) { target.extend(values.split_whitespace().map(str::to_owned)); } pub fn artifact_path(project: &Path) -> PathBuf { project.join("out/alt-controller-rootfs.tar") }