mirror of
https://github.com/qwjyh/xdbm
synced 2024-11-22 22:51:05 +09:00
Revert "refactor: separate subcommands"
This reverts commit 4502113e41
.
This commit is contained in:
parent
4502113e41
commit
5c83532719
4 changed files with 275 additions and 298 deletions
|
@ -1,80 +0,0 @@
|
||||||
use std::{path::{self, Path}, fs::File, io::{BufWriter, Write}};
|
|
||||||
use git2::Repository;
|
|
||||||
|
|
||||||
use anyhow::{Result, Context, anyhow};
|
|
||||||
|
|
||||||
use crate::{add_and_commit, full_status, set_device_name, devices::{Device, get_devices, write_devices, DEVICESFILE}};
|
|
||||||
|
|
||||||
pub fn cmd_init(repo_url: Option<String>, config_dir: &path::PathBuf) -> Result<()> {
|
|
||||||
let is_first_device: bool;
|
|
||||||
// get repo or initialize it
|
|
||||||
let repo = match repo_url {
|
|
||||||
Some(repo_url) => {
|
|
||||||
trace!("repo: {}", repo_url);
|
|
||||||
let repo = Repository::clone(&repo_url, &config_dir)?;
|
|
||||||
is_first_device = false;
|
|
||||||
repo
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
trace!("No repo provided");
|
|
||||||
println!("Initializing for the first device...");
|
|
||||||
|
|
||||||
// create repository
|
|
||||||
let repo = Repository::init(&config_dir)?;
|
|
||||||
|
|
||||||
// set up gitignore
|
|
||||||
{
|
|
||||||
let f = File::create(&config_dir.join(".gitignore"))?;
|
|
||||||
{
|
|
||||||
let mut buf = BufWriter::new(f);
|
|
||||||
buf.write("devname".as_bytes())?;
|
|
||||||
}
|
|
||||||
add_and_commit(&repo, Path::new(".gitignore"), "Add devname to gitignore.")?;
|
|
||||||
full_status(&repo)?;
|
|
||||||
}
|
|
||||||
is_first_device = true;
|
|
||||||
repo
|
|
||||||
}
|
|
||||||
};
|
|
||||||
full_status(&repo)?;
|
|
||||||
|
|
||||||
// set device name
|
|
||||||
let device = set_device_name()?;
|
|
||||||
|
|
||||||
// save devname
|
|
||||||
let devname_path = &config_dir.join("devname");
|
|
||||||
{
|
|
||||||
let f = File::create(devname_path)
|
|
||||||
.context("Failed to create a file to store local device name")?;
|
|
||||||
let writer = BufWriter::new(f);
|
|
||||||
serde_yaml::to_writer(writer, &device.name()).unwrap();
|
|
||||||
};
|
|
||||||
full_status(&repo)?;
|
|
||||||
|
|
||||||
// Add new device to devices.yml
|
|
||||||
{
|
|
||||||
let mut devices: Vec<Device> = if is_first_device {
|
|
||||||
vec![]
|
|
||||||
} else {
|
|
||||||
get_devices(&config_dir)?
|
|
||||||
};
|
|
||||||
trace!("devices: {:?}", devices);
|
|
||||||
if devices.iter().any(|x| x.name() == device.name()) {
|
|
||||||
return Err(anyhow!("device name is already used."));
|
|
||||||
}
|
|
||||||
devices.push(device.clone());
|
|
||||||
trace!("Devices: {:?}", devices);
|
|
||||||
write_devices(&config_dir, devices)?;
|
|
||||||
}
|
|
||||||
full_status(&repo)?;
|
|
||||||
|
|
||||||
// commit
|
|
||||||
add_and_commit(
|
|
||||||
&repo,
|
|
||||||
&Path::new(DEVICESFILE),
|
|
||||||
&format!("Add new devname: {}", &device.name()),
|
|
||||||
)?;
|
|
||||||
println!("Device added");
|
|
||||||
full_status(&repo)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
/// CLI arguments definition
|
|
||||||
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
|
||||||
use clap_verbosity_flag::Verbosity;
|
|
||||||
|
|
||||||
use crate::storages::StorageType;
|
|
||||||
|
|
||||||
#[derive(Parser)]
|
|
||||||
#[command(author, version, about, long_about = None)]
|
|
||||||
pub(crate) struct Cli {
|
|
||||||
#[command(subcommand)]
|
|
||||||
pub command: Commands,
|
|
||||||
|
|
||||||
#[command(flatten)]
|
|
||||||
pub verbose: Verbosity,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
|
||||||
pub(crate) enum Commands {
|
|
||||||
/// Initialize for this device.
|
|
||||||
/// Provide `repo_url` to use existing repository, otherwise this device will be configured as the
|
|
||||||
/// first device.
|
|
||||||
Init {
|
|
||||||
repo_url: Option<String>, // url?
|
|
||||||
},
|
|
||||||
|
|
||||||
/// Manage storages.
|
|
||||||
Storage(StorageArgs),
|
|
||||||
|
|
||||||
/// Print config dir.
|
|
||||||
Path {},
|
|
||||||
|
|
||||||
/// Sync with git repo.
|
|
||||||
Sync {},
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(clap::Args)]
|
|
||||||
#[command(args_conflicts_with_subcommands = true)]
|
|
||||||
pub(crate) struct StorageArgs {
|
|
||||||
#[command(subcommand)]
|
|
||||||
pub(crate) command: StorageCommands,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
|
||||||
pub(crate) enum StorageCommands {
|
|
||||||
/// Add new storage.
|
|
||||||
Add {
|
|
||||||
#[arg(value_enum)]
|
|
||||||
storage_type: StorageType,
|
|
||||||
|
|
||||||
// TODO: set this require and select matching disk for physical
|
|
||||||
#[arg(short, long, value_name = "PATH")]
|
|
||||||
path: Option<PathBuf>,
|
|
||||||
},
|
|
||||||
/// List all storages.
|
|
||||||
List {},
|
|
||||||
/// Add new device-specific name to existing storage.
|
|
||||||
/// For physical disk, the name is taken from system info automatically.
|
|
||||||
Bind { storage: String },
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn verify_cli() {
|
|
||||||
use clap::CommandFactory;
|
|
||||||
Cli::command().debug_assert()
|
|
||||||
}
|
|
|
@ -1,136 +0,0 @@
|
||||||
use std::{path::{self, Path}, collections::HashMap, io::ErrorKind};
|
|
||||||
|
|
||||||
use anyhow::{Result, Context, Ok};
|
|
||||||
use clap::{CommandFactory, error};
|
|
||||||
use git2::Repository;
|
|
||||||
use inquire::Text;
|
|
||||||
use sysinfo::{SystemExt, DiskExt};
|
|
||||||
|
|
||||||
use crate::{anyhow, StorageCommands, cmd_options::{StorageArgs, Cli}, storages::{Storage, get_storages, StorageType, physical_drive_partition::{select_physical_storage, select_sysinfo_disk}, self, write_storages, STORAGESFILE, StorageExt}, devices::get_device, ask_unique_name, add_and_commit};
|
|
||||||
|
|
||||||
pub fn cmd_storage(storage: StorageArgs, config_dir: &path::PathBuf) -> Result<()> {
|
|
||||||
let repo = Repository::open(&config_dir)
|
|
||||||
.context("Repository doesn't exist. Please run init to initialize the repository.")?;
|
|
||||||
trace!("repo state: {:?}", repo.state());
|
|
||||||
match storage.command {
|
|
||||||
StorageCommands::Add { storage_type, path } => {
|
|
||||||
trace!("Storage Add {:?}, {:?}", storage_type, path);
|
|
||||||
// Get storages
|
|
||||||
// let mut storages: Vec<Storage> = get_storages(&config_dir)?;
|
|
||||||
let mut storages: HashMap<String, Storage> = get_storages(&config_dir)?;
|
|
||||||
trace!("found storages: {:?}", storages);
|
|
||||||
|
|
||||||
let device = get_device(&config_dir)?;
|
|
||||||
let (key, storage) = match storage_type {
|
|
||||||
StorageType::Physical => {
|
|
||||||
// select storage
|
|
||||||
let (key, storage) = select_physical_storage(device, &storages)?;
|
|
||||||
println!("storage: {}: {:?}", key, storage);
|
|
||||||
(key, Storage::PhysicalStorage(storage))
|
|
||||||
}
|
|
||||||
StorageType::SubDirectory => {
|
|
||||||
if storages.is_empty() {
|
|
||||||
return Err(anyhow!(
|
|
||||||
"No storages found. Please add at least 1 physical storage first."
|
|
||||||
));
|
|
||||||
}
|
|
||||||
let path = path.unwrap_or_else(|| {
|
|
||||||
let mut cmd = Cli::command();
|
|
||||||
cmd.error(
|
|
||||||
error::ErrorKind::MissingRequiredArgument,
|
|
||||||
"<PATH> is required with sub-directory",
|
|
||||||
)
|
|
||||||
.exit();
|
|
||||||
});
|
|
||||||
trace!("SubDirectory arguments: path: {:?}", path);
|
|
||||||
// Nightly feature std::path::absolute
|
|
||||||
let path = path.canonicalize()?;
|
|
||||||
trace!("canonicalized: path: {:?}", path);
|
|
||||||
|
|
||||||
let key_name = ask_unique_name(&storages, "sub-directory".to_string())?;
|
|
||||||
let notes = Text::new("Notes for this sub-directory:").prompt()?;
|
|
||||||
let storage = storages::directory::Directory::try_from_device_path(
|
|
||||||
key_name.clone(),
|
|
||||||
path,
|
|
||||||
notes,
|
|
||||||
&device,
|
|
||||||
&storages,
|
|
||||||
)?;
|
|
||||||
(key_name, Storage::SubDirectory(storage))
|
|
||||||
}
|
|
||||||
StorageType::Online => todo!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// add to storages
|
|
||||||
storages.insert(key.clone(), storage);
|
|
||||||
trace!("updated storages: {:?}", storages);
|
|
||||||
|
|
||||||
// write to file
|
|
||||||
write_storages(&config_dir, storages)?;
|
|
||||||
|
|
||||||
// commit
|
|
||||||
add_and_commit(
|
|
||||||
&repo,
|
|
||||||
&Path::new(STORAGESFILE),
|
|
||||||
&format!("Add new storage(physical drive): {}", key),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
println!("Added new storage.");
|
|
||||||
trace!("Finished adding storage");
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
StorageCommands::List {} => {
|
|
||||||
// Get storages
|
|
||||||
let storages: HashMap<String, Storage> = get_storages(&config_dir)?;
|
|
||||||
trace!("found storages: {:?}", storages);
|
|
||||||
let device = get_device(&config_dir)?;
|
|
||||||
for (k, storage) in &storages {
|
|
||||||
println!("{}: {}", k, storage);
|
|
||||||
println!(" {}", storage.mount_path(&device, &storages)?.display());
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
StorageCommands::Bind {
|
|
||||||
storage: storage_name,
|
|
||||||
} => {
|
|
||||||
// get storages
|
|
||||||
let mut storages: HashMap<String, Storage> = get_storages(&config_dir)?;
|
|
||||||
let commit_comment = {
|
|
||||||
// find matching storage
|
|
||||||
let storage = storages
|
|
||||||
.get_mut(&storage_name)
|
|
||||||
.context(format!("No storage has name {}", storage_name))?;
|
|
||||||
// get disk from sysinfo
|
|
||||||
let mut sysinfo = sysinfo::System::new_all();
|
|
||||||
sysinfo.refresh_disks();
|
|
||||||
let disk = select_sysinfo_disk(&sysinfo)?;
|
|
||||||
let system_name = disk
|
|
||||||
.name()
|
|
||||||
.to_str()
|
|
||||||
.context("Failed to convert disk name to valid string")?;
|
|
||||||
// add to storages
|
|
||||||
storage.bind_device(disk, &config_dir)?;
|
|
||||||
trace!("storage: {}", storage);
|
|
||||||
format!("{} to {}", system_name, storage.name())
|
|
||||||
};
|
|
||||||
trace!("bound new system name to the storage");
|
|
||||||
trace!("storages: {:#?}", storages);
|
|
||||||
|
|
||||||
write_storages(&config_dir, storages)?;
|
|
||||||
// commit
|
|
||||||
add_and_commit(
|
|
||||||
&repo,
|
|
||||||
&Path::new(STORAGESFILE),
|
|
||||||
&format!(
|
|
||||||
"Bound new storage name to physical drive ({})",
|
|
||||||
commit_comment
|
|
||||||
),
|
|
||||||
)?;
|
|
||||||
println!(
|
|
||||||
"Bound new storage name to physical drive ({})",
|
|
||||||
commit_comment
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
289
src/main.rs
289
src/main.rs
|
@ -12,24 +12,83 @@ extern crate log;
|
||||||
extern crate dirs;
|
extern crate dirs;
|
||||||
|
|
||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use clap::{CommandFactory, Parser};
|
use clap::error::ErrorKind;
|
||||||
|
use clap::{CommandFactory, Parser, Subcommand};
|
||||||
|
use clap_verbosity_flag::Verbosity;
|
||||||
use git2::{Commit, Oid, Repository};
|
use git2::{Commit, Oid, Repository};
|
||||||
use inquire::{validator::Validation, Text};
|
use inquire::{validator::Validation, Text};
|
||||||
use serde_yaml;
|
use serde_yaml;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::Path;
|
use std::path::PathBuf;
|
||||||
|
use std::{env, io::BufReader, path::Path};
|
||||||
use crate::cmd_options::{Cli, Commands, StorageCommands};
|
use std::{
|
||||||
use crate::devices::get_device;
|
ffi::OsString,
|
||||||
use crate::storages::{
|
io::{self, BufWriter},
|
||||||
get_storages, physical_drive_partition::*, write_storages, Storage, StorageExt, StorageType,
|
|
||||||
STORAGESFILE,
|
|
||||||
};
|
};
|
||||||
use devices::Device;
|
use std::{fmt::Debug, fs::File};
|
||||||
|
use std::{fs, io::prelude::*};
|
||||||
|
use sysinfo::{Disk, DiskExt, SystemExt};
|
||||||
|
|
||||||
|
use crate::storages::{
|
||||||
|
directory::Directory, get_storages, local_info, online_storage, physical_drive_partition::*,
|
||||||
|
write_storages, Storage, StorageExt, StorageType, STORAGESFILE,
|
||||||
|
};
|
||||||
|
use devices::{Device, DEVICESFILE, *};
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(author, version, about, long_about = None)]
|
||||||
|
struct Cli {
|
||||||
|
#[command(subcommand)]
|
||||||
|
command: Commands,
|
||||||
|
|
||||||
|
#[command(flatten)]
|
||||||
|
verbose: Verbosity,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand)]
|
||||||
|
enum Commands {
|
||||||
|
/// Initialize for this device.
|
||||||
|
/// Provide `repo_url` to use existing repository, otherwise this device will be configured as the
|
||||||
|
/// first device.
|
||||||
|
Init {
|
||||||
|
repo_url: Option<String>, // url?
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Manage storages.
|
||||||
|
Storage(StorageArgs),
|
||||||
|
|
||||||
|
/// Print config dir.
|
||||||
|
Path {},
|
||||||
|
|
||||||
|
/// Sync with git repo.
|
||||||
|
Sync {},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(clap::Args)]
|
||||||
|
#[command(args_conflicts_with_subcommands = true)]
|
||||||
|
struct StorageArgs {
|
||||||
|
#[command(subcommand)]
|
||||||
|
command: StorageCommands,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand)]
|
||||||
|
enum StorageCommands {
|
||||||
|
/// Add new storage.
|
||||||
|
Add {
|
||||||
|
#[arg(value_enum)]
|
||||||
|
storage_type: StorageType,
|
||||||
|
|
||||||
|
// TODO: set this require and select matching disk for physical
|
||||||
|
#[arg(short, long, value_name = "PATH")]
|
||||||
|
path: Option<PathBuf>,
|
||||||
|
},
|
||||||
|
/// List all storages.
|
||||||
|
List {},
|
||||||
|
/// Add new device-specific name to existing storage.
|
||||||
|
/// For physical disk, the name is taken from system info automatically.
|
||||||
|
Bind { storage: String },
|
||||||
|
}
|
||||||
|
|
||||||
mod cmd_init;
|
|
||||||
mod cmd_options;
|
|
||||||
mod cmd_storage;
|
|
||||||
mod devices;
|
mod devices;
|
||||||
mod storages;
|
mod storages;
|
||||||
|
|
||||||
|
@ -49,8 +108,204 @@ fn main() -> Result<()> {
|
||||||
trace!("Config dir: {:?}", config_dir);
|
trace!("Config dir: {:?}", config_dir);
|
||||||
|
|
||||||
match cli.command {
|
match cli.command {
|
||||||
Commands::Init { repo_url } => cmd_init::cmd_init(repo_url, &config_dir)?,
|
Commands::Init { repo_url } => {
|
||||||
Commands::Storage(storage) => cmd_storage::cmd_storage(storage, &config_dir)?,
|
let is_first_device: bool;
|
||||||
|
// get repo or initialize it
|
||||||
|
let repo = match repo_url {
|
||||||
|
Some(repo_url) => {
|
||||||
|
trace!("repo: {}", repo_url);
|
||||||
|
let repo = Repository::clone(&repo_url, &config_dir)?;
|
||||||
|
is_first_device = false;
|
||||||
|
repo
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
trace!("No repo provided");
|
||||||
|
println!("Initializing for the first device...");
|
||||||
|
|
||||||
|
// create repository
|
||||||
|
let repo = Repository::init(&config_dir)?;
|
||||||
|
|
||||||
|
// set up gitignore
|
||||||
|
{
|
||||||
|
let f = File::create(&config_dir.join(".gitignore"))?;
|
||||||
|
{
|
||||||
|
let mut buf = BufWriter::new(f);
|
||||||
|
buf.write("devname".as_bytes())?;
|
||||||
|
}
|
||||||
|
add_and_commit(
|
||||||
|
&repo,
|
||||||
|
Path::new(".gitignore"),
|
||||||
|
"Add devname to gitignore.",
|
||||||
|
)?;
|
||||||
|
full_status(&repo)?;
|
||||||
|
}
|
||||||
|
is_first_device = true;
|
||||||
|
repo
|
||||||
|
}
|
||||||
|
};
|
||||||
|
full_status(&repo)?;
|
||||||
|
|
||||||
|
// set device name
|
||||||
|
let device = set_device_name()?;
|
||||||
|
|
||||||
|
// save devname
|
||||||
|
let devname_path = &config_dir.join("devname");
|
||||||
|
{
|
||||||
|
let f = File::create(devname_path)
|
||||||
|
.context("Failed to create a file to store local device name")?;
|
||||||
|
let writer = BufWriter::new(f);
|
||||||
|
serde_yaml::to_writer(writer, &device.name()).unwrap();
|
||||||
|
};
|
||||||
|
full_status(&repo)?;
|
||||||
|
|
||||||
|
// Add new device to devices.yml
|
||||||
|
{
|
||||||
|
let mut devices: Vec<Device> = if is_first_device {
|
||||||
|
vec![]
|
||||||
|
} else {
|
||||||
|
get_devices(&config_dir)?
|
||||||
|
};
|
||||||
|
trace!("devices: {:?}", devices);
|
||||||
|
if devices.iter().any(|x| x.name() == device.name()) {
|
||||||
|
return Err(anyhow!("device name is already used."));
|
||||||
|
}
|
||||||
|
devices.push(device.clone());
|
||||||
|
trace!("Devices: {:?}", devices);
|
||||||
|
write_devices(&config_dir, devices)?;
|
||||||
|
}
|
||||||
|
full_status(&repo)?;
|
||||||
|
|
||||||
|
// commit
|
||||||
|
add_and_commit(
|
||||||
|
&repo,
|
||||||
|
&Path::new(DEVICESFILE),
|
||||||
|
&format!("Add new devname: {}", &device.name()),
|
||||||
|
)?;
|
||||||
|
println!("Device added");
|
||||||
|
full_status(&repo)?;
|
||||||
|
}
|
||||||
|
Commands::Storage(storage) => {
|
||||||
|
let repo = Repository::open(&config_dir).context(
|
||||||
|
"Repository doesn't exist. Please run init to initialize the repository.",
|
||||||
|
)?;
|
||||||
|
trace!("repo state: {:?}", repo.state());
|
||||||
|
match storage.command {
|
||||||
|
StorageCommands::Add { storage_type, path } => {
|
||||||
|
trace!("Storage Add {:?}, {:?}", storage_type, path);
|
||||||
|
// Get storages
|
||||||
|
// let mut storages: Vec<Storage> = get_storages(&config_dir)?;
|
||||||
|
let mut storages: HashMap<String, Storage> = get_storages(&config_dir)?;
|
||||||
|
trace!("found storages: {:?}", storages);
|
||||||
|
|
||||||
|
let device = get_device(&config_dir)?;
|
||||||
|
let (key, storage) = match storage_type {
|
||||||
|
StorageType::Physical => {
|
||||||
|
// select storage
|
||||||
|
let (key, storage) = select_physical_storage(device, &storages)?;
|
||||||
|
println!("storage: {}: {:?}", key, storage);
|
||||||
|
(key, Storage::PhysicalStorage(storage))
|
||||||
|
}
|
||||||
|
StorageType::SubDirectory => {
|
||||||
|
if storages.is_empty() {
|
||||||
|
return Err(anyhow!("No storages found. Please add at least 1 physical storage first."));
|
||||||
|
}
|
||||||
|
let path = path.unwrap_or_else(|| {
|
||||||
|
let mut cmd = Cli::command();
|
||||||
|
cmd.error(
|
||||||
|
ErrorKind::MissingRequiredArgument,
|
||||||
|
"<PATH> is required with sub-directory",
|
||||||
|
)
|
||||||
|
.exit();
|
||||||
|
});
|
||||||
|
trace!("SubDirectory arguments: path: {:?}", path);
|
||||||
|
// Nightly feature std::path::absolute
|
||||||
|
let path = path.canonicalize()?;
|
||||||
|
trace!("canonicalized: path: {:?}", path);
|
||||||
|
|
||||||
|
let key_name = ask_unique_name(&storages, "sub-directory".to_string())?;
|
||||||
|
let notes = Text::new("Notes for this sub-directory:").prompt()?;
|
||||||
|
let storage = storages::directory::Directory::try_from_device_path(
|
||||||
|
key_name.clone(),
|
||||||
|
path,
|
||||||
|
notes,
|
||||||
|
&device,
|
||||||
|
&storages,
|
||||||
|
)?;
|
||||||
|
(key_name, Storage::SubDirectory(storage))
|
||||||
|
}
|
||||||
|
StorageType::Online => todo!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// add to storages
|
||||||
|
storages.insert(key.clone(), storage);
|
||||||
|
trace!("updated storages: {:?}", storages);
|
||||||
|
|
||||||
|
// write to file
|
||||||
|
write_storages(&config_dir, storages)?;
|
||||||
|
|
||||||
|
// commit
|
||||||
|
add_and_commit(
|
||||||
|
&repo,
|
||||||
|
&Path::new(STORAGESFILE),
|
||||||
|
&format!("Add new storage(physical drive): {}", key),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
println!("Added new storage.");
|
||||||
|
trace!("Finished adding storage");
|
||||||
|
}
|
||||||
|
StorageCommands::List {} => {
|
||||||
|
// Get storages
|
||||||
|
let storages: HashMap<String, Storage> = get_storages(&config_dir)?;
|
||||||
|
trace!("found storages: {:?}", storages);
|
||||||
|
let device = get_device(&config_dir)?;
|
||||||
|
for (k, storage) in &storages {
|
||||||
|
println!("{}: {}", k, storage);
|
||||||
|
println!(" {}", storage.mount_path(&device, &storages)?.display());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StorageCommands::Bind {
|
||||||
|
storage: storage_name,
|
||||||
|
} => {
|
||||||
|
// get storages
|
||||||
|
let mut storages: HashMap<String, Storage> = get_storages(&config_dir)?;
|
||||||
|
let commit_comment = {
|
||||||
|
// find matching storage
|
||||||
|
let storage = storages
|
||||||
|
.get_mut(&storage_name)
|
||||||
|
.context(format!("No storage has name {}", storage_name))?;
|
||||||
|
// get disk from sysinfo
|
||||||
|
let mut sysinfo = sysinfo::System::new_all();
|
||||||
|
sysinfo.refresh_disks();
|
||||||
|
let disk = select_sysinfo_disk(&sysinfo)?;
|
||||||
|
let system_name = disk
|
||||||
|
.name()
|
||||||
|
.to_str()
|
||||||
|
.context("Failed to convert disk name to valid string")?;
|
||||||
|
// add to storages
|
||||||
|
storage.bind_device(disk, &config_dir)?;
|
||||||
|
trace!("storage: {}", storage);
|
||||||
|
format!("{} to {}", system_name, storage.name())
|
||||||
|
};
|
||||||
|
trace!("bound new system name to the storage");
|
||||||
|
trace!("storages: {:#?}", storages);
|
||||||
|
|
||||||
|
write_storages(&config_dir, storages)?;
|
||||||
|
// commit
|
||||||
|
add_and_commit(
|
||||||
|
&repo,
|
||||||
|
&Path::new(STORAGESFILE),
|
||||||
|
&format!(
|
||||||
|
"Bound new storage name to physical drive ({})",
|
||||||
|
commit_comment
|
||||||
|
),
|
||||||
|
)?;
|
||||||
|
println!(
|
||||||
|
"Bound new storage name to physical drive ({})",
|
||||||
|
commit_comment
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Commands::Path {} => {
|
Commands::Path {} => {
|
||||||
println!("{}", &config_dir.display());
|
println!("{}", &config_dir.display());
|
||||||
}
|
}
|
||||||
|
@ -163,3 +418,9 @@ fn full_status(repo: &Repository) -> Result<()> {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn verify_cli() {
|
||||||
|
use clap::CommandFactory;
|
||||||
|
Cli::command().debug_assert()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue