Compare commits

...

12 Commits

Author SHA1 Message Date
Lux Aliaga b5c0818719
manifest: Bump version to v1.2
New features, new version!
2023-02-19 18:24:27 -03:00
Lux Aliaga 0424ec2ba9
src: Add public documentation for remaining functions
Essentially the documentation that will go into docs.rs.
2023-02-19 18:23:00 -03:00
Lux Aliaga 27b42e963e
error: Add more error types
Since error refactoring was quite incomplete, I've added more errors for other parts of Vento. This should cover almost every error except slot errors, since those require their own formatting.
2023-02-19 14:42:26 -03:00
Lux Aliaga 67d2da8767
error: Fix switchup between SpecifyFile and SpecifySlot
Turns out SpecifyFile would show the message for SpecifySlot and
viceversa. Whoops!
2023-02-19 13:34:32 -03:00
Lux Aliaga 5e2763f5df
manifest: Remove unused flate2 crate
I accidentally added this crate which ended up not being used. Oh well.
2023-02-19 13:32:40 -03:00
Lux Aliaga 75fb04d674
help: Document the archiving flags
The only caveat is the limitations of the man library will not
allow me to write more in-depth documentation of the new flags. Maybe if
I go through refactoring the binary side using clap this will be easier.
2023-02-19 13:30:48 -03:00
Lux Aliaga d148a96e06
archive: Reword Vento directory archives
Calling the action of archiving the Vento directory "Archiving Vento
installs" was a bit misleading, so I changed it to Vento directories.
2023-02-19 13:19:20 -03:00
Lux Aliaga 2a4ee258a3
archive: Add install importing
Allows exported installs to be imported using the command `vento -G`.
Mind the uppercase "G" there!
2023-02-19 13:04:33 -03:00
Lux Aliaga 13d0889ad1
archive: Add inventory importing
Allows exported inventories to be imported using the command `vento -g`
2023-02-19 12:49:11 -03:00
Lux Aliaga c5cc1ea97a
archive: Add install exporting
This exports all contents in your vento directory into an xz tarball.
Needs documentation, but essentially it works using `vento -E`. Mind the
uppercase E there!
2023-02-17 13:39:56 -03:00
Lux Aliaga faf8036b19
archive: Fixed slot colors
In the confirmation message the slot being exported showed as white. It
should now be colored in either green, blue or red.
2023-02-17 12:44:18 -03:00
Lux Aliaga b6162a9dcb
archive: Add inventory exporting
Currently undocumented, but this should allow users to export their
inventory slots as xz tarballs using `vento -e`. Ideal for sharing
collections of files to friends!
2023-02-17 02:07:28 -03:00
12 changed files with 379 additions and 34 deletions

134
Cargo.lock generated
View File

