Add updates.warn_cache_age config option (#492)

This is useful when the cache is managed externally, e.g. provisioned
from a Nix store path or by a package manager, where the directory's
mtime doesn't reflect the cache's real age, causing a spurious warning
on every invocation. Today the only way to silence it is `--quiet`,
which must be passed every call and hides all other output too.
This commit is contained in:
Nikolaos Karaolidis 2026-07-07 13:24:06 +01:00 committed by GitHub
commit f8a2003bc2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 63 additions and 10 deletions

View file

@ -30,6 +30,18 @@ auto_update = true
auto_update_interval_hours = 24
```
### `warn_cache_age`
Controls when a warning is printed if the cache has not been updated in a while.
By default, the warning is shown once the cache is older than 30 days. Set this
to `"never"` to silence the warning. This is useful if, for some reason, the
modification time does not reflect its actual age.
```toml
[updates]
warn_cache_age = "never"
```
## Download configuration
### `download_languages`

View file

@ -228,6 +228,17 @@ fn default_archive_source() -> String {
"https://github.com/tldr-pages/tldr/releases/latest/download".to_owned()
}
/// Controls when a warning about an outdated cache is printed.
///
/// Currently, the only nameable option is `"never"`. In the future, this may
/// be extended to also accept a duration (e.g. `"60d"`), after which the
/// warning should be shown.
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
enum RawWarnCacheAge {
Never,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
struct RawUpdatesConfig {
#[serde(default)]
@ -240,6 +251,8 @@ struct RawUpdatesConfig {
pub tls_backend: RawTlsBackend,
#[serde(default)]
pub download_languages: Option<Vec<String>>,
#[serde(default)]
pub warn_cache_age: Option<RawWarnCacheAge>,
}
impl Default for RawUpdatesConfig {
@ -250,6 +263,7 @@ impl Default for RawUpdatesConfig {
archive_source: default_archive_source(),
tls_backend: RawTlsBackend::default(),
download_languages: None,
warn_cache_age: None,
}
}
}
@ -380,6 +394,7 @@ pub struct UpdatesConfig<'a> {
pub archive_source: &'a str,
pub tls_backend: TlsBackend,
pub download_languages: Vec<Language<'a>>,
pub warn_cache_age: Option<Duration>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
@ -569,6 +584,10 @@ impl<'a> Config<'a> {
|| search.languages.clone(),
|languages| languages.iter().map(|lang| Language(lang)).collect(),
),
warn_cache_age: match raw_config.updates.warn_cache_age {
None => Some(MAX_CACHE_AGE),
Some(RawWarnCacheAge::Never) => None,
},
};
let relative_path_root = config_file_path

View file

@ -376,16 +376,18 @@ fn try_main(args: Cli, enable_styles: bool) -> Result<ExitCode> {
return Ok(ExitCode::FAILURE);
};
let age = cache.age()?;
if age > config::MAX_CACHE_AGE && !args.quiet {
print_warning(
enable_styles,
&format!(
"The cache hasn't been updated for {} days.\n\
You should probably run `tldr --update` soon.",
age.as_secs() / 24 / 3600
),
);
if let Some(max_cache_age) = config.updates.warn_cache_age {
let age = cache.age()?;
if age > max_cache_age && !args.quiet {
print_warning(
enable_styles,
&format!(
"The cache hasn't been updated for {} days.\n\
You should probably run `tldr --update` soon.",
age.as_secs() / 24 / 3600
),
);
}
}
cache

View file

@ -493,6 +493,26 @@ fn test_quiet_old_cache() {
.stderr(contains("The cache hasn't been updated for ").not());
}
#[test]
fn test_warn_cache_age_never() {
let testenv = TestEnv::new().install_default_cache();
filetime::set_file_mtime(
testenv.cache_dir().join(TLDR_PAGES_DIR),
filetime::FileTime::from_unix_time(1, 0),
)
.unwrap();
testenv.append_to_config("[updates]\nwarn_cache_age = \"never\"\n");
testenv
.command()
.args(["which"])
.assert()
.success()
.stderr(contains("The cache hasn't been updated for ").not());
}
#[cfg_attr(feature = "ignore-online-tests", ignore = "online test")]
#[test]
fn test_create_cache_directory_path() {