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 list;
|
||||||
pub mod rate;
|
pub mod rate;
|
||||||
pub mod recovery_qr;
|
pub mod recovery_qr;
|
||||||
|
pub mod settings;
|
||||||
pub mod status;
|
pub mod status;
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
pub mod trash;
|
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 { length, bip39, words, symbols, separator } => {
|
||||||
commands::generate::cmd_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::Sync => commands::sync::cmd_sync(),
|
||||||
Commands::Status => commands::status::cmd_status(),
|
Commands::Status => commands::status::cmd_status(),
|
||||||
Commands::Lock => { eprintln!("no cached session to lock"); Ok(()) }
|
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 ─────────────────────────────────────────────────────────
|
// ── Device management ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
/// Build a `GiteaClient` from flags or environment variables.
|
/// Build a `GiteaClient` from flags or environment variables.
|
||||||
|
|||||||
Reference in New Issue
Block a user