use std::{
path::Path,
process::{Command, Stdio},
};
use crate::{Cmd, CmdExt as _, Spawned, SpawnedExt as _};
pub fn fmt(root: &Path) -> Cmd {
Command::new("cargo")
.current_dir(root)
.arg("fmt")
.output()
.into_cmd("fmt")
}
pub fn git_add(root: &Path) -> Cmd {
Command::new("git")
.current_dir(root)
.arg("add")
.arg(".")
.output()
.into_cmd("git add")
}
pub fn clippy(root: &Path) -> Spawned {
Command::new("cargo")
.current_dir(root)
.arg("clippy")
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.into_spawned("clippy")
}
pub fn clippy_tests(root: &Path) -> Spawned {
Command::new("cargo")
.current_dir(root)
.arg("clippy")
.arg("--tests")
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.into_spawned("clippy the tests")
}
pub fn test(root: &Path) -> Spawned {
Command::new("cargo")
.current_dir(root)
.arg("test")
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.into_spawned("tests")
}
pub fn build(
root: &Path,
target: &Option<String>,
glibc: &Option<String>,
release: &bool,
) -> Spawned {
let BuildArgs { builder, target } = BuildArgs::parse(target, glibc);
let release = if *release { Some("--release") } else { None };
Command::new("cargo")
.current_dir(root)
.arg(builder)
.args(release)
.args(target)
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.into_spawned("build")
}
struct BuildArgs {
builder: &'static str,
target: Vec<String>,
}
impl BuildArgs {
fn parse(target: &Option<String>, glibc: &Option<String>) -> Self {
if target.is_none() && glibc.is_none() {
return Self {
builder: "build",
target: vec![],
};
}
let builder = "zigbuild";
let target_triple = target.clone().unwrap_or_else(default_triple);
let full_target = match glibc {
Some(version) => format!("{}.{}", target_triple, version),
None => target_triple,
};
Self {
builder,
target: vec!["--target".into(), full_target],
}
}
}
fn default_triple() -> String {
match Command::new("rustc")
.arg("--print")
.arg("host-tuple")
.output()
{
Ok(output) => String::from_utf8_lossy(&output.stdout).trim().to_string(),
Err(_) => "x86_64-unknown-linux-gnu".to_string(),
}
}
#[cfg(test)]
mod tests {
use super::*;
mod generate_target {
use super::*;
const FLAG: &str = "--target";
#[test]
fn glibc() {
let expected_target: Vec<String> =
vec![FLAG.into(), format!("{}.2.41", default_triple())];
let generated = BuildArgs::parse(&None, &Some("2.41".into()));
let BuildArgs { builder, target } = generated;
assert_eq!(builder, "zigbuild");
assert_eq!(target, expected_target)
}
#[test]
fn default() {
let expected_target: Vec<String> = vec![];
let generated = BuildArgs::parse(&None, &None);
let BuildArgs { builder, target } = generated;
assert_eq!(builder, "build");
assert_eq!(target, expected_target)
}
#[test]
fn both_specified() {
let expected_target: Vec<String> =
vec![FLAG.into(), "x86_64-unknown-linux-musl.2.41".into()];
let generated = BuildArgs::parse(
&Some("x86_64-unknown-linux-musl".into()),
&Some("2.41".into()),
);
let BuildArgs { builder, target } = generated;
assert_eq!(builder, "zigbuild");
assert_eq!(target, expected_target)
}
#[test]
fn triple() {
let expected_target: Vec<String> =
vec![FLAG.into(), "x86_64-unknown-linux-musl".into()];
let generated = BuildArgs::parse(&Some("x86_64-unknown-linux-musl".into()), &None);
let BuildArgs { builder, target } = generated;
assert_eq!(builder, "zigbuild");
assert_eq!(target, expected_target)
}
}
}