Skip to content

Commit 8275713

Browse files
committed
Add CacheConfigs.cache_type_by_name to reduce boilerplate
1 parent 4abd35f commit 8275713

2 files changed

Lines changed: 62 additions & 81 deletions

File tree

src/cache/multilevel.rs

Lines changed: 13 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ use crate::cache::build_single_cache;
2525
use crate::cache::disk::DiskCache;
2626
use crate::cache::{Cache, CacheMode, CacheWrite, Storage};
2727
use crate::compiler::PreprocessorCacheEntry;
28-
#[cfg(any_cache_remote)]
29-
use crate::config::CacheType;
3028
use crate::config::{Config, PreprocessorCacheModeConfig, WriteErrorPolicy};
3129
use crate::errors::*;
3230

@@ -400,47 +398,21 @@ impl MultiLevelStorage {
400398
// Build remote cache - get the appropriate CacheType
401399
#[cfg(any_cache_remote)]
402400
{
403-
let cache_type = match level_name.to_lowercase().as_str() {
404-
#[cfg(feature = "s3")]
405-
"s3" => config.cache_configs.s3.clone().map(CacheType::S3),
406-
#[cfg(feature = "redis")]
407-
"redis" => config.cache_configs.redis.clone().map(CacheType::Redis),
408-
#[cfg(feature = "memcached")]
409-
"memcached" => config
410-
.cache_configs
411-
.memcached
412-
.clone()
413-
.map(CacheType::Memcached),
414-
#[cfg(feature = "gcs")]
415-
"gcs" => config.cache_configs.gcs.clone().map(CacheType::GCS),
416-
#[cfg(feature = "gha")]
417-
"gha" => config.cache_configs.gha.clone().map(CacheType::GHA),
418-
#[cfg(feature = "azure")]
419-
"azure" => config.cache_configs.azure.clone().map(CacheType::Azure),
420-
#[cfg(feature = "webdav")]
421-
"webdav" => config.cache_configs.webdav.clone().map(CacheType::Webdav),
422-
#[cfg(feature = "oss")]
423-
"oss" => config.cache_configs.oss.clone().map(CacheType::OSS),
424-
#[cfg(feature = "cos")]
425-
"cos" => config.cache_configs.cos.clone().map(CacheType::COS),
426-
_ => {
427-
return Err(anyhow!("Unknown cache level: '{}'", level_name));
428-
}
429-
};
430-
431-
if let Some(cache_type) = cache_type {
432-
let storage = build_single_cache(&cache_type, &config.basedirs, pool)
433-
.with_context(|| {
434-
format!("Failed to build cache for level '{}'", level_name)
435-
})?;
436-
storages.push(storage);
437-
trace!("Added cache level: {}", level_name);
438-
} else {
439-
return Err(anyhow!(
401+
let level_lower = level_name.to_lowercase();
402+
let (_display_name, cache_type) =
403+
config.cache_configs.cache_type_by_name(&level_lower)?;
404+
let cache_type = cache_type.ok_or_else(|| {
405+
anyhow!(
440406
"Cache level '{}' specified in SCCACHE_MULTILEVEL_CHAIN but not configured (missing environment variables)",
441407
level_name
442-
));
443-
}
408+
)
409+
})?;
410+
let storage = build_single_cache(&cache_type, &config.basedirs, pool)
411+
.with_context(|| {
412+
format!("Failed to build cache for level '{}'", level_name)
413+
})?;
414+
storages.push(storage);
415+
trace!("Added cache level: {}", level_name);
444416
}
445417
#[cfg(not(any_cache_remote))]
446418
{

src/config.rs

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,40 @@ impl CacheConfigs {
537537
(cache_type, fallback)
538538
}
539539

540+
/// Look up a remote cache type by name (e.g. "s3", "gha").
541+
/// Returns `Ok((display_name, Some(..)))` if the name is known and configured,
542+
/// `Ok((display_name, None))` if known but not configured, `Err` if unknown.
543+
pub fn cache_type_by_name(&self, name: &str) -> Result<(&'static str, Option<CacheType>)> {
544+
match name {
545+
#[cfg(feature = "s3")]
546+
"s3" => Ok(("S3", self.s3.clone().map(CacheType::S3))),
547+
#[cfg(feature = "redis")]
548+
"redis" => Ok(("Redis", self.redis.clone().map(CacheType::Redis))),
549+
#[cfg(feature = "memcached")]
550+
"memcached" => Ok((
551+
"Memcached",
552+
self.memcached.clone().map(CacheType::Memcached),
553+
)),
554+
#[cfg(feature = "gcs")]
555+
"gcs" => Ok(("GCS", self.gcs.clone().map(CacheType::GCS))),
556+
#[cfg(feature = "gha")]
557+
"gha" => Ok(("GHA", self.gha.clone().map(CacheType::GHA))),
558+
#[cfg(feature = "azure")]
559+
"azure" => Ok(("Azure", self.azure.clone().map(CacheType::Azure))),
560+
#[cfg(feature = "webdav")]
561+
"webdav" => Ok(("WebDAV", self.webdav.clone().map(CacheType::Webdav))),
562+
#[cfg(feature = "oss")]
563+
"oss" => Ok(("OSS", self.oss.clone().map(CacheType::OSS))),
564+
#[cfg(feature = "cos")]
565+
"cos" => Ok(("COS", self.cos.clone().map(CacheType::COS))),
566+
_ => bail!(
567+
"Unknown cache level: '{}' (may require a feature flag, e.g. --features {})",
568+
name,
569+
name
570+
),
571+
}
572+
}
573+
540574
/// Get ordered list of cache types based on configured levels.
541575
/// If levels are specified, returns them in order with validation.
542576
/// If no levels specified and single remote cache, returns that single cache.
@@ -547,42 +581,17 @@ impl CacheConfigs {
547581
let mut caches = Vec::new();
548582
for level_name in &ml_config.chain {
549583
let level_name = level_name.trim();
550-
let cache_type = match level_name {
551-
"s3" => self.s3.clone().map(CacheType::S3).ok_or_else(|| {
552-
anyhow!("S3 cache not configured but specified in levels")
553-
})?,
554-
"redis" => self.redis.clone().map(CacheType::Redis).ok_or_else(|| {
555-
anyhow!("Redis cache not configured but specified in levels")
556-
})?,
557-
"memcached" => self
558-
.memcached
559-
.clone()
560-
.map(CacheType::Memcached)
561-
.ok_or_else(|| {
562-
anyhow!("Memcached cache not configured but specified in levels")
563-
})?,
564-
"gcs" => self.gcs.clone().map(CacheType::GCS).ok_or_else(|| {
565-
anyhow!("GCS cache not configured but specified in levels")
566-
})?,
567-
"gha" => self.gha.clone().map(CacheType::GHA).ok_or_else(|| {
568-
anyhow!("GHA cache not configured but specified in levels")
569-
})?,
570-
"azure" => self.azure.clone().map(CacheType::Azure).ok_or_else(|| {
571-
anyhow!("Azure cache not configured but specified in levels")
572-
})?,
573-
"webdav" => self.webdav.clone().map(CacheType::Webdav).ok_or_else(|| {
574-
anyhow!("Webdav cache not configured but specified in levels")
575-
})?,
576-
"oss" => self.oss.clone().map(CacheType::OSS).ok_or_else(|| {
577-
anyhow!("OSS cache not configured but specified in levels")
578-
})?,
579-
"disk" => {
580-
// Disk cache is handled separately in MultiLevelStorage::from_config
581-
// Mark it by continuing - it will be added to the storage list there
582-
continue;
583-
}
584-
_ => bail!("Unknown cache level: {}", level_name),
585-
};
584+
if level_name == "disk" {
585+
// Disk cache is handled separately in MultiLevelStorage::from_config
586+
continue;
587+
}
588+
let (display_name, cache_type) = self.cache_type_by_name(level_name)?;
589+
let cache_type = cache_type.ok_or_else(|| {
590+
anyhow!(
591+
"{} cache not configured but specified in levels",
592+
display_name
593+
)
594+
})?;
586595
caches.push(cache_type);
587596
}
588597
Ok(caches)
@@ -2858,10 +2867,10 @@ fn test_get_cache_levels_missing_config() {
28582867

28592868
let result = configs.get_cache_levels();
28602869
assert!(result.is_err());
2870+
let err = result.unwrap_err().to_string();
2871+
// With the s3 feature, we get "not configured"; without it, "unknown cache level"
28612872
assert!(
2862-
result
2863-
.unwrap_err()
2864-
.to_string()
2865-
.contains("S3 cache not configured")
2873+
err.contains("S3 cache not configured") || err.contains("Unknown cache level"),
2874+
"unexpected error: {err}"
28662875
);
28672876
}

0 commit comments

Comments
 (0)