pavex_cli 0.2.10

The companion CLI for Pavex, a Rust framework to build API services and web applications.
Documentation
use crate::cli_kind::CliKind;
use anyhow::Context;
use std::path::Path;
use std::process::Stdio;

pub enum Source {
    CratesIo { version: String },
    Git { url: String, rev: GitSourceRevision },
}

pub enum GitSourceRevision {
    Rev(String),
    Tag(String),
    Branch(String),
}

/// Install a single binary via `cargo install` and copy it to the specified destination path.
pub fn cargo_install(
    source: Source,
    kind: CliKind,
    destination: &Path,
) -> Result<(), anyhow::Error> {
    let temp_dir = tempfile::tempdir()?;
    let mut cmd = std::process::Command::new("cargo");
    cmd.arg("install")
        .arg("--root")
        .arg(temp_dir.path())
        .arg("--bin")
        .arg(kind.binary_target_name());
    match source {
        Source::CratesIo { version } => {
            cmd.arg("--version");
            cmd.arg(&version);
        }
        Source::Git { url, rev } => {
            cmd.arg("--git");
            cmd.arg(&url);
            match rev {
                GitSourceRevision::Rev(rev) => {
                    cmd.arg("--rev");
                    cmd.arg(&rev);
                }
                GitSourceRevision::Tag(tag) => {
                    cmd.arg("--tag");
                    cmd.arg(&tag);
                }
                GitSourceRevision::Branch(branch) => {
                    cmd.arg("--branch");
                    cmd.arg(&branch);
                }
            }
        }
    }
    cmd.arg(kind.package_name());
    let cmd_debug = format!("{:?}", &cmd);
    let output = cmd
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .output()
        .with_context(|| format!("`{cmd_debug}` failed"))?;
    if !output.status.success() {
        anyhow::bail!("`{cmd_debug}` failed");
    }
    fs_err::copy(
        temp_dir.path().join("bin").join(kind.binary_filename()),
        destination,
    )?;
    Ok(())
}