use crate::locking::package_coordinate::PackageCoordinate;
use crate::paths::locking::{cache_lock_path, install_lock_path, locks_root};
use std::fmt;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LockKind {
Shared,
Exclusive,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum LockScope {
Installation { coordinate: PackageCoordinate },
CacheWriter,
GlobalConfig,
}
impl LockScope {
pub fn installation(coordinate: PackageCoordinate) -> Self {
Self::Installation { coordinate }
}
pub fn lock_path(&self, kopi_home: &Path) -> PathBuf {
match self {
LockScope::Installation { coordinate } => install_lock_path(
kopi_home,
coordinate.distribution(),
coordinate.slug().as_ref(),
),
LockScope::CacheWriter => cache_lock_path(kopi_home),
LockScope::GlobalConfig => locks_root(kopi_home).join("config.lock"),
}
}
pub fn lock_kind(&self) -> LockKind {
match self {
LockScope::Installation { .. } | LockScope::CacheWriter | LockScope::GlobalConfig => {
LockKind::Exclusive
}
}
}
pub fn label(&self) -> String {
match self {
LockScope::Installation { coordinate } => {
format!("installation {}", coordinate.slug())
}
LockScope::CacheWriter => "cache writer".to_string(),
LockScope::GlobalConfig => "global configuration".to_string(),
}
}
}
impl fmt::Display for LockScope {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.label())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::locking::PackageKind;
use std::path::Path;
#[test]
fn installation_scope_uses_slugged_path() {
let coordinate =
PackageCoordinate::new("Temurin", 21, PackageKind::Jdk).with_architecture(Some("x64"));
let home = Path::new("/tmp/kopi");
let path = LockScope::installation(coordinate).lock_path(home);
assert_eq!(
path,
Path::new("/tmp/kopi/locks/install/temurin/temurin-21-jdk-x64.lock")
);
}
#[test]
fn cache_scope_uses_shared_path() {
let home = Path::new("/tmp/kopi");
let path = LockScope::CacheWriter.lock_path(home);
assert_eq!(path, Path::new("/tmp/kopi/locks/cache.lock"));
}
#[test]
fn labels_are_human_readable() {
let coordinate = PackageCoordinate::new("Temurin", 21, PackageKind::Jdk);
let install_scope = LockScope::installation(coordinate);
assert!(install_scope.label().contains("installation"));
assert_eq!(LockScope::CacheWriter.label(), "cache writer");
assert_eq!(LockScope::GlobalConfig.label(), "global configuration");
}
}