WP-11: contract and failing tests for package upgrades
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@ -53,3 +53,17 @@ impl Inventory {
|
||||
.count()
|
||||
}
|
||||
}
|
||||
|
||||
/// Debian package names: lowercase letters, digits, `+`, `-`, `.`; at least two characters.
|
||||
pub fn validate_package_name(name: &str) -> Result<(), crate::DomainError> {
|
||||
let ok = name.len() >= 2
|
||||
&& name
|
||||
.chars()
|
||||
.next()
|
||||
.is_some_and(|c| c.is_ascii_lowercase() || c.is_ascii_digit())
|
||||
&& name
|
||||
.chars()
|
||||
.all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || matches!(c, '+' | '-' | '.'));
|
||||
ok.then_some(())
|
||||
.ok_or_else(|| crate::DomainError::Validation(format!("invalid package name: {name}")))
|
||||
}
|
||||
|
||||
@ -90,3 +90,14 @@ pub trait InventoryRepository: Send + Sync {
|
||||
async fn save(&self, inventory: &Inventory) -> Result<(), DomainError>;
|
||||
async fn load(&self) -> Result<Option<Inventory>, DomainError>;
|
||||
}
|
||||
|
||||
/// Synchronous sink for streamed command output.
|
||||
pub trait LineSink: Send + Sync {
|
||||
fn line(&self, text: &str);
|
||||
}
|
||||
|
||||
/// Applies package upgrades on the host. An empty package list upgrades everything.
|
||||
#[async_trait]
|
||||
pub trait HostUpdater: Send + Sync {
|
||||
async fn upgrade(&self, packages: &[String], out: &dyn LineSink) -> Result<(), DomainError>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user