Simple Check Feature Task xtask (#7041)

This commit is contained in:
Connor Fitzgerald 2025-01-31 12:59:29 -05:00 committed by GitHub
parent 7cde4707ec
commit ad194a8a3e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 154 additions and 20 deletions

View File

@ -780,3 +780,22 @@ jobs:
command: check bans licenses sources
arguments: --all-features --workspace
rust-version: ${{ env.REPO_MSRV }}
check-feature-dependencies:
# runtime is normally 1 minute
timeout-minutes: 5
name: "Feature Dependencies"
runs-on: ubuntu-latest
steps:
- name: checkout repo
uses: actions/checkout@v4
- name: Install Repo MSRV toolchain
run: |
rustup toolchain install ${{ env.REPO_MSRV }} --no-self-update --profile=minimal
rustup override set ${{ env.REPO_MSRV }}
cargo -V
- name: Run `cargo feature-dependencies`
run: cargo xtask check-feature-dependencies

View File

@ -0,0 +1,114 @@
use pico_args::Arguments;
use xshell::Shell;
#[derive(Debug)]
enum Search<'a> {
#[expect(dead_code)]
Positive(&'a str),
Negative(&'a str),
}
#[derive(Debug)]
struct Requirement<'a> {
human_readable_name: &'a str,
target: &'a str,
packages: &'a [&'a str],
features: &'a [&'a str],
default_features: bool,
search_terms: &'a [Search<'a>],
}
const ALL_WGPU_FEATURES: &[&str] = &[
"dx12",
"metal",
"webgpu",
"angle",
"vulkan-portability",
"webgl",
"spirv",
"glsl",
"wgsl",
"naga-ir",
"serde",
"replay",
"counters",
"fragile-send-sync-non-atomic-wasm",
"static-dxc",
];
pub fn check_feature_dependencies(shell: Shell, arguments: Arguments) -> anyhow::Result<()> {
let mut _args = arguments.finish();
let features_no_webgl: Vec<&str> = ALL_WGPU_FEATURES
.iter()
.copied()
.filter(|feature| *feature != "webgl")
.collect();
let requirements = [
Requirement {
human_readable_name: "wasm32 without `webgl` feature does not depend on `wgpu-core`",
target: "wasm32-unknown-unknown",
packages: &["wgpu"],
features: &features_no_webgl,
default_features: false,
search_terms: &[Search::Negative("wgpu-core")],
},
Requirement {
human_readable_name:
"wasm32 with `webgpu` and `wgsl` feature does not depend on `naga`",
target: "wasm32-unknown-unknown",
packages: &["wgpu"],
features: &["webgpu", "wgsl"],
default_features: false,
search_terms: &[Search::Negative("naga")],
},
];
let mut any_failures = false;
for requirement in requirements {
let mut cmd = shell
.cmd("cargo")
.args(["tree", "--target", requirement.target]);
for package in requirement.packages {
cmd = cmd.arg("--package").arg(package);
}
if !requirement.default_features {
cmd = cmd.arg("--no-default-features");
}
if !requirement.features.is_empty() {
cmd = cmd.arg("--features").arg(requirement.features.join(","));
}
log::info!("Checking Requirement: {}", requirement.human_readable_name);
log::debug!("{:#?}", requirement);
log::debug!("$ {cmd}");
let output = cmd.read()?;
log::debug!("{output}");
for search_term in requirement.search_terms {
let found = match search_term {
Search::Positive(search_term) => output.contains(search_term),
Search::Negative(search_term) => !output.contains(search_term),
};
if found {
log::info!("✅ Passed!");
} else {
log::info!("❌ Failed");
any_failures = true;
}
}
}
if any_failures {
anyhow::bail!("Some feature dependencies are not met");
}
Ok(())
}

View File

@ -3,6 +3,7 @@ use std::process::ExitCode;
use anyhow::Context;
use pico_args::Arguments;
mod check_feature_dependencies;
mod run_wasm;
mod test;
mod util;
@ -12,6 +13,9 @@ const HELP: &str = "\
Usage: xtask <COMMAND>
Commands:
check-feature-dependencies
Check certain dependency invariants are upheld.
run-wasm
Build and run web examples
@ -71,6 +75,9 @@ fn main() -> anyhow::Result<ExitCode> {
shell.change_dir(String::from(env!("CARGO_MANIFEST_DIR")) + "/..");
match subcommand.as_deref() {
Some("check-feature-dependencies") => {
check_feature_dependencies::check_feature_dependencies(shell, args)?
}
Some("run-wasm") => run_wasm::run_wasm(shell, args)?,
Some("test") => test::run_tests(shell, args)?,
Some("vendor-web-sys") => vendor_web_sys::run_vendor_web_sys(shell, args)?,

View File

@ -6,28 +6,22 @@ use xshell::Shell;
use crate::util::{check_all_programs, Program};
pub(crate) fn run_wasm(shell: Shell, mut args: Arguments) -> anyhow::Result<()> {
let no_serve = args.contains("--no-serve");
let should_serve = !args.contains("--no-serve");
let release = args.contains("--release");
let programs_needed: &[_] = if no_serve {
&[Program {
let mut programs_needed = vec![Program {
crate_name: "wasm-bindgen-cli",
binary_name: "wasm-bindgen",
}]
} else {
&[
Program {
crate_name: "wasm-bindgen-cli",
binary_name: "wasm-bindgen",
},
Program {
}];
if should_serve {
programs_needed.push(Program {
crate_name: "simple-http-server",
binary_name: "simple-http-server",
},
]
};
});
}
check_all_programs(programs_needed)?;
check_all_programs(&programs_needed)?;
let release_flag: &[_] = if release { &["--release"] } else { &[] };
let output_dir = if release { "release" } else { "debug" };
@ -91,7 +85,7 @@ pub(crate) fn run_wasm(shell: Shell, mut args: Arguments) -> anyhow::Result<()>
.with_context(|| format!("Failed to copy static file \"{}\"", file.display()))?;
}
if !no_serve {
if should_serve {
log::info!("serving on port 8000");
// Explicitly specify the IP address to 127.0.0.1 since otherwise simple-http-server will