mirror of
https://github.com/qwjyh/xdbm
synced 2024-11-22 06:40:12 +09:00
(WIP) new: implement status
subcommand
- Error while getting mount path of Storages - Need to redesign the API of LocalInfo or something
This commit is contained in:
parent
0abf9c0693
commit
37782c934c
4 changed files with 99 additions and 1 deletions
|
@ -44,6 +44,18 @@ pub(crate) enum Commands {
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
Backup(BackupSubCommands),
|
Backup(BackupSubCommands),
|
||||||
|
|
||||||
|
/// Print status for the given path.
|
||||||
|
Status {
|
||||||
|
/// Target path. Default is the current directory.
|
||||||
|
path: Option<PathBuf>,
|
||||||
|
/// Show storage which the path belongs to.
|
||||||
|
#[arg(short)]
|
||||||
|
storage: bool,
|
||||||
|
/// Show backup config covering the path.
|
||||||
|
#[arg(short)]
|
||||||
|
backup: bool,
|
||||||
|
},
|
||||||
|
|
||||||
/// Print config dir.
|
/// Print config dir.
|
||||||
Path {},
|
Path {},
|
||||||
|
|
||||||
|
|
81
src/cmd_status.rs
Normal file
81
src/cmd_status.rs
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use console::Style;
|
||||||
|
use std::{
|
||||||
|
env,
|
||||||
|
path::{self, Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
backups::Backups,
|
||||||
|
devices::{self, Device},
|
||||||
|
storages::{self, StorageExt, Storages},
|
||||||
|
util,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: fine styling like `backup list`, or should I just use the same style?
|
||||||
|
pub(crate) fn cmd_status(
|
||||||
|
path: Option<PathBuf>,
|
||||||
|
show_storage: bool,
|
||||||
|
show_backup: bool,
|
||||||
|
config_dir: &Path,
|
||||||
|
) -> Result<()> {
|
||||||
|
let path = path.unwrap_or(env::current_dir().context("Failed to get current directory.")?);
|
||||||
|
let device = devices::get_device(config_dir)?;
|
||||||
|
|
||||||
|
if show_storage {
|
||||||
|
let storages = storages::Storages::read(config_dir)?;
|
||||||
|
let storage = util::min_parent_storage(&path, &storages, &device);
|
||||||
|
|
||||||
|
match storage {
|
||||||
|
Some(storage) => {
|
||||||
|
println!("Storage: {}", storage.0.name())
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
println!("Storage: None");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if show_backup {
|
||||||
|
let devices = devices::get_devices(config_dir)?;
|
||||||
|
let storages = storages::Storages::read(config_dir)?;
|
||||||
|
let backups = Backups::read(config_dir, &device)?;
|
||||||
|
let covering_backup = devices
|
||||||
|
.iter()
|
||||||
|
.map(|device| (device, parent_backups(&path, &backups, &storages, device)));
|
||||||
|
|
||||||
|
for (backup_device, covering_backups) in covering_backup {
|
||||||
|
println!("Device: {}", backup_device.name());
|
||||||
|
for backup in covering_backups {
|
||||||
|
println!(" {}", console::style(backup.0).bold());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parent_backups<'a>(
|
||||||
|
target_path: &'a PathBuf,
|
||||||
|
backups: &'a Backups,
|
||||||
|
storages: &'a Storages,
|
||||||
|
device: &'a Device,
|
||||||
|
) -> Vec<(&'a String, PathBuf)> {
|
||||||
|
backups
|
||||||
|
.list
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(k, v)| {
|
||||||
|
let backup_path = match v.source().path(storages, device) {
|
||||||
|
Ok(path) => path,
|
||||||
|
Err(e) => {
|
||||||
|
error!("Error while getting backup source path: {}", e);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let diff = pathdiff::diff_paths(target_path, backup_path)?;
|
||||||
|
if diff.components().any(|c| c == path::Component::ParentDir) {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some((k, diff))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
|
@ -31,6 +31,7 @@ mod cmd_backup;
|
||||||
mod cmd_check;
|
mod cmd_check;
|
||||||
mod cmd_completion;
|
mod cmd_completion;
|
||||||
mod cmd_init;
|
mod cmd_init;
|
||||||
|
mod cmd_status;
|
||||||
mod cmd_storage;
|
mod cmd_storage;
|
||||||
mod cmd_sync;
|
mod cmd_sync;
|
||||||
mod devices;
|
mod devices;
|
||||||
|
@ -91,6 +92,11 @@ fn main() -> Result<()> {
|
||||||
println!("{}", &config_dir.display());
|
println!("{}", &config_dir.display());
|
||||||
}
|
}
|
||||||
Commands::Sync { remote_name } => cmd_sync::cmd_sync(&config_dir, remote_name)?,
|
Commands::Sync { remote_name } => cmd_sync::cmd_sync(&config_dir, remote_name)?,
|
||||||
|
Commands::Status {
|
||||||
|
path,
|
||||||
|
storage,
|
||||||
|
backup,
|
||||||
|
} => cmd_status::cmd_status(path, storage, backup, &config_dir)?,
|
||||||
Commands::Check {} => cmd_check::cmd_check(&config_dir)?,
|
Commands::Check {} => cmd_check::cmd_check(&config_dir)?,
|
||||||
Commands::Backup(backup) => {
|
Commands::Backup(backup) => {
|
||||||
trace!("backup subcommand with args: {:?}", backup);
|
trace!("backup subcommand with args: {:?}", backup);
|
||||||
|
|
|
@ -144,7 +144,6 @@ pub trait StorageExt {
|
||||||
fn local_info(&self, device: &devices::Device) -> Option<&local_info::LocalInfo>;
|
fn local_info(&self, device: &devices::Device) -> Option<&local_info::LocalInfo>;
|
||||||
|
|
||||||
/// Get mount path of `self` on `device`.
|
/// Get mount path of `self` on `device`.
|
||||||
/// `storages` is a `BTreeMap` with key of storage name and value of the storage.
|
|
||||||
fn mount_path(&self, device: &devices::Device) -> Result<path::PathBuf>;
|
fn mount_path(&self, device: &devices::Device) -> Result<path::PathBuf>;
|
||||||
|
|
||||||
/// Add local info of `device` to `self`.
|
/// Add local info of `device` to `self`.
|
||||||
|
|
Loading…
Reference in a new issue