refactor(cli): move cmd_settings into commands/settings.rs
This commit is contained in:
@@ -15,6 +15,7 @@ pub mod init;
|
||||
pub mod list;
|
||||
pub mod rate;
|
||||
pub mod recovery_qr;
|
||||
pub mod settings;
|
||||
pub mod status;
|
||||
pub mod sync;
|
||||
pub mod trash;
|
||||
|
||||
98
crates/relicario-cli/src/commands/settings.rs
Normal file
98
crates/relicario-cli/src/commands/settings.rs
Normal file
@@ -0,0 +1,98 @@
|
||||
//! `relicario settings {show, trash-retention, history-retention, attachment-cap, generator-defaults}`.
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::SettingsAction;
|
||||
|
||||
pub fn cmd_settings(action: SettingsAction) -> Result<()> {
|
||||
use relicario_core::{
|
||||
Capitalization, CharClasses, GeneratorRequest, HistoryRetention,
|
||||
SymbolCharset, TrashRetention,
|
||||
};
|
||||
|
||||
let vault = crate::session::UnlockedVault::unlock_interactive()?;
|
||||
let mut settings = vault.load_settings()?;
|
||||
|
||||
match action {
|
||||
SettingsAction::Show => {
|
||||
println!("{}", serde_json::to_string_pretty(&settings)?);
|
||||
return Ok(());
|
||||
}
|
||||
SettingsAction::TrashRetention { days, forever } => {
|
||||
settings.trash_retention = match (days, forever) {
|
||||
(Some(d), false) => TrashRetention::Days(d),
|
||||
(None, true) => TrashRetention::Forever,
|
||||
_ => anyhow::bail!("specify exactly one of --days or --forever"),
|
||||
};
|
||||
}
|
||||
SettingsAction::HistoryRetention { last_n, days, forever } => {
|
||||
settings.field_history_retention = match (last_n, days, forever) {
|
||||
(Some(n), None, false) => HistoryRetention::LastN(n),
|
||||
(None, Some(d), false) => HistoryRetention::Days(d),
|
||||
(None, None, true) => HistoryRetention::Forever,
|
||||
_ => anyhow::bail!("specify exactly one of --last-n / --days / --forever"),
|
||||
};
|
||||
}
|
||||
SettingsAction::AttachmentCap {
|
||||
per_attachment_max_bytes, per_item_max_count,
|
||||
per_vault_soft_cap_bytes, per_vault_hard_cap_bytes,
|
||||
} => {
|
||||
if let Some(v) = per_attachment_max_bytes { settings.attachment_caps.per_attachment_max_bytes = v; }
|
||||
if let Some(v) = per_item_max_count { settings.attachment_caps.per_item_max_count = v; }
|
||||
if let Some(v) = per_vault_soft_cap_bytes { settings.attachment_caps.per_vault_soft_cap_bytes = v; }
|
||||
if let Some(v) = per_vault_hard_cap_bytes { settings.attachment_caps.per_vault_hard_cap_bytes = v; }
|
||||
}
|
||||
SettingsAction::GeneratorDefaults {
|
||||
random, bip39, length, words, symbols, separator,
|
||||
} => {
|
||||
// Decide target mode: explicit flag wins, else preserve current.
|
||||
let target_bip39 = if random { false }
|
||||
else if bip39 { true }
|
||||
else { matches!(settings.generator_defaults, GeneratorRequest::Bip39 { .. }) };
|
||||
|
||||
// Pull existing fields where compatible, else seed with sensible
|
||||
// defaults (kept in sync with `GeneratorRequest::default()`).
|
||||
let (cur_length, cur_classes, cur_charset) = match &settings.generator_defaults {
|
||||
GeneratorRequest::Random { length, classes, symbol_charset } => {
|
||||
(*length, *classes, symbol_charset.clone())
|
||||
}
|
||||
_ => (
|
||||
20,
|
||||
CharClasses { lower: true, upper: true, digits: true, symbols: true },
|
||||
SymbolCharset::SafeOnly,
|
||||
),
|
||||
};
|
||||
let (cur_words, cur_sep, cur_cap) = match &settings.generator_defaults {
|
||||
GeneratorRequest::Bip39 { word_count, separator, capitalization } => {
|
||||
(*word_count, separator.clone(), *capitalization)
|
||||
}
|
||||
_ => (5, " ".to_string(), Capitalization::Lower),
|
||||
};
|
||||
|
||||
settings.generator_defaults = if target_bip39 {
|
||||
GeneratorRequest::Bip39 {
|
||||
word_count: words.unwrap_or(cur_words),
|
||||
separator: separator.unwrap_or(cur_sep),
|
||||
capitalization: cur_cap,
|
||||
}
|
||||
} else {
|
||||
let charset = match symbols.as_deref() {
|
||||
None => cur_charset,
|
||||
Some("safe") => SymbolCharset::SafeOnly,
|
||||
Some("extended") => SymbolCharset::Extended,
|
||||
Some(other) => SymbolCharset::Custom(other.to_string()),
|
||||
};
|
||||
GeneratorRequest::Random {
|
||||
length: length.unwrap_or(cur_length),
|
||||
classes: cur_classes,
|
||||
symbol_charset: charset,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
vault.save_settings(&settings)?;
|
||||
super::commit_paths(&vault, "settings: update", &["settings.enc"])?;
|
||||
eprintln!("Settings updated.");
|
||||
Ok(())
|
||||
}
|
||||
@@ -446,7 +446,7 @@ fn main() -> Result<()> {
|
||||
Commands::Generate { length, bip39, words, symbols, separator } => {
|
||||
commands::generate::cmd_generate(length, bip39, words, symbols, separator)
|
||||
}
|
||||
Commands::Settings { action } => cmd_settings(action),
|
||||
Commands::Settings { action } => commands::settings::cmd_settings(action),
|
||||
Commands::Sync => commands::sync::cmd_sync(),
|
||||
Commands::Status => commands::status::cmd_status(),
|
||||
Commands::Lock => { eprintln!("no cached session to lock"); Ok(()) }
|
||||
@@ -979,98 +979,6 @@ fn push_history(
|
||||
});
|
||||
}
|
||||
|
||||
fn cmd_settings(action: SettingsAction) -> Result<()> {
|
||||
use relicario_core::{
|
||||
Capitalization, CharClasses, GeneratorRequest, HistoryRetention,
|
||||
SymbolCharset, TrashRetention,
|
||||
};
|
||||
|
||||
let vault = crate::session::UnlockedVault::unlock_interactive()?;
|
||||
let mut settings = vault.load_settings()?;
|
||||
|
||||
match action {
|
||||
SettingsAction::Show => {
|
||||
println!("{}", serde_json::to_string_pretty(&settings)?);
|
||||
return Ok(());
|
||||
}
|
||||
SettingsAction::TrashRetention { days, forever } => {
|
||||
settings.trash_retention = match (days, forever) {
|
||||
(Some(d), false) => TrashRetention::Days(d),
|
||||
(None, true) => TrashRetention::Forever,
|
||||
_ => anyhow::bail!("specify exactly one of --days or --forever"),
|
||||
};
|
||||
}
|
||||
SettingsAction::HistoryRetention { last_n, days, forever } => {
|
||||
settings.field_history_retention = match (last_n, days, forever) {
|
||||
(Some(n), None, false) => HistoryRetention::LastN(n),
|
||||
(None, Some(d), false) => HistoryRetention::Days(d),
|
||||
(None, None, true) => HistoryRetention::Forever,
|
||||
_ => anyhow::bail!("specify exactly one of --last-n / --days / --forever"),
|
||||
};
|
||||
}
|
||||
SettingsAction::AttachmentCap {
|
||||
per_attachment_max_bytes, per_item_max_count,
|
||||
per_vault_soft_cap_bytes, per_vault_hard_cap_bytes,
|
||||
} => {
|
||||
if let Some(v) = per_attachment_max_bytes { settings.attachment_caps.per_attachment_max_bytes = v; }
|
||||
if let Some(v) = per_item_max_count { settings.attachment_caps.per_item_max_count = v; }
|
||||
if let Some(v) = per_vault_soft_cap_bytes { settings.attachment_caps.per_vault_soft_cap_bytes = v; }
|
||||
if let Some(v) = per_vault_hard_cap_bytes { settings.attachment_caps.per_vault_hard_cap_bytes = v; }
|
||||
}
|
||||
SettingsAction::GeneratorDefaults {
|
||||
random, bip39, length, words, symbols, separator,
|
||||
} => {
|
||||
// Decide target mode: explicit flag wins, else preserve current.
|
||||
let target_bip39 = if random { false }
|
||||
else if bip39 { true }
|
||||
else { matches!(settings.generator_defaults, GeneratorRequest::Bip39 { .. }) };
|
||||
|
||||
// Pull existing fields where compatible, else seed with sensible
|
||||
// defaults (kept in sync with `GeneratorRequest::default()`).
|
||||
let (cur_length, cur_classes, cur_charset) = match &settings.generator_defaults {
|
||||
GeneratorRequest::Random { length, classes, symbol_charset } => {
|
||||
(*length, *classes, symbol_charset.clone())
|
||||
}
|
||||
_ => (
|
||||
20,
|
||||
CharClasses { lower: true, upper: true, digits: true, symbols: true },
|
||||
SymbolCharset::SafeOnly,
|
||||
),
|
||||
};
|
||||
let (cur_words, cur_sep, cur_cap) = match &settings.generator_defaults {
|
||||
GeneratorRequest::Bip39 { word_count, separator, capitalization } => {
|
||||
(*word_count, separator.clone(), *capitalization)
|
||||
}
|
||||
_ => (5, " ".to_string(), Capitalization::Lower),
|
||||
};
|
||||
|
||||
settings.generator_defaults = if target_bip39 {
|
||||
GeneratorRequest::Bip39 {
|
||||
word_count: words.unwrap_or(cur_words),
|
||||
separator: separator.unwrap_or(cur_sep),
|
||||
capitalization: cur_cap,
|
||||
}
|
||||
} else {
|
||||
let charset = match symbols.as_deref() {
|
||||
None => cur_charset,
|
||||
Some("safe") => SymbolCharset::SafeOnly,
|
||||
Some("extended") => SymbolCharset::Extended,
|
||||
Some(other) => SymbolCharset::Custom(other.to_string()),
|
||||
};
|
||||
GeneratorRequest::Random {
|
||||
length: length.unwrap_or(cur_length),
|
||||
classes: cur_classes,
|
||||
symbol_charset: charset,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
vault.save_settings(&settings)?;
|
||||
commit_paths(&vault, "settings: update", &["settings.enc"])?;
|
||||
eprintln!("Settings updated.");
|
||||
Ok(())
|
||||
}
|
||||
// ── Device management ─────────────────────────────────────────────────────────
|
||||
|
||||
/// Build a `GiteaClient` from flags or environment variables.
|
||||
|
||||
Reference in New Issue
Block a user