//! 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)] #[macro_use] extern crate log; use std::io; use std::{env, error, fmt, num, result}; 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), /// 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, "couldn't read environment variable GCLONE_PATH {}", e ), Error::IoError(e) => write!( fmt, "couldn't read or write cache: {}", e ), Error::GitUrlParseError => write!( fmt, "couldn't guess server, owner and repo from url" ), Error::GitCloneError(Some(e)) => write!( fmt, "couldn't clone git repository: {}", e ), Error::GitCloneError(None) => write!( fmt, "couldn't clone git repository" ), Error::PathAlreadyExists => write!( fmt, "the path corresponding to the repository already exists" ), Error::WrongArgument => write!( fmt, "this program expects exactly one argument" ), Error::ParseIntError(e) => write!( fmt, "couldn't parse integer: {}", e ), Error::OutsideRange => write!( fmt, "integer is outside the range" ), Error::NoSuchDirectory => write!( fmt, "no such directory was found" ), } } } impl error::Error for Error {} /// The result type of gclone. pub type Result = result::Result; /// Gets the single argument of the program. pub fn first_arg() -> Result { env::args().nth(1).ok_or(Error::WrongArgument) }