1
0
Fork 0
mirror of https://git.sr.ht/~nixgoat/vento synced 2025-11-29 16:15:43 +00:00

vento: The BIG commit

Since I worked on a LOT of stuff here, it's quite hard for me to
separate every change I've done. Take this as one huge refactor, which
includes:
- Changing the syntax of the Vento command
- Separating Vento into three binaries: vento, take, drop
- Moving the help messages into a new file called help.rs
- Removing unnecessary format macros
- Changing expect macros to context, for better anyhow compatibility
- Updating the documentation for these changes.
This commit is contained in:
Lux Aliaga 2022-09-26 16:54:39 -03:00
parent aa233555a4
commit ac986f8822
Signed by: lux
GPG key ID: B56C805968637437
10 changed files with 333 additions and 148 deletions

View file

@ -47,7 +47,7 @@ fn vento() -> Result<(String, String)> {
.description("List files and directories in the currently active inventory, the files in SLOT, the files in DIRECTORY or the files in DIRECTORY in SLOT.") .description("List files and directories in the currently active inventory, the files in SLOT, the files in DIRECTORY or the files in DIRECTORY in SLOT.")
.flag( .flag(
Flag::new() Flag::new()
.short("-s") .short("-c")
.long("--switch") .long("--switch")
.help("Switches inventory slots"), .help("Switches inventory slots"),
) )
@ -63,7 +63,12 @@ fn vento() -> Result<(String, String)> {
.long("--help") .long("--help")
.help("Shows the help message"), .help("Shows the help message"),
) )
.arg(Arg::new("[SLOT]")) .option(
Opt::new("slot")
.short("-s")
.long("--slot")
.help("The slot to list"),
)
.arg(Arg::new("[DIRECTORY]")) .arg(Arg::new("[DIRECTORY]"))
.custom( .custom(
Section::new("before starting") Section::new("before starting")

66
src/bin/drop.rs Normal file
View file

@ -0,0 +1,66 @@
/*
* Vento, a CLI inventory for your files.
* Copyright (C) 2022 Lux Aliaga
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
use anyhow::{bail, Result};
use colored::Colorize;
use std::env;
use std::path::Path;
use vento::{help, item};
fn main() -> Result<()> {
let args: Vec<String> = env::args().collect();
if args.len() >= 2 {
if args[1].contains("--slot=") {
match args.len() {
4 => item::drop(&args[2], &args[1].as_str().replace("--slot=", ""), Path::new(&args[4]).to_path_buf())?,
3 => item::drop(&args[2], &args[1].as_str().replace("--slot=", ""), match env::current_dir() {
Ok(dir) => dir,
Err(_) => bail!("❌ {}", "Vento was unable to detect your current directory. Have you configured your environment correctly?".red())
})?,
2 => bail!("❌ {}", "You need to specify a file".red()),
_ => bail!("❌ {}", "Too many arguments".red()),
};
} else {
match args[1].as_str() {
"--help" | "-h" => help::drop()?,
"-s" => match args.len() {
5 => item::drop(&args[3], &args[2], Path::new(&args[4]).to_path_buf())?,
4 => item::drop(&args[3], &args[2], match env::current_dir() {
Ok(dir) => dir,
Err(_) => bail!("❌ {}", "Vento was unable to detect your current directory. Have you configured your environment correctly?".red())
})?,
3 => bail!("❌ {}", "You need to specify a file".red()),
2 => bail!("❌ {}", "You need to specify a slot".red()),
_ => bail!("❌ {}", "Too many arguments".red()),
},
_ => match args.len() {
3 => item::drop(&args[1], &String::from("active"), Path::new(&args[2]).to_path_buf())?,
2 => item::drop(&args[1], &String::from("active"), match env::current_dir() {
Ok(dir) => dir,
Err(_) => bail!("❌ {}", "Vento was unable to detect your current directory. Have you configured your environment correctly?".red())
})?,
_ => bail!("❌ {}", "Too many arguments".red()),
},
}
}
} else {
help::drop()?;
}
Ok(())
}

53
src/bin/take.rs Normal file
View file

@ -0,0 +1,53 @@
/*
* Vento, a CLI inventory for your files.
* Copyright (C) 2022 Lux Aliaga
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
use anyhow::{bail, Result};
use colored::Colorize;
use std::env;
use vento::{help, item};
fn main() -> Result<()> {
let args: Vec<String> = env::args().collect();
if args.len() >= 2 {
if args[1].contains("--slot=") {
match args.len() {
3 => item::take(&args[2], &args[1].replace("--slot=", ""))?,
2 => bail!("❌ {}", "You need to specify a file".red()),
_ => bail!("❌ {}", "Too many arguments".red()),
};
} else {
match args[1].as_str() {
"--help" | "-h" => help::take()?,
"-s" => match args.len() {
4 => item::take(&args[3], &args[2])?,
3 => bail!("❌ {}", "You need to specify a file".red()),
2 => bail!("❌ {}", "You need to specify a slot".red()),
_ => bail!("❌ {}", "Too many arguments".red()),
},
_ => match args.len() {
2 => item::take(&args[1], &String::from("active"))?,
_ => bail!("❌ {}", "Too many arguments".red()),
},
}
}
} else {
help::take()?;
}
Ok(())
}

54
src/bin/vento.rs Normal file
View file

@ -0,0 +1,54 @@
/*
* Vento, a CLI inventory for your files.
* Copyright (C) 2022 Lux Aliaga
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
use anyhow::{bail, Result};
use colored::Colorize;
use std::env;
use vento::{help, inv};
fn main() -> Result<()> {
let args: Vec<String> = env::args().collect();
if args.len() >= 2 {
// If the vector for the arguments the command is taking is larger than 2, it most likely means the user has provided an argument
if args[1].contains("--slot=") {
match args.len() {
3 => inv::list(&args[1].replace("--slot=", ""), &args[2])?,
2 => inv::list(&args[1].replace("--slot=", ""), "")?,
_ => bail!("❌ {}", "Too many arguments".red()),
};
} else {
match args[1].as_str() {
"-h" | "--help" => help::vento()?,
"-i" | "--init" => inv::init()?,
"-c" | "--switch" => inv::switch()?,
"-s" => match args.len() {
4 => inv::list(&args[2], &args[3])?,
3 => inv::list(&args[2], "")?,
2 => bail!("❌ {}", "You need to specify a slot.".red()),
_ => bail!("❌ {}", "Too many arguments".red()),
},
_ => inv::list("active", args[1].as_str())?,
}
}
} else {
// If the user provides no commands, Vento will display the files in the active slot.
inv::list("active", "")?;
}
Ok(())
}

View file

@ -29,7 +29,7 @@ pub fn env_config() -> Result<Vec<PathBuf>> {
_ => PathBuf::new(), _ => PathBuf::new(),
}; };
if home == emptypath { if home == emptypath {
bail!("❌ {}", format!("Vento was unable to detect your home folder. Have you configured your environment correctly?").red()); bail!("❌ {}", "Vento was unable to detect your home folder. Have you configured your environment correctly?".red());
}; };
let vento_dir = [home, Path::new(".vento").to_path_buf()].iter().collect(); let vento_dir = [home, Path::new(".vento").to_path_buf()].iter().collect();
let active_dir = [&vento_dir, &Path::new("active").to_path_buf()] let active_dir = [&vento_dir, &Path::new("active").to_path_buf()]

82
src/help.rs Normal file
View file

@ -0,0 +1,82 @@
/*
* Vento, a CLI inventory for your files.
* Copyright (C) 2022 Lux Aliaga
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
use anyhow::Result;
use colored::Colorize;
pub fn vento() -> Result<()> {
// A quick guide to move around in Vento
println!(
"{}, a CLI inventory for your files
© 2022 Lux Aliaga. Licensed under GPLv3
{}
- {}: Lists files in selected inventory
- {}: Switches slots
- {}: Initializes Vento
- {}: Displays this message",
"Vento".bold().blue(),
"Usage:".bold(),
"vento [ -s slot | --slot=slot ] [ directory ]"
.bold()
.green(),
"vento ( -c | --switch )".bold().green(),
"vento ( -i | --init )".bold().green(),
"vento ( -h | --help )".bold().green()
);
Ok(())
}
pub fn take() -> Result<()> {
// A quick guide to move around in Vento
println!(
"{}, a file grabber for Vento
© 2022 Lux Aliaga. Licensed under GPLv3
{}
- {}: Takes a file and saves it in the inventory
- {}: Displays this message",
"Take".bold().blue(),
"Usage:".bold(),
"take [ -s slot | --slot=slot ] file | directory"
.bold()
.green(),
"take ( -h | --help )".bold().green()
);
Ok(())
}
pub fn drop() -> Result<()> {
// A quick guide to move around in Vento
println!(
"{}, a file dropper for Vento
© 2022 Lux Aliaga. Licensed under GPLv3
{}
- {}: Takes a file off the inventory and drops it.
- {}: Displays this message",
"Drop".bold().blue(),
"Usage:".bold(),
"drop [ -s slot | --slot=slot ] file | directory [destination]"
.bold()
.green(),
"drop ( -h | --help )".bold().green()
);
Ok(())
}

View file

@ -32,11 +32,11 @@ pub fn init() -> Result<()> {
if ventodir.is_dir() { if ventodir.is_dir() {
// Checks if Vento has already been initialized and prompts the user if they want to initialize it again // Checks if Vento has already been initialized and prompts the user if they want to initialize it again
let mut answer = String::new(); let mut answer = String::new();
print!("⚠️ {} {}", format!("WARNING:").bold().red(), "Vento has already been initialized. Reinitializing will delete all files on the directory for Vento. Do you wish to proceed? (y/N) "); print!("⚠️ {} {}", "WARNING:".bold().red(), "Vento has already been initialized. Reinitializing will delete all files on the directory for Vento. Do you wish to proceed? (y/N) ");
let _ = io::stdout().flush(); let _ = io::stdout().flush();
io::stdin() io::stdin()
.read_line(&mut answer) .read_line(&mut answer)
.expect("❌ Failed to read input"); .context("❌ Failed to read input")?;
match answer.as_str().trim() { match answer.as_str().trim() {
"y" | "Y" => fs::remove_dir_all(&ventodir)?, "y" | "Y" => fs::remove_dir_all(&ventodir)?,
_ => process::exit(0), _ => process::exit(0),
@ -55,13 +55,21 @@ pub fn list(slot: &str, dir: &str) -> Result<()> {
_ => PathBuf::new(), _ => PathBuf::new(),
}; };
let ventodir = &common::env_config()?[0];
if !ventodir.is_dir() {
bail!(
"❌ {}",
"Vento not initialized. Run \"vento -i\" to initialize Vento.".red()
);
}
if dir != "" { if dir != "" {
slotdir = [&slotdir, &Path::new(dir).to_path_buf()].iter().collect(); slotdir = [&slotdir, &Path::new(dir).to_path_buf()].iter().collect();
} }
if dir.to_string().contains("..") { if dir.to_string().contains("..") {
bail!("❌ {}", format!("Cannot access parent.").red()); bail!("❌ {}", "Cannot access parent.".red());
// process::exit(1);
} }
if slotdir.is_dir() { if slotdir.is_dir() {
@ -117,11 +125,11 @@ pub fn list(slot: &str, dir: &str) -> Result<()> {
println!( println!(
" - [{}] {}{}", " - [{}] {}{}",
if file.clone().is_dir() { if file.clone().is_dir() {
format!("D").blue() "D".blue()
} else if file.clone().is_symlink() { } else if file.clone().is_symlink() {
format!("S").yellow() "S".yellow()
} else { } else {
format!("F").green() "F".green()
}, },
file.clone() file.clone()
.file_name() .file_name()
@ -145,8 +153,8 @@ pub fn list(slot: &str, dir: &str) -> Result<()> {
"❌ {}", "❌ {}",
format!( format!(
"No such slot or directory. Valid slots are {} and {}.", "No such slot or directory. Valid slots are {} and {}.",
format!("active").green().bold(), "active".green().bold(),
format!("inactive").blue().bold() "inactive".blue().bold()
) )
.red() .red()
); );
@ -163,14 +171,13 @@ pub fn switch() -> Result<()> {
.iter() .iter()
.collect(); .collect();
fs::rename(&active, &temp) let rename_error = "❌ Vento was unable to switch slots. Try running vento init and try again";
.expect("❌ Vento was unable to switch slots. Try running vento init and try again");
fs::rename(&inactive, &active)
.expect("❌ Vento was unable to switch slots. Try running vento init and try again");
fs::rename(&temp, &inactive)
.expect("❌ Vento was unable to switch slots. Try running vento init and try again");
println!("🎉 {}", format!("Switched inventory slots!").green()); fs::rename(&active, &temp).context(rename_error)?;
fs::rename(&inactive, &active).context(rename_error)?;
fs::rename(&temp, &inactive).context(rename_error)?;
println!("🎉 {}", "Switched inventory slots!".green());
Ok(()) Ok(())
} }
@ -179,13 +186,11 @@ fn create_slots() -> Result<()> {
let active = &common::env_config()?[1]; let active = &common::env_config()?[1];
let inactive = &common::env_config()?[2]; let inactive = &common::env_config()?[2];
fs::create_dir_all(active) let initialize_error = "❌ Vento was unable to initalize. Do you have the correct permissions";
.context("❌ Vento was unable to initalize. Do you have the correct permissions?")?;
fs::create_dir_all(inactive)
.context("❌ Vento was unable to initalize. Do you have the correct permissions?")?;
println!( fs::create_dir_all(active).context(initialize_error)?;
"🎉 {}", format!("Vento has been succesfully initialized!").green() fs::create_dir_all(inactive).context(initialize_error)?;
);
println!("🎉 {}", "Vento has been succesfully initialized!".green());
Ok(()) Ok(())
} }

View file

@ -24,35 +24,42 @@ use fs_extra::dir::{move_dir, CopyOptions};
use std::fs; use std::fs;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
pub fn take(file: &String) -> Result<()> { pub fn take(file: &String, slot: &String) -> Result<()> {
// Takes a file or directory // Takes a file or directory
let active = &common::env_config()?[1]; let slotdir: PathBuf = match slot.as_str() {
"active" | "a" => common::env_config()?[1].clone(),
"inactive" | "i" => common::env_config()?[2].clone(),
_ => PathBuf::new(),
};
let sourcepath: PathBuf = Path::new(&file).to_path_buf(); let sourcepath: PathBuf = Path::new(&file).to_path_buf();
let destpath: PathBuf = [&active, &Path::new(file).to_path_buf()].iter().collect(); let destpath: PathBuf = [&slotdir, &Path::new(file).to_path_buf()].iter().collect();
if Path::exists(&destpath) { if Path::exists(&destpath) {
bail!( bail!(
"❌ {}", "❌ {}",
format!("A file with the same name already exists in your inventory!").red() "A file with the same name already exists in your inventory!".red()
); );
} else if sourcepath.is_file() | sourcepath.is_symlink() { } else if sourcepath.is_file() | sourcepath.is_symlink() {
fs::copy(&file, &destpath).expect("❌ Vento was unable to copy the file."); fs::copy(&file, &destpath).expect("❌ Vento was unable to copy the file.");
fs::remove_file(&file).expect("❌ Vento was unable to remove the file."); fs::remove_file(&file).expect("❌ Vento was unable to remove the file.");
} else if sourcepath.is_dir() { } else if sourcepath.is_dir() {
let options = CopyOptions::new(); let options = CopyOptions::new();
move_dir(&file, &active, &options).expect("❌ Vento was unable to move the directory."); move_dir(&file, &slotdir, &options).expect("❌ Vento was unable to move the directory.");
} else { } else {
println!("{}", format!("No such file or directory.").red()); println!("{}", "No such file or directory.".red());
} }
Ok(()) Ok(())
} }
pub fn drop(file: &String, dest: PathBuf) -> Result<()> { pub fn drop(file: &String, slot: &String, dest: PathBuf) -> Result<()> {
// Drops a file or directory // Drops a file or directory
let active = &common::env_config()?[1]; let slotdir: PathBuf = match slot.as_str() {
"active" | "a" => common::env_config()?[1].clone(),
"inactive" | "i" => common::env_config()?[2].clone(),
_ => PathBuf::new(),
};
let sourcepath: PathBuf = [&active, &Path::new(file).to_path_buf()].iter().collect(); let sourcepath: PathBuf = [&slotdir, &Path::new(file).to_path_buf()].iter().collect();
let destpath: PathBuf = [ let destpath: PathBuf = [
Path::new(&dest).to_path_buf(), Path::new(&dest).to_path_buf(),
Path::new(file).to_path_buf(), Path::new(file).to_path_buf(),
@ -62,7 +69,7 @@ pub fn drop(file: &String, dest: PathBuf) -> Result<()> {
if Path::exists(&destpath) { if Path::exists(&destpath) {
// HAHA YANDEREDEV MOMENT. This checks what method to use for the file/directory the user has picked // HAHA YANDEREDEV MOMENT. This checks what method to use for the file/directory the user has picked
bail!("❌ {}", format!("A file with the same name already exists in the destination! Try renaming it or dropping this file somewhere else.").red()); bail!("❌ {}", "A file with the same name already exists in the destination! Try renaming it or dropping this file somewhere else.".red());
} else if sourcepath.is_file() | sourcepath.is_symlink() { } else if sourcepath.is_file() | sourcepath.is_symlink() {
fs::copy(&sourcepath, &destpath).context("❌ Vento was unable to copy the file.")?; fs::copy(&sourcepath, &destpath).context("❌ Vento was unable to copy the file.")?;
fs::remove_file(&sourcepath).context("❌ Vento was unable to remove the file.")?; fs::remove_file(&sourcepath).context("❌ Vento was unable to remove the file.")?;
@ -72,7 +79,7 @@ pub fn drop(file: &String, dest: PathBuf) -> Result<()> {
move_dir(&sourcepath, &destpath, &options) move_dir(&sourcepath, &destpath, &options)
.expect("❌ Vento was unable to move the directory."); .expect("❌ Vento was unable to move the directory.");
} else { } else {
bail!("❌ {}", format!("No such file or directory.").red()); bail!("❌ {}", "No such file or directory.".red());
} }
Ok(()) Ok(())
} }

23
src/lib.rs Normal file
View file

@ -0,0 +1,23 @@
/*
* Vento, a CLI inventory for your files.
* Copyright (C) 2022 Lux Aliaga
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
mod common;
pub mod help;
pub mod inv;
pub mod item;

View file

@ -1,110 +0,0 @@
/*
* Vento, a CLI inventory for your files.
* Copyright (C) 2022 Lux Aliaga
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
use anyhow::{bail, Result};
use colored::Colorize;
use std::env;
use std::path::Path;
use std::process;
mod common;
mod inv;
mod item;
fn main() -> Result<()> {
let args: Vec<String> = env::args().collect();
if args.len() >= 2 {
// If the vector for the arguments the command is taking is larger than 2, it most likely means the user has provided an argument
match args[1].as_str() {
"help" | "h" => help()?,
"init" | "i" => inv::init()?,
"list" | "l" => match args.len() {
4 => inv::list(args[2].as_str(), args[3].as_str())?,
3 => match args[2].as_str() {
"active" | "a" | "inactive" | "i" => inv::list(args[2].as_str(), "")?,
_ => inv::list("active", args[2].as_str())?,
},
2 => inv::list("active", "")?,
_ => bail!("❌ {}", format!("Too many arguments.").red()),
},
"switch" | "s" => inv::switch()?,
"take" | "t" => {
if args.len() == 3 {
// Similar thing with list, but change it with a file and it will show an error instead of defaulting to anything
item::take(&args[2])?;
} else {
bail!("❌ {}", format!("You need to specify a file.").red())
};
}
"drop" | "d" => {
if args.len() == 3 {
// Tries to get the current directory if the user hasn't provided a "landing location"
item::drop(
&args[2],
match env::current_dir() {
Ok(dir) => dir,
Err(_) => {
println!("{}", format!("Vento was unable to detect your current directory. Have you configured your environment correctly?").red());
process::exit(1);
}
},
)?;
} else if args.len() == 4 {
item::drop(&args[2], Path::new(&args[3]).to_path_buf())?;
} else {
println!("{}", format!("You need to specify a file.").red())
};
}
_ => {
println!("❔ Command not found. Type \"vento help\" to see all commands available.")
}
}
} else {
// If the user provides no commands, it'll fall back to the help guide
help()?;
}
Ok(())
}
fn help() -> Result<()> {
// A quick guide to move around in Vento
println!(
"{}, a CLI inventory for your files
© 2022 Lux Aliaga. Licensed under GPLv3
{}
- {}: Takes a file or directory and saves it in your inventory
- {}: Drops a file off of your inventory
- {}: Lists files in selected inventory
- {}: Switches slots
- {}: Initializes Vento
- {}: Displays this message",
format!("Vento").bold().blue(),
format!("Usage:").bold(),
format!("take | t <file | directory>").bold().green(),
format!("drop | d <file | directory> [destination]")
.bold()
.green(),
format!("list | l [slot] [directory]").bold().green(),
format!("switch | s").bold().green(),
format!("init | i").bold().green(),
format!("help | h").bold().green()
);
Ok(())
}