WP-11: contract and failing tests for package upgrades
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / ui (push) Has been cancelled

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Dennis Nemec
2026-09-02 22:24:40 +02:00
parent b6ddb8889d
commit 1f56f015a2
18 changed files with 524 additions and 2 deletions

View File

@ -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}")))
}

View File

@ -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>;
}