github_cli 0.1.0

A CLI tool for clone repository or download file from github
Documentation
use std::env;
use github_cli::utils::print_dot_every_second;
fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        println!("require a github url for clone repository or download file");
        println!("Example:");
        println!("github_cli https://github.com/songjiz/quirc-rb.git");
        println!("github_cli https://github.com/vadimcn/codelldb/releases/download/v1.9.2/codelldb-x86_64-linux.vsix");
    } else {
        let url = &args[1];
        if url.ends_with(".git"){
            git_clone_with_progress(format!("{}{}", "https://ghproxy.com/", url.replace("https://", "").replace("http://", ""))).unwrap();
        }else{
            download_file_with_progress(format!("{}{}", "https://ghproxy.com/", url.replace("https://", "").replace("http://", ""))).unwrap();
        }
    }
}
use std::io;
use std::sync::Mutex;
use indicatif::{ProgressBar, ProgressStyle};
#[allow(warnings)]
fn git_clone_with_progress(url: String) -> io::Result<()> {
    use git2::Repository;
    use std::process::Command;
    use doe::*;
    use std::sync::Arc;
    use std::thread;
    use std::time::{Duration, Instant};
    let mut error = false;
    let last_name = split_to_vec!(url.replace(".git", ""),"/").last().unwrap().to_string();
    print!("{}",url.to_string());
    print!("\ngit cloning ...");
    let stop_flag = Arc::new(Mutex::new(false));
    let stop_flag_clone = stop_flag.clone();
    let t1 = thread::spawn(move || {
        print_dot_every_second(stop_flag_clone);
    });
    let stop_flag_clone = stop_flag.clone();
    let t2 = thread::spawn(move || {
       if let Ok(repo) = Repository::clone(&url, last_name.to_string()){
        let mut flag = stop_flag.lock().unwrap();
        *flag = true;
        println!();
        Ok(())
       }else{
        Err(io::Error::new(io::ErrorKind::Other, "git clone failed,maybe folder exists"))
       }
    });
    t1.join().unwrap();
    t2.join().unwrap()
}


#[allow(warnings)]
use std::fs::File;
use std::io::{Write};
use std::path::Path;
use reqwest::Url;

fn download_file_with_progress(url: String) -> io::Result<()> {
    println!("{}",url);
    let url = Url::parse(&url).unwrap();
    let file_name = Path::new(url.path())
        .file_name()
        .and_then(|n| n.to_str())
        .unwrap_or("downloaded_file");
    let mut file = File::create(file_name)?;

    let client = reqwest::blocking::Client::new();
    let mut response = client.get(url).send().unwrap();
    let total_size = response.content_length().unwrap_or(0);

    let pb = ProgressBar::new(total_size);
    pb.set_style(
        ProgressStyle::default_bar()
            .template("{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {bytes}/{total_bytes} ({eta})").unwrap()
    );
    use std::io::Read;
    let mut downloaded = 0;
    let mut buffer = [0; 1024];
    loop {
        let bytes_read = response.read(&mut buffer)?;
        if bytes_read == 0 {
            break;
        }
        file.write_all(&buffer[..bytes_read])?;
        downloaded += bytes_read as u64;
        pb.set_position(downloaded);
    }
    pb.finish_with_message("Downloaded");
    Ok(())
}