131 lines
3.9 KiB
Rust
131 lines
3.9 KiB
Rust
//! This crate contains the gclone and pgd commands.
|
|
//!
|
|
//! The `gclone` command automatically clones a git repository and puts it in the right place.
|
|
//! The `pgd` command manages a cache for efficiently being able to print a directory corresponding
|
|
//! to a repo or an owner. You can then add the following to automatically `cd` to a directory:
|
|
//! ``` zsh
|
|
//! cdg() {
|
|
//! local newdir
|
|
//! newdir=$(pgd $1) && cd $newdir
|
|
//! }
|
|
//! ```
|
|
|
|
#![warn(missing_docs)]
|
|
|
|
use std::{env, fmt, num, error, result};
|
|
use std::io;
|
|
|
|
use colored::*;
|
|
|
|
mod cache;
|
|
pub use cache::Cache;
|
|
|
|
pub mod git;
|
|
|
|
macro_rules! impl_from_error {
|
|
($type: ty, $variant: path, $from: ty) => {
|
|
impl From<$from> for $type {
|
|
fn from(e: $from) -> $type {
|
|
$variant(e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
/// The error type of gclone.
|
|
pub enum Error {
|
|
/// Couldn't read the GCLONE_PATH env.
|
|
NoGclonePath(env::VarError),
|
|
|
|
/// An error occured while manipulating files.
|
|
IoError(io::Error),
|
|
|
|
/// Couldn't parse git url.
|
|
GitUrlParseError,
|
|
|
|
/// Couldn't clone the respository.
|
|
GitCloneError(Option<io::Error>),
|
|
|
|
/// The specified directory already exists.
|
|
PathAlreadyExists,
|
|
|
|
/// The binaries of this crate require exactly one argument.
|
|
WrongArgument,
|
|
|
|
/// An error while parsing an int.
|
|
ParseIntError(num::ParseIntError),
|
|
|
|
/// A value is outside a range.
|
|
OutsideRange,
|
|
|
|
/// No such directory was found.
|
|
NoSuchDirectory,
|
|
}
|
|
|
|
impl_from_error!(Error, Error::NoGclonePath, env::VarError);
|
|
impl_from_error!(Error, Error::IoError, io::Error);
|
|
impl_from_error!(Error, Error::ParseIntError, num::ParseIntError);
|
|
|
|
impl fmt::Display for Error {
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
|
match self {
|
|
Error::NoGclonePath(e) =>
|
|
write!(fmt, "{} {} {}",
|
|
"error:".bold().red(),
|
|
"couldn't read environment variable GCLONE_PATH".bold(),
|
|
e),
|
|
Error::IoError(e) =>
|
|
write!(fmt, "{} {} {}",
|
|
"error:".bold().red(),
|
|
"couldn't read or write cache:".bold(),
|
|
e),
|
|
Error::GitUrlParseError =>
|
|
write!(fmt, "{} {}",
|
|
"error:".bold().red(),
|
|
"couldn't guess server, owner and repo from url".bold()),
|
|
Error::GitCloneError(Some(e)) =>
|
|
write!(fmt, "{} {} {}",
|
|
"error:".bold().red(),
|
|
"couldn't clone git repository:".bold(),
|
|
e),
|
|
Error::GitCloneError(None) =>
|
|
write!(fmt, "{} {}",
|
|
"error:".bold().red(),
|
|
"couldn't clone git repository".bold()),
|
|
Error::PathAlreadyExists =>
|
|
write!(fmt, "{} {}",
|
|
"error:".bold().red(),
|
|
"the path corresponding to the repository already exists".bold()),
|
|
Error::WrongArgument =>
|
|
write!(fmt, "{} {}",
|
|
"error:".bold().red(),
|
|
"this program expects exactly one argument".bold()),
|
|
Error::ParseIntError(e) =>
|
|
write!(fmt, "{} {} {}",
|
|
"error:".bold().red(),
|
|
"couldn't parse integer:".bold(),
|
|
e),
|
|
Error::OutsideRange =>
|
|
write!(fmt, "{} {}",
|
|
"error:".bold().red(),
|
|
"integer is outside the range".bold()),
|
|
Error::NoSuchDirectory =>
|
|
write!(fmt, "{} {}",
|
|
"error:".bold().red(),
|
|
"no such directory was found".bold()),
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
impl error::Error for Error {}
|
|
|
|
/// The result type of gclone.
|
|
pub type Result<T> = result::Result<T, Error>;
|
|
|
|
/// Gets the single argument of the program.
|
|
pub fn first_arg() -> Result<String> {
|
|
env::args().nth(1).ok_or(Error::WrongArgument)
|
|
}
|