init STORAGESFILE and DEVICESFILE at repo init and change Storages.read

- return Err instead of new object when there is no STORAGESFILE
- setup empty DEVICESFILE and STORAGESFILE at repository initialization
- update readme
This commit is contained in:
qwjyh 2024-03-11 08:22:35 +09:00
parent 7e026ec229
commit 8eb7d1179d
5 changed files with 36 additions and 57 deletions

View file

@ -1,10 +1,10 @@
# TODO:
- [x] split subcommands to functions
- [ ] write test for init subcommand
- [x] write test for init subcommand
- [ ] write test with existing repo
- [ ] with ssh credential
- [ ] ssh-agent
- [ ] specify key
- [x] with ssh credential
- [x] ssh-agent
- [x] specify key
- [ ] add storage remove command
- [ ] add sync subcommand
- [ ] add check subcommand

View file

@ -1,6 +1,7 @@
//! Init subcommand.
//! Initialize xdbm for the device.
use crate::storages::{Storages, STORAGESFILE};
use crate::{add_and_commit, full_status, get_devices, write_devices, Device, DEVICESFILE};
use anyhow::{anyhow, Context, Ok, Result};
use core::panic;
@ -81,11 +82,11 @@ pub(crate) fn cmd_init(
return Err(anyhow!("Device name is empty"));
}
// get repo or initialize it
let (is_first_device, repo) = match repo_url {
let repo = match repo_url {
Some(repo_url) => {
trace!("repo: {}", repo_url);
let repo = clone_repo(&repo_url, use_sshagent, ssh_key, config_dir)?;
(false, repo)
repo
}
None => {
trace!("No repo provided");
@ -104,7 +105,26 @@ pub(crate) fn cmd_init(
add_and_commit(&repo, Path::new(".gitignore"), "Add devname to gitignore.")?;
full_status(&repo)?;
}
(true, repo)
// TDOO: wrap up below into one commit?
// set up devices.yml
let devices: Vec<Device> = vec![];
write_devices(&config_dir, devices)?;
add_and_commit(
&repo,
Path::new(DEVICESFILE),
&format!("Initialize {}", DEVICESFILE),
)?;
// set up storages.yml
let storages = Storages::new();
storages.write(&config_dir)?;
add_and_commit(
&repo,
Path::new(STORAGESFILE),
&format!("Initialize {}", STORAGESFILE),
)?;
repo
}
};
full_status(&repo)?;
@ -126,11 +146,7 @@ pub(crate) fn cmd_init(
// Add new device to devices.yml
{
let mut devices: Vec<Device> = if is_first_device {
vec![]
} else {
get_devices(&config_dir)?
};
let mut devices: Vec<Device> = get_devices(&config_dir)?;
trace!("devices: {:?}", devices);
if devices.iter().any(|x| x.name() == device.name()) {
return Err(anyhow!("device name is already used."));
@ -145,7 +161,7 @@ pub(crate) fn cmd_init(
add_and_commit(
&repo,
&Path::new(DEVICESFILE),
&format!("Add new devname: {}", &device.name()),
&format!("Add new device: {}", &device.name()),
)?;
println!("Device added");
full_status(&repo)?;

View file

@ -33,7 +33,6 @@ pub(crate) fn cmd_storage_add(
) -> Result<()> {
trace!("Storage Add {:?}, {:?}", storage_type, path);
// Get storages
// let mut storages: Vec<Storage> = get_storages(&config_dir)?;
let mut storages = Storages::read(&config_dir)?;
trace!("found storages: {:?}", storages);
@ -109,7 +108,7 @@ pub(crate) fn cmd_storage_add(
StorageType::S => {
if storages.list.is_empty() {
return Err(anyhow!(
"No storages found. Please add at least 1 physical storage first."
"No storages found. Please add at least 1 physical/online storage first to add sub directory."
));
}
let path = path.unwrap_or_else(|| {
@ -325,7 +324,7 @@ fn ask_unique_name(storages: &Storages, target: String) -> Result<String> {
let mut disk_name = String::new();
loop {
disk_name = Text::new(format!("Name for {}:", target).as_str()).prompt()?;
if storages.list.iter().all(|(k, v)| k != &disk_name) {
if storages.list.iter().all(|(k, _v)| k != &disk_name) {
break;
}
println!("The name {} is already used.", disk_name);

View file

@ -18,16 +18,15 @@ use git2::{Commit, Oid, Repository};
use inquire::{min_length, Confirm, CustomType, Select};
use inquire::{validator::Validation, Text};
use serde_yaml;
use storages::Storages;
use std::collections::HashMap;
use std::path::Path;
use std::path::{self, PathBuf};
use storages::Storages;
use crate::cmd_args::{Cli, Commands, StorageCommands};
use crate::storages::online_storage;
use crate::storages::{
directory, local_info, physical_drive_partition, Storage,
StorageExt, StorageType, STORAGESFILE,
directory, local_info, physical_drive_partition, Storage, StorageExt, StorageType, STORAGESFILE,
};
use devices::{Device, DEVICESFILE, *};
@ -97,8 +96,7 @@ fn main() -> Result<()> {
}
Commands::Check {} => {
println!("Config dir: {}", &config_dir.display());
let _storages =
Storages::read(&config_dir)?;
let _storages = Storages::read(&config_dir)?;
todo!()
}
}

View file

@ -225,8 +225,8 @@ impl Storages {
pub fn read(config_dir: &path::Path) -> Result<Self> {
let storages_file = config_dir.join(STORAGESFILE);
if !storages_file.exists() {
trace!("No storages file found. Returning new `Storages` object.");
return Ok(Storages::new());
warn!("No storages file found.");
return Err(anyhow!("Couln't find {}", STORAGESFILE))
}
trace!("Reading {:?}", storages_file);
let f = fs::File::open(storages_file)?;
@ -242,37 +242,3 @@ impl Storages {
serde_yaml::to_writer(writer, &self).context(format!("Failed to writing to {:?}", STORAGESFILE))
}
}
// /// Get `HashMap<String, Storage>` from devices.yml([devices::DEVICESFILE]).
// /// If [devices::DEVICESFILE] isn't found, return empty vec.
// pub fn get_storages(config_dir: &path::Path) -> Result<HashMap<String, Storage>> {
// if let Some(storages_file) = fs::read_dir(&config_dir)?
// .filter(|f| {
// f.as_ref().map_or_else(
// |_e| false,
// |f| {
// let storagesfile: ffi::OsString = STORAGESFILE.into();
// f.path().file_name() == Some(&storagesfile)
// },
// )
// })
// .next()
// {
// trace!("{} found: {:?}", STORAGESFILE, storages_file);
// let f = fs::File::open(config_dir.join(STORAGESFILE))?;
// let reader = io::BufReader::new(f);
// let yaml: HashMap<String, Storage> =
// serde_yaml::from_reader(reader).context("Failed to read devices.yml")?;
// Ok(yaml)
// } else {
// trace!("No {} found", STORAGESFILE);
// Ok(HashMap::new())
// }
// }
//
// /// Write `storages` to yaml file in `config_dir`.
// pub fn write_storages(config_dir: &path::Path, storages: HashMap<String, Storage>) -> Result<()> {
// let f = fs::File::create(config_dir.join(STORAGESFILE))?;
// let writer = io::BufWriter::new(f);
// serde_yaml::to_writer(writer, &storages).map_err(|e| anyhow!(e))
// }