diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 00000000..35049cbc --- /dev/null +++ b/.cargo/config @@ -0,0 +1,2 @@ +[alias] +xtask = "run --package xtask --" diff --git a/Cargo.toml b/Cargo.toml index b81f1ae6..ef83f41f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -119,7 +119,8 @@ harness = false members = [ "pyo3-macros", "pyo3-macros-backend", - "examples" + "examples", + "xtask" ] [package.metadata.docs.rs] diff --git a/Makefile b/Makefile index 20e7fa71..229575d0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ .PHONY: test test_py publish clippy lint fmt fmt_py fmt_rust ALL_ADDITIVE_FEATURES = macros multiple-pymethods num-bigint num-complex hashbrown serde indexmap eyre anyhow +COVERAGE_PACKAGES = --package pyo3 --package pyo3-build-config --package pyo3-macros-backend --package pyo3-macros list_all_additive_features: @echo $(ALL_ADDITIVE_FEATURES) @@ -25,6 +26,21 @@ fmt_rust: fmt: fmt_rust fmt_py @true +coverage: + # cargo llvm-cov clean --workspace + # cargo llvm-cov $(COVERAGE_PACKAGES) --no-report + # cargo llvm-cov $(COVERAGE_PACKAGES) --no-report --features abi3 + # cargo llvm-cov $(COVERAGE_PACKAGES) --no-report --features $(ALL_ADDITIVE_FEATURES) + # cargo llvm-cov $(COVERAGE_PACKAGES) --no-report --features abi3 $(ALL_ADDITIVE_FEATURES) + bash -c "\ + set -a\ + source <(cargo llvm-cov show-env)\ + export TOX_TESTENV_PASSENV=*\ + make test_py\ + " + cargo llvm-cov $(COVERAGE_PACKAGES) --no-run --summary-only + + clippy: cargo clippy --features="$(ALL_ADDITIVE_FEATURES)" --all-targets --workspace -- -Dwarnings cargo clippy --features="abi3 $(ALL_ADDITIVE_FEATURES)" --all-targets --workspace -- -Dwarnings diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml new file mode 100644 index 00000000..f147d000 --- /dev/null +++ b/xtask/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "xtask" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1.0.51" +clap = { version = "3.0.0-rc.7", features = ["derive"] } diff --git a/xtask/src/main.rs b/xtask/src/main.rs new file mode 100644 index 00000000..b077c5cc --- /dev/null +++ b/xtask/src/main.rs @@ -0,0 +1,57 @@ +use anyhow::Result; +use clap::Parser; +use std::{collections::HashMap, process::Command}; + +#[derive(Parser)] +enum Subcommand { + Coverage, +} + +fn main() -> Result<()> { + match Subcommand::parse() { + Subcommand::Coverage => { + run(&mut llvm_cov_command(&["clean", "--workspace"]))?; + // FIXME: run (including with various feature combinations) + // run(&mut llvm_cov_command(&["--no-report"]))?; + let env = get_coverage_env()?; + for entry in std::fs::read_dir("pytests")? { + let path = entry?.path(); + if path.is_dir() { + run(Command::new("tox").arg("-c").arg(path).envs(&env))?; + } + } + // FIXME: also run for examples + // FIXME: make it possible to generate lcov report too + run(&mut llvm_cov_command(&["--no-run", "--summary-only"]))?; + } + } + Ok(()) +} + +fn run(command: &mut Command) -> Result<()> { + command.spawn()?.wait()?; + Ok(()) +} + +fn llvm_cov_command(args: &[&str]) -> Command { + let mut command = Command::new("cargo"); + command.args(["llvm-cov", "--package=pyo3"]).args(args); + command +} + +fn get_coverage_env() -> Result> { + let mut env = HashMap::new(); + + let output = String::from_utf8(llvm_cov_command(&["show-env"]).output()?.stdout)?; + + for line in output.trim().split('\n') { + // TODO use split_once on MSRV 1.52 + let mut iter = line.splitn(2, '='); + env.insert(iter.next().unwrap().into(), iter.next().unwrap().trim_matches('"').into()); + } + + env.insert("TOX_TESTENV_PASSENV".to_owned(), "*".to_owned()); + env.insert("RUSTUP_TOOLCHAIN".to_owned(), "nightly".to_owned()); + + Ok(env) +}