@ -68,6 +68,12 @@ dependencies = [
"generic-array 0.14.6",
]
[[package]]
name = "cc"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -159,6 +165,18 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257"
[[package]]
name = "filetime"
version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"windows-sys",
]
[[package]]
name = "fs_extra"
version = "1.2.0"
@ -248,6 +266,17 @@ version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "lzma-sys"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27"
dependencies = [
"cc",
"libc",
"pkg-config",
]
[[package]]
name = "man"
version = "0.3.0"
@ -409,6 +438,12 @@ dependencies = [
"sha1",
]
[[package]]
name = "pkg-config"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
[[package]]
name = "proc-macro2"
version = "1.0.43"
@ -543,6 +578,17 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "tar"
version = "0.4.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6"
dependencies = [
"filetime",
"libc",
"xattr",
]
[[package]]
name = "thiserror"
version = "1.0.34"
@ -592,7 +638,7 @@ checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
[[package]]
name = "vento"
version = "1.1.3"
version = "1.2.0"
dependencies = [
"anyhow",
"colored",
@ -601,6 +647,8 @@ dependencies = [
"fs_extra",
"man",
"size_format",
"tar",
"xz2",
]
[[package]]
@ -637,6 +685,90 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
[[package]]
name = "windows_i686_gnu"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
[[package]]
name = "windows_i686_msvc"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
[[package]]
name = "xattr"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc"
dependencies = [
"libc",
]
[[package]]
name = "xz2"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2"
dependencies = [
"lzma-sys",
]
[[package]]
name = "yaml-rust"
version = "0.4.5"

View File

@ -1,6 +1,6 @@
[package]
name = "vento"
version = "1.1.3"
version = "1.2.0"
edition = "2021"
readme = "README.md"
@ -22,6 +22,8 @@ fs_extra = "1.2.0"
anyhow = "1.0"
size_format = "1.0.2"
config = "0.13.1"
xz2 = "0.1"
tar = "0.4"
[build-dependencies]
man = "0.3.0"

View File

@ -62,6 +62,30 @@ fn vento() -> Result<Page> {
.long("--undo")
.help("Undoes the last action"),
)
.flag(
Flag::new()
.short("-e")
.long("--export-inv")
.help("Exports an inventory"),
)
.flag(
Flag::new()
.short("-E")
.long("--export-dir")
.help("Exports the Vento directory"),
)
.flag(
Flag::new()
.short("-g")
.long("--import-inv")
.help("Imports an inventory archive"),
)
.flag(
Flag::new()
.short("-G")
.long("--import-dir")
.help("Imports a Vento directory archive"),
)
.flag(
Flag::new()
.short("-i")

126
src/archive.rs Normal file
View File

@ -0,0 +1,126 @@
/*
* Vento, a CLI inventory for your files.
* Copyright (C) 2023 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 crate::common;
use anyhow::Result;
use colored::Colorize;
use std::{fs::File, path::PathBuf};
use tar::Archive;
use xz2::read::XzDecoder;
use xz2::write::XzEncoder;
/// Exports an inventory slot into an xz tarball
pub fn export_inv(slot: &str, output: PathBuf, message: bool) -> Result<()> {
let slotdir: PathBuf = match slot {
"active" | "a" => common::env_config()?.active_dir,
"inactive" | "i" => common::env_config()?.inactive_dir,
_ => PathBuf::new(),
};
let archive = File::create(&output)?;
let enc = XzEncoder::new(archive, 9);
let mut tar = tar::Builder::new(enc);
tar.append_dir_all("", slotdir)?;
if message {
println!(
"✅ {} {} {} {}",
"Exported".green(),
match slot {
"a" | "active" => "active".green(),
"i" | "inactive" => "inactive".blue(),
_ => slot.red(),
}
.bold(),
"slot into".green(),
&output.to_str().unwrap()
);
};
Ok(())
}
/// Exports the Vento directory into an xz tarball
pub fn export_dir(output: PathBuf, message: bool) -> Result<()> {
let dir: PathBuf = common::env_config()?.vento_dir;
let archive = File::create(&output)?;
let enc = XzEncoder::new(archive, 9);
let mut tar = tar::Builder::new(enc);
tar.append_dir_all("", dir)?;
if message {
println!(
"✅ {} {}",
"Exported Vento directory into".green(),
&output.to_str().unwrap()
);
};
Ok(())
}
/// Imports an xz tarball into an inventory slot
pub fn import_inv(input: PathBuf, slot: &str, message: bool) -> Result<()> {
let slotdir: PathBuf = match slot {
"active" | "a" => common::env_config()?.active_dir,
"inactive" | "i" => common::env_config()?.inactive_dir,
_ => PathBuf::new(),
};
let tar_xz = File::open(&input)?;
let tar = XzDecoder::new(tar_xz);
let mut archive = Archive::new(tar);
archive.unpack(&slotdir)?;
if message {
println!(
"✅ {} {} {} {} {}",
"Imported".green(),
&input.to_str().unwrap(),
"into".green(),
match slot {
"a" | "active" => "active".green(),
"i" | "inactive" => "inactive".blue(),
_ => slot.red(),
}
.bold(),
"slot".green()
);
};
Ok(())
}
/// Imports an xz tarball into the Vento directory
pub fn import_dir(input: PathBuf, message: bool) -> Result<()> {
let dir: PathBuf = common::env_config()?.vento_dir;
let tar_xz = File::open(&input)?;
let tar = XzDecoder::new(tar_xz);
let mut archive = Archive::new(tar);
archive.unpack(&dir)?;
if message {
println!(
"✅ {} {} {}",
"Imported".green(),
&input.to_str().unwrap(),
"into Vento directory".green(),
);
};
Ok(())
}

View File

@ -18,8 +18,9 @@
*/
use anyhow::Result;
use std::env;
use std::{env, path::PathBuf};
use vento::{
archive,
error::{throw_error, ErrorType},
help, history, inv,
};
@ -42,6 +43,39 @@ fn main() -> Result<()> {
"-i" | "--init" => inv::init()?,
"-c" | "--switch" => inv::switch(true)?,
"-u" | "--undo" => history::undo()?,
"-e" | "--export-inv" => match args.len() {
4 => archive::export_inv(&args[2], PathBuf::from(&args[3]), true)?,
3 => match args[2].as_str() {
"active" | "a" | "inactive" | "i" => {
let mut path = PathBuf::from(match args[2].as_str() {
"a" => "active",
"i" => "inactive",
_ => &args[2],
});
path.set_extension("tar.xz");
archive::export_inv(&args[2], path, true)?
}
_ => archive::export_inv("active", PathBuf::from(&args[2]), true)?,
},
2 => archive::export_inv("active", PathBuf::from("active.tar.xz"), true)?,
_ => throw_error(ErrorType::TooManyArgs)?,
},
"-E" | "--export-dir" => match args.len() {
3 => archive::export_dir(PathBuf::from(&args[2]), true)?,
2 => archive::export_dir(PathBuf::from("vento.tar.xz"), true)?,
_ => throw_error(ErrorType::TooManyArgs)?,
},
"-g" | "--import-inv" => match args.len() {
4 => archive::import_inv(PathBuf::from(&args[2]), &args[3], true)?,
3 => archive::import_inv(PathBuf::from(&args[2]), "active", true)?,
2 => throw_error(ErrorType::SpecifyFile)?,
_ => throw_error(ErrorType::TooManyArgs)?,
},
"-G" | "--import-dir" => match args.len() {
3 => archive::import_dir(PathBuf::from(&args[2]), true)?,
2 => throw_error(ErrorType::SpecifyFile)?,
_ => throw_error(ErrorType::TooManyArgs)?,
},
"-s" => match args.len() {
4 => inv::list(&args[2], &args[3])?,
3 => inv::list(&args[2], "")?,

View File

@ -18,8 +18,7 @@
*/
use crate::error::{throw_error, ErrorType};
use anyhow::{bail, Result};
use colored::Colorize;
use anyhow::Result;
use config::Config;
use std::env::current_dir;
use std::fs::File;
@ -52,7 +51,7 @@ pub fn env_config() -> Result<Settings> {
_ => PathBuf::new(),
};
if home == PathBuf::new() {
bail!("{}", "Vento was unable to detect your home folder. Have you configured your environment correctly?".red());
throw_error(ErrorType::NoHomeDirectory)?;
};
let custom_dir = Path::new(&dir_config()?).to_path_buf();
let vento_dir: PathBuf = if custom_dir != PathBuf::new() {

View File

@ -25,16 +25,33 @@ pub enum ErrorType {
SpecifySlot,
SpecifyFile,
NoCurrentDirectory,
NoHomeDirectory,
InvalidHistoryLength,
IllegalAction,
NotInitialized,
NoAccessParent,
ExistsInventory,
ExistsDestination,
NoFileOrDir,
}
/// Displays an error and exits
pub fn throw_error(error: ErrorType) -> Result<()> {
bail!(
"{}",
match error {
ErrorType::TooManyArgs => "Too many arguments",
ErrorType::SpecifySlot => "You need to specify a file",
ErrorType::SpecifyFile => "You need to specify a slot",
ErrorType::SpecifyFile => "You need to specify a file",
ErrorType::SpecifySlot => "You need to specify a slot",
ErrorType::NoCurrentDirectory => "Vento was unable to detect your current directory. Have you configured your environment correctly?",
ErrorType::NoHomeDirectory => "Vento was unable to detect your home directory. Have you configured your environment correctly?",
ErrorType::InvalidHistoryLength => "Invalid history length",
ErrorType::IllegalAction => "Illegal action",
ErrorType::NotInitialized => "Vento not initialized. Run \"vento -i\" to initialize Vento",
ErrorType::NoAccessParent => "Cannot access parent",
ErrorType::ExistsInventory => "A file with the same name already exists in your inventory!",
ErrorType::ExistsDestination => "A file with the same name already exists in the destination! Try renaming it or dropping this file somewhere else",
ErrorType::NoFileOrDir => "No such file or directory",
}
.red()
);

View File

@ -30,6 +30,10 @@ pub fn vento() -> Result<()> {
- {}: Lists files in selected inventory
- {}: Switches slots
- {}: Undoes the last action
- {}: Exports an inventory
- {}: Exports the Vento directory
- {}: Imports an inventory archive
- {}: Imports a Vento directory archive
- {}: Initializes Vento
- {}: Displays this message",
"Vento".bold().blue(),
@ -39,6 +43,14 @@ pub fn vento() -> Result<()> {
.green(),
"vento ( -c | --switch )".bold().green(),
"vento ( -u | --undo )".bold().green(),
"vento ( -e | --export-inv ) [ slot ] [ output ]"
.bold()
.green(),
"vento ( -E | --export-dir ) [ output ]".bold().green(),
"vento ( -g | --import-inv ) [ input ] [ slot ]"
.bold()
.green(),
"vento ( -G | --import-dir ) [ input ]".bold().green(),
"vento ( -i | --init )".bold().green(),
"vento ( -h | --help )".bold().green()
);

View File

@ -17,8 +17,12 @@
*
*/
use crate::{common, inv, item};
use anyhow::{bail, Result};
use crate::{
common,
error::{throw_error, ErrorType},
inv, item,
};
use anyhow::Result;
use colored::Colorize;
use std::fs;
use std::path::{Path, PathBuf};
@ -41,7 +45,7 @@ pub fn undo() -> Result<()> {
}
if contents.len() != 4 {
bail!("Invalid history length".red());
throw_error(ErrorType::InvalidHistoryLength)?;
}
match contents[3] {
@ -56,7 +60,7 @@ pub fn undo() -> Result<()> {
"switch" => {
inv::switch(false)?;
}
_ => bail!("Illegal action".red()),
_ => throw_error(ErrorType::IllegalAction)?,
}
println!(

View File

@ -17,7 +17,10 @@
*
*/
use super::common;
use super::{
common,
error::{throw_error, ErrorType},
};
use anyhow::{bail, Context, Result};
use colored::Colorize;
use size_format::SizeFormatterBinary;
@ -51,10 +54,7 @@ pub fn list(slot: &str, dir: &str) -> Result<()> {
if !ventodir.is_dir() {
// Detects if Vento hasn't been initialized and bails if so
bail!(
"{}",
"Vento not initialized. Run \"vento -i\" to initialize Vento".red()
);
throw_error(ErrorType::NotInitialized)?;
}
let mut slotdir: PathBuf = match slot {
@ -70,7 +70,7 @@ pub fn list(slot: &str, dir: &str) -> Result<()> {
if dir.to_string().contains("..") {
// Basically preventing from listing anything out of bounds. ls and dir exist for that
bail!("{}", "Cannot access parent".red());
throw_error(ErrorType::NoAccessParent)?;
}
if !slotdir.is_dir() {

View File

@ -17,7 +17,10 @@
*
*/
use super::common;
use super::{
common,
error::{throw_error, ErrorType},
};
use anyhow::{bail, Result};
use colored::Colorize;
use fs_extra::dir::{move_dir, CopyOptions};
@ -30,10 +33,7 @@ pub fn take(file: &String, slot: &str, message: bool) -> Result<()> {
if !ventodir.is_dir() {
// Detects if Vento hasn't been initialized and bails if so
bail!(
"{}",
"Vento not initialized. Run \"vento -i\" to initialize Vento".red()
);
throw_error(ErrorType::NotInitialized)?;
};
let slotdir: PathBuf = match slot {
"active" | "a" => common::env_config()?.active_dir,
@ -64,10 +64,7 @@ pub fn take(file: &String, slot: &str, message: bool) -> Result<()> {
if Path::exists(&destpath) {
// Checks if there's a file with the same name in the inventory.
bail!(
"{}",
"A file with the same name already exists in your inventory!".red()
);
throw_error(ErrorType::ExistsInventory)?;
}
if sourcepath.is_file() | sourcepath.is_symlink() {
@ -78,7 +75,7 @@ pub fn take(file: &String, slot: &str, message: bool) -> Result<()> {
let options = CopyOptions::new();
move_dir(file, &slotdir, &options)?;
} else {
bail!("{}", "No such file or directory".red());
throw_error(ErrorType::NoFileOrDir)?;
}
common::history(common::HistoryData {
@ -116,10 +113,7 @@ pub fn drop(file: &String, slot: &str, dest: PathBuf, message: bool) -> Result<(
if !ventodir.is_dir() {
// Detects if Vento hasn't been initialized and bails if so
bail!(
"{}",
"Vento not initialized. Run \"vento -i\" to initialize Vento".red()
);
throw_error(ErrorType::NotInitialized)?;
};
let slotdir: PathBuf = match slot {
@ -151,7 +145,7 @@ pub fn drop(file: &String, slot: &str, dest: PathBuf, message: bool) -> Result<(
if Path::exists(&destpath) {
// Checks if there's a file with the same name in the destination path.
bail!("{}", "A file with the same name already exists in the destination! Try renaming it or dropping this file somewhere else".red());
throw_error(ErrorType::ExistsDestination)?;
}
if sourcepath.is_file() | sourcepath.is_symlink() {
@ -163,7 +157,7 @@ pub fn drop(file: &String, slot: &str, dest: PathBuf, message: bool) -> Result<(
let options = CopyOptions::new();
move_dir(&sourcepath, destpath, &options)?;
} else {
bail!("{}", "No such file or directory".red());
throw_error(ErrorType::NoFileOrDir)?;
}
destpath.pop();

View File

@ -17,6 +17,7 @@
*
*/
pub mod archive;
pub mod common;
pub mod error;
pub mod help;