Merge branch 'master' of gitea.tforgione.fr:tforgione/gclone
This commit is contained in:
commit
c44c9fe789
|
@ -11,6 +11,7 @@ name = "gclone"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"colored 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"colored 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -18,6 +19,57 @@ name = "lazy_static"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "same-file"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "walkdir"
|
||||||
|
version = "2.2.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
"checksum colored 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e9a455e156a4271e12fd0246238c380b1e223e3736663c7a18ed8b6362028a9"
|
"checksum colored 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e9a455e156a4271e12fd0246238c380b1e223e3736663c7a18ed8b6362028a9"
|
||||||
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
|
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
|
||||||
|
"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
|
||||||
|
"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1"
|
||||||
|
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
|
||||||
|
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
|
||||||
|
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
|
@ -6,11 +6,12 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
colored = "1.7.0"
|
colored = "1.7.0"
|
||||||
|
walkdir = "2.2.7"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "gclone"
|
name = "gclone"
|
||||||
path = "src/gclone.rs"
|
path = "src/gclone.rs"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "cdg"
|
name = "pgd"
|
||||||
path = "src/cdg.rs"
|
path = "src/pgd.rs"
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
use gclone::Cache;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let cache = Cache::read();
|
|
||||||
}
|
|
|
@ -6,7 +6,7 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
use colored::*;
|
use colored::*;
|
||||||
|
|
||||||
use gclone::{git_dir, Cache};
|
use gclone::{git_dir, Cache, Result};
|
||||||
|
|
||||||
macro_rules! unwrap {
|
macro_rules! unwrap {
|
||||||
($e: expr) => {
|
($e: expr) => {
|
||||||
|
@ -55,9 +55,9 @@ fn help() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() -> Result<()> {
|
||||||
|
|
||||||
let git_dir = git_dir();
|
let git_dir = git_dir()?;
|
||||||
|
|
||||||
// Parse args
|
// Parse args
|
||||||
let url = match env::args().nth(1) {
|
let url = match env::args().nth(1) {
|
||||||
|
@ -72,7 +72,7 @@ fn main() {
|
||||||
};
|
};
|
||||||
|
|
||||||
if url == "-h" || url == "--help" {
|
if url == "-h" || url == "--help" {
|
||||||
return help();
|
return Ok(help());
|
||||||
}
|
}
|
||||||
|
|
||||||
let (server, owner, repo) = match parse_url(&url) {
|
let (server, owner, repo) = match parse_url(&url) {
|
||||||
|
@ -137,7 +137,7 @@ fn main() {
|
||||||
eprintln!("{} {}", "info:".bold(), "done!");
|
eprintln!("{} {}", "info:".bold(), "done!");
|
||||||
|
|
||||||
// Append to cache
|
// Append to cache
|
||||||
let mut cache = Cache::read();
|
let mut cache = Cache::read()?;
|
||||||
cache.append(path.display().to_string());
|
cache.append(path.display().to_string());
|
||||||
|
|
||||||
match cache.write() {
|
match cache.write() {
|
||||||
|
@ -150,4 +150,6 @@ fn main() {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
29
src/lib.rs
29
src/lib.rs
|
@ -6,6 +6,7 @@ use std::fs::File;
|
||||||
use std::io::{self, Write, BufRead, BufReader};
|
use std::io::{self, Write, BufRead, BufReader};
|
||||||
|
|
||||||
use colored::*;
|
use colored::*;
|
||||||
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
macro_rules! impl_from_error {
|
macro_rules! impl_from_error {
|
||||||
($type: ty, $variant: path, $from: ty) => {
|
($type: ty, $variant: path, $from: ty) => {
|
||||||
|
@ -43,11 +44,9 @@ impl fmt::Display for MError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for MError {
|
impl Error for MError {}
|
||||||
|
|
||||||
}
|
pub type Result<T> = result::Result<T, MError>;
|
||||||
|
|
||||||
type Result<T> = result::Result<T, MError>;
|
|
||||||
|
|
||||||
pub fn git_dir() -> Result<String> {
|
pub fn git_dir() -> Result<String> {
|
||||||
Ok(env::var("GCLONE_PATH")?)
|
Ok(env::var("GCLONE_PATH")?)
|
||||||
|
@ -56,6 +55,16 @@ pub fn git_dir() -> Result<String> {
|
||||||
pub struct Cache(Vec<String>);
|
pub struct Cache(Vec<String>);
|
||||||
|
|
||||||
impl Cache {
|
impl Cache {
|
||||||
|
|
||||||
|
pub fn new() -> Result<Cache> {
|
||||||
|
Ok(Cache(WalkDir::new(git_dir()?)
|
||||||
|
.max_depth(3)
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|x| x.ok())
|
||||||
|
.map(|x| x.path().display().to_string())
|
||||||
|
.collect()))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read() -> Result<Cache> {
|
pub fn read() -> Result<Cache> {
|
||||||
|
|
||||||
let mut path = PathBuf::from(git_dir()?);
|
let mut path = PathBuf::from(git_dir()?);
|
||||||
|
@ -91,6 +100,18 @@ impl Cache {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find(&self, dirname: &str) -> Vec<String> {
|
||||||
|
let dirname = &format!("/{}", dirname);
|
||||||
|
let mut matches = vec![];
|
||||||
|
for line in &self.0 {
|
||||||
|
if line.ends_with(dirname) {
|
||||||
|
matches.push(line.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
matches
|
||||||
|
}
|
||||||
|
|
||||||
pub fn append(&mut self, value: String) {
|
pub fn append(&mut self, value: String) {
|
||||||
self.0.push(value);
|
self.0.push(value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
use std::env;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::process::exit;
|
||||||
|
use std::io::{stdout, stdin, Write};
|
||||||
|
use std::num::Wrapping;
|
||||||
|
use colored::*;
|
||||||
|
use gclone::Cache;
|
||||||
|
|
||||||
|
fn flush_stdout() {
|
||||||
|
stdout().flush().ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let request = match env::args().nth(1) {
|
||||||
|
Some(arg) => arg,
|
||||||
|
None => {
|
||||||
|
eprintln!("{} {}",
|
||||||
|
"error:".bold().red(),
|
||||||
|
"cdg expects an argument".bold());
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
main_with_cache(&request, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main_with_cache(request: &str, regen: bool) {
|
||||||
|
|
||||||
|
let cache = Cache::read();
|
||||||
|
|
||||||
|
let matches = cache.find(&request);
|
||||||
|
|
||||||
|
match matches.len() {
|
||||||
|
0 => {
|
||||||
|
|
||||||
|
if regen {
|
||||||
|
eprintln!("{} {}",
|
||||||
|
"warning:".bold().yellow(),
|
||||||
|
"directory not found, regenerating cache...".bold());
|
||||||
|
|
||||||
|
let cache = Cache::new();
|
||||||
|
|
||||||
|
match cache.write() {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("{} {} {}",
|
||||||
|
"warning:".bold().yellow(),
|
||||||
|
"couldn't write cache:".bold(),
|
||||||
|
e.description());
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return main_with_cache(request, false);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
eprintln!("{} {}",
|
||||||
|
"error:".bold().red(),
|
||||||
|
"no such directory".bold());
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
1 => {
|
||||||
|
println!("{}", matches[0]);
|
||||||
|
},
|
||||||
|
|
||||||
|
len => {
|
||||||
|
|
||||||
|
eprintln!("{}", "info: multiple entries found, please select one".bold());
|
||||||
|
|
||||||
|
for (i, j) in matches.iter().enumerate() {
|
||||||
|
eprintln!("{} {}",
|
||||||
|
&format!("[{}]", i + 1).bold().blue(),
|
||||||
|
&format!("{}", j).yellow());
|
||||||
|
}
|
||||||
|
|
||||||
|
eprint!("{}", "Enter your choice: ".bold());
|
||||||
|
flush_stdout();
|
||||||
|
|
||||||
|
let mut string = String::new();
|
||||||
|
match stdin().read_line(&mut string) {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("{} {} {}",
|
||||||
|
"error:".bold().red(),
|
||||||
|
"couldn't read line:".bold(),
|
||||||
|
e.description());
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Pop the trailing \n of the string
|
||||||
|
string.pop();
|
||||||
|
|
||||||
|
// Use wrapping to move 0 to std::usize::MAX which is ok.
|
||||||
|
let value = (Wrapping(match string.parse::<usize>() {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("{} {} {}",
|
||||||
|
"error:".bold().red(),
|
||||||
|
"couldn't parse integer:".bold(),
|
||||||
|
e.description());
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}) - Wrapping(1)).0;
|
||||||
|
|
||||||
|
if value >= len {
|
||||||
|
eprintln!("{} {}",
|
||||||
|
"error:".bold().red(),
|
||||||
|
"integer wasn't in the right range".bold());
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{}", matches[value]);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue