use crate::manifest::Manifest;
use crate::meme::Meme;
use anyhow::Context;
use std::path::PathBuf;
use std::process::Command;
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
#[structopt(name = "build")]
pub struct BuildCommand {
#[structopt(long, parse(from_os_str))]
manifest_path: Option<PathBuf>,
meme: Option<String>,
#[structopt(long)]
bin: Option<String>,
#[structopt(long)]
example: Option<String>,
#[structopt(long)]
release: bool,
#[structopt(long)]
subreddit: Option<String>,
}
impl BuildCommand {
pub fn run(&self) -> anyhow::Result<BuildOutput> {
let meme = if let Some(ref subreddit) = self.subreddit {
Meme::fetch_random_meme(subreddit)?
.context(format!("No jpeg meme found on subreddit {}", subreddit))?
} else {
if let Some(ref meme) = self.meme {
Meme::new(meme)?
} else {
if let Ok(Some(meme)) = Meme::fetch_random_meme("rustjerk") {
meme
} else {
if self.release {
Meme::new("release")?
} else {
Meme::new("debug")?
}
}
}
};
let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_string());
let mut cmd = Command::new(cargo);
cmd.arg("build");
let (manifest, mut bin_path) = if let Some(ref path) = self.manifest_path {
cmd.arg("--manifest-path").arg(path);
(
Manifest::new(path)?,
path.parent()
.map(|p| p.to_path_buf())
.unwrap_or_else(|| PathBuf::from(".")),
)
} else {
(Manifest::new("./Cargo.toml")?, PathBuf::from("."))
};
bin_path.push("target");
if self.release {
cmd.arg("--release");
bin_path.push("release");
} else {
bin_path.push("debug");
}
let bin_name = if let Some(ref bin) = self.bin {
cmd.arg("--bin").arg(bin);
bin.clone()
} else if let Some(ref example) = self.example {
cmd.arg("--example").arg(example);
bin_path.push("examples");
example.clone()
} else {
manifest.name()?.to_string()
};
bin_path.push(&bin_name);
log::debug!("Executing: `{:?}`", cmd);
let child = cmd.spawn()?;
let output = child
.wait_with_output()
.context(format!("Error executing `{:?}`", cmd))?;
if !output.status.success() {
anyhow::bail!(
"`{:?}` failed with exit code: {:?}",
cmd,
output.status.code()
);
}
let mut meme_path = bin_path.clone();
meme_path.set_extension("jpeg");
meme.write_with_bin_to(&bin_path, &meme_path)?;
Ok(BuildOutput {
meme_path,
bin_path,
bin_name,
})
}
}
pub struct BuildOutput {
pub meme_path: PathBuf,
pub bin_path: PathBuf,
pub bin_name: String,
}