mirror of
https://github.com/PR0M3TH3AN/Marlin.git
synced 2025-09-08 23:28:44 +00:00
Add backup prune CLI and update roadmap
This commit is contained in:
@@ -21,3 +21,4 @@
|
||||
| `version diff` | — |
|
||||
| `event add` | — |
|
||||
| `event timeline` | — |
|
||||
| `backup run` | --dir, --prune, --verify, --file |
|
||||
|
@@ -1,6 +1,7 @@
|
||||
// src/cli.rs
|
||||
|
||||
pub mod annotate;
|
||||
pub mod backup;
|
||||
pub mod coll;
|
||||
pub mod event;
|
||||
pub mod link;
|
||||
@@ -73,8 +74,8 @@ pub enum Commands {
|
||||
exec: Option<String>,
|
||||
},
|
||||
|
||||
/// Create a timestamped backup of the database
|
||||
Backup,
|
||||
/// Create or manage database backups
|
||||
Backup(backup::BackupOpts),
|
||||
|
||||
/// Restore from a backup file (overwrites current DB)
|
||||
Restore { backup_path: std::path::PathBuf },
|
||||
|
67
cli-bin/src/cli/backup.rs
Normal file
67
cli-bin/src/cli/backup.rs
Normal file
@@ -0,0 +1,67 @@
|
||||
// src/cli/backup.rs
|
||||
use crate::cli::Format;
|
||||
use anyhow::{Context, Result};
|
||||
use clap::Args;
|
||||
use libmarlin::backup::BackupManager;
|
||||
use rusqlite::Connection;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// Options for the `backup` command
|
||||
#[derive(Args, Debug)]
|
||||
pub struct BackupOpts {
|
||||
/// Directory to store backups (defaults next to DB)
|
||||
#[arg(long)]
|
||||
pub dir: Option<PathBuf>,
|
||||
|
||||
/// Keep only N newest backups
|
||||
#[arg(long)]
|
||||
pub prune: Option<usize>,
|
||||
|
||||
/// Verify a backup file
|
||||
#[arg(long)]
|
||||
pub verify: bool,
|
||||
|
||||
/// Backup file to verify (used with --verify)
|
||||
#[arg(long)]
|
||||
pub file: Option<PathBuf>,
|
||||
}
|
||||
|
||||
pub fn run(opts: &BackupOpts, db_path: &Path, _conn: &mut Connection, _fmt: Format) -> Result<()> {
|
||||
let backups_dir = opts
|
||||
.dir
|
||||
.clone()
|
||||
.unwrap_or_else(|| db_path.parent().unwrap().join("backups"));
|
||||
let manager = BackupManager::new(db_path, &backups_dir)?;
|
||||
|
||||
if opts.verify {
|
||||
let file = opts
|
||||
.file
|
||||
.as_ref()
|
||||
.context("--file required with --verify")?;
|
||||
let name = file
|
||||
.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.context("invalid backup file name")?;
|
||||
let ok = manager.verify_backup(name)?;
|
||||
if ok {
|
||||
println!("Backup OK: {}", name);
|
||||
} else {
|
||||
println!("Backup corrupted: {}", name);
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if let Some(n) = opts.prune {
|
||||
let result = manager.prune(n)?;
|
||||
println!(
|
||||
"Pruned {} old backups, kept {}",
|
||||
result.removed.len(),
|
||||
result.kept.len()
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let info = manager.create_backup()?;
|
||||
println!("Created backup {}", info.id);
|
||||
Ok(())
|
||||
}
|
@@ -79,3 +79,9 @@ event:
|
||||
add:
|
||||
args: [file, date, description]
|
||||
timeline: {}
|
||||
|
||||
backup:
|
||||
description: "Create, prune or verify backups"
|
||||
actions:
|
||||
run:
|
||||
flags: ["--dir", "--prune", "--verify", "--file"]
|
||||
|
@@ -41,7 +41,7 @@ fn main() -> Result<()> {
|
||||
let cfg = config::Config::load()?; // resolves DB path
|
||||
|
||||
match &args.command {
|
||||
Commands::Init | Commands::Backup | Commands::Restore { .. } => {}
|
||||
Commands::Init | Commands::Backup(_) | Commands::Restore { .. } => {}
|
||||
_ => match db::backup(&cfg.db_path) {
|
||||
Ok(p) => info!("Pre-command auto-backup created at {}", p.display()),
|
||||
Err(e) => error!("Failed to create pre-command auto-backup: {e}"),
|
||||
@@ -100,9 +100,8 @@ fn main() -> Result<()> {
|
||||
Commands::Search { query, exec } => run_search(&conn, &query, exec)?,
|
||||
|
||||
/* ---- maintenance ---------------------------------------- */
|
||||
Commands::Backup => {
|
||||
let p = db::backup(&cfg.db_path)?;
|
||||
println!("Backup created: {}", p.display());
|
||||
Commands::Backup(opts) => {
|
||||
cli::backup::run(&opts, &cfg.db_path, &mut conn, args.format)?;
|
||||
}
|
||||
|
||||
Commands::Restore { backup_path } => {
|
||||
|
Reference in New Issue
Block a user