cli: write groups.cache for shell-completion --group enumeration
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -83,6 +83,38 @@ pub fn humanize_age(seconds: i64) -> String {
|
||||
|
||||
fn plural(n: i64) -> &'static str { if n == 1 { "" } else { "s" } }
|
||||
|
||||
/// Path to the plaintext `groups.cache` file used by shell completion to
|
||||
/// enumerate `--group <TAB>` candidates without unlocking the vault.
|
||||
///
|
||||
/// **Plaintext leak:** group names land on disk in cleartext alongside the
|
||||
/// vault directory. This is intentional — the file feeds shell completion,
|
||||
/// which cannot prompt for a passphrase. Set `RELICARIO_NO_GROUPS_CACHE=1`
|
||||
/// to suppress the write.
|
||||
pub fn groups_cache_path(vault_dir: &Path) -> PathBuf {
|
||||
vault_dir.join(".relicario").join("groups.cache")
|
||||
}
|
||||
|
||||
/// Write the sorted set of group names to `<vault_dir>/.relicario/groups.cache`,
|
||||
/// one name per line. A no-op if `RELICARIO_NO_GROUPS_CACHE` is set.
|
||||
pub fn write_groups_cache(
|
||||
vault_dir: &Path,
|
||||
groups: &std::collections::BTreeSet<String>,
|
||||
) -> std::io::Result<()> {
|
||||
if std::env::var_os("RELICARIO_NO_GROUPS_CACHE").is_some() {
|
||||
return Ok(());
|
||||
}
|
||||
let path = groups_cache_path(vault_dir);
|
||||
if let Some(parent) = path.parent() {
|
||||
std::fs::create_dir_all(parent)?;
|
||||
}
|
||||
let mut body = String::new();
|
||||
for g in groups {
|
||||
body.push_str(g);
|
||||
body.push('\n');
|
||||
}
|
||||
std::fs::write(path, body)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user