mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Re-implement `naga` development workflows using [`cargo xtask`]. Convert `make` logic and shader test configuration as file with Bash variables into an `xtask` crate and YAML files, respectively. Pros: * We now have a _portable_ workflow everywhere, which means Windows folks and people who don't install `make` don't have to suffer. 😮💨 * Workflow logic is now relatively easy to inspect and change. Whew! 💁🏻♂️💦 * Contributors can use their existing Rust knowledge to contribute to developer experience. 🎉 * `cargo xtask` is a relatively well-known convention for workflows in the ecosystem. * We can do fancy things like allow folks to run at different log levels for workflows, depending on their tastes. Cons: * There's now a non-trivial compile step to project workflow. Incremental rebuilds seem to be pretty short, though! * Code is much more verbose than the (very) terse `make` implementation. [`cargo xtask`]: https://github.com/matklad/cargo-xtask
79 lines
1.9 KiB
Rust
79 lines
1.9 KiB
Rust
use std::{
|
|
ffi::{OsStr, OsString},
|
|
fmt::{self, Display},
|
|
iter::once,
|
|
ops::{Deref, DerefMut},
|
|
process::Command,
|
|
};
|
|
|
|
use anyhow::{ensure, Context};
|
|
|
|
#[derive(Debug)]
|
|
pub(crate) struct EasyCommand {
|
|
inner: Command,
|
|
}
|
|
|
|
impl EasyCommand {
|
|
pub fn new<C>(cmd: C, config: impl FnOnce(&mut Command) -> &mut Command) -> Self
|
|
where
|
|
C: AsRef<OsStr>,
|
|
{
|
|
let mut inner = Command::new(cmd);
|
|
config(&mut inner);
|
|
Self { inner }
|
|
}
|
|
|
|
pub fn simple<C, A, I>(cmd: C, args: I) -> Self
|
|
where
|
|
C: AsRef<OsStr>,
|
|
A: AsRef<OsStr>,
|
|
I: IntoIterator<Item = A>,
|
|
{
|
|
Self::new(cmd, |cmd| cmd.args(args))
|
|
}
|
|
|
|
pub fn success(&mut self) -> anyhow::Result<()> {
|
|
let Self { inner } = self;
|
|
log::debug!("running {inner:?}");
|
|
let status = inner
|
|
.status()
|
|
.with_context(|| format!("failed to run {self}"))?;
|
|
ensure!(
|
|
status.success(),
|
|
"{self} failed to run; exit code: {:?}",
|
|
status.code()
|
|
);
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl Deref for EasyCommand {
|
|
type Target = Command;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.inner
|
|
}
|
|
}
|
|
|
|
impl DerefMut for EasyCommand {
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
&mut self.inner
|
|
}
|
|
}
|
|
|
|
pub(crate) fn which(binary_name: &str) -> anyhow::Result<OsString> {
|
|
::which::which(binary_name)
|
|
.with_context(|| format!("unable to find `{binary_name}` binary"))
|
|
.map(|buf| buf.file_name().unwrap().to_owned())
|
|
}
|
|
|
|
impl Display for EasyCommand {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let Self { inner } = self;
|
|
let prog = inner.get_program().to_string_lossy();
|
|
let args = inner.get_args().map(|a| a.to_string_lossy());
|
|
let shell_words = shell_words::join(once(prog).chain(args));
|
|
write!(f, "`{shell_words}`")
|
|
}
|
|
}
|