Skip to content

Commit

Permalink
dlcrate | add util to download a rust crate for a specific version
Browse files Browse the repository at this point in the history
  • Loading branch information
the-shank committed Nov 28, 2023
1 parent 52a1629 commit d27b8f6
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 4 deletions.
36 changes: 36 additions & 0 deletions src/bin/dlcrate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use clap::Parser;
use color_eyre::eyre::eyre;
use color_eyre::eyre::Result;
use color_eyre::eyre::WrapErr;
use std::process::Command;

use utils_rs::common::parsers;

#[derive(Parser, Debug)]
struct Args {
/// name and version of the crate in the format <name>:<version>
#[arg(value_parser=parsers::parse_name_version)]
name_version: (String, String),
}

fn download(name: &str, version: &str) -> Result<()> {
let url = format!("https://static.crates.io/crates/{name}/{name}-{version}.crate");
let _ = Command::new("wget")
.arg(&url)
.arg("--output-document")
.arg(format!("{}-{}.tar.gz", name, version))
.status()
.wrap_err_with(|| eyre!("Failed to download crate from {}", url))?;
Ok(())
}

fn main() -> Result<()> {
// setup color_eyre panic and error report handlers
color_eyre::install()?;

// parse args
let args = Args::parse();

let (crate_name, version) = args.name_version;
download(&crate_name, &version)
}
20 changes: 16 additions & 4 deletions src/common/parsers.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
use std::error::Error;
// use std::error::Error;
use color_eyre::eyre::{eyre, Result};
use std::path::PathBuf;

// TODO: add tests for parse_dir
// TODO: setup CI on gitlab to run tests on every commit

// TODO: add tests
/// custom parser to validate that an arg is a directory
#[allow(dead_code)]
pub fn parse_dir(s: &str) -> Result<PathBuf, Box<dyn Error + Send + Sync + 'static>> {
pub fn parse_dir(s: &str) -> Result<PathBuf> {
let path = PathBuf::from(s);
if path.is_dir() {
Ok(path)
} else {
Err(format!("{} is not a directory", s).into())
Err(eyre!(format!("{} is not a directory", s)))
}
}

// TODO: add tests
/// custom parser to parse a crate-version input of the form
/// `<crate_name>:<crate_version>`
#[allow(dead_code)]
pub fn parse_name_version(s: &str) -> Result<(String, String)> {
let parts = s
.split_once(':')
.ok_or_else(|| eyre!("invalid input (should be in the format <name>:<version>)"))?;
Ok((String::from(parts.0), String::from(parts.1)))
}

0 comments on commit d27b8f6

Please sign in to comment.