Drop the xtask helper as it is superseded by Nox.
While the xtask code base is better engineered than our slightly messy Nox manifest, all functionality is available via Nox including some that is not available via xtask. Finally, only the Nox sessions are used in the CI by now so that xtask does not see regular automated usage.
This commit is contained in:
parent
f1b6cb9256
commit
b816d4d561
|
@ -1,6 +1,3 @@
|
|||
[alias]
|
||||
xtask = "run --package xtask --"
|
||||
|
||||
[target.'cfg(feature = "cargo-clippy")']
|
||||
rustflags = [
|
||||
# Lints to enforce in CI
|
||||
|
@ -11,6 +8,7 @@ rustflags = [
|
|||
"-Dclippy::filter_map_next",
|
||||
"-Dclippy::flat_map_option",
|
||||
"-Dclippy::let_unit_value",
|
||||
"-Dclippy::manual_assert",
|
||||
"-Dclippy::manual_ok_or",
|
||||
"-Dclippy::todo",
|
||||
"-Dclippy::unnecessary_wraps",
|
||||
|
|
|
@ -53,7 +53,7 @@ mv target/guide netlify_build/main/
|
|||
|
||||
## Build public docs
|
||||
|
||||
cargo xtask doc
|
||||
nox -s docs
|
||||
mv target/doc netlify_build/main/doc/
|
||||
|
||||
echo "<meta http-equiv=refresh content=0;url=pyo3/>" > netlify_build/main/doc/index.html
|
||||
|
@ -61,7 +61,7 @@ echo "<meta http-equiv=refresh content=0;url=pyo3/>" > netlify_build/main/doc/in
|
|||
## Build internal docs
|
||||
|
||||
echo "<div class='internal-banner' style='position:fixed; z-index: 99999; color:red;border:3px solid red;margin-left: auto; margin-right: auto; width: 430px;left:0;right: 0;'><div style='display: flex; align-items: center; justify-content: center;'> ⚠️ Internal Docs ⚠️ Not Public API 👉 <a href='https://pyo3.rs/main/doc/pyo3/index.html' style='color:red;text-decoration:underline;'>Official Docs Here</a></div></div>" > netlify_build/banner.html
|
||||
RUSTDOCFLAGS="--html-before-content netlify_build/banner.html" cargo xtask doc --internal
|
||||
RUSTDOCFLAGS="--html-before-content netlify_build/banner.html" nox -s docs -- nightly internal
|
||||
rm netlify_build/banner.html
|
||||
|
||||
mkdir -p netlify_build/internal
|
||||
|
|
|
@ -186,7 +186,6 @@ members = [
|
|||
"pyo3-macros-backend",
|
||||
"pytests",
|
||||
"examples",
|
||||
"xtask"
|
||||
]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
|
|
|
@ -51,7 +51,7 @@ There are some specific areas of focus where help is currently needed for the do
|
|||
You can build the docs (including all features) with
|
||||
|
||||
```shell
|
||||
cargo xtask doc --open
|
||||
nox -s docs -- open
|
||||
```
|
||||
|
||||
#### Doctests
|
||||
|
@ -95,8 +95,10 @@ Tests run with all supported Python versions with the latest stable Rust compile
|
|||
If you are adding a new feature, you should add it to the `full` feature in our *Cargo.toml** so that it is tested in CI.
|
||||
|
||||
You can run these tests yourself with
|
||||
```cargo xtask ci```
|
||||
See [its documentation](https://github.com/PyO3/pyo3/tree/main/xtask#readme) for more commands you can run.
|
||||
```nox```
|
||||
and
|
||||
```nox -l```
|
||||
lists further commands you can run.
|
||||
|
||||
### Documenting changes
|
||||
|
||||
|
@ -145,7 +147,7 @@ You can view what code is and isn't covered by PyO3's tests. We aim to have 100%
|
|||
|
||||
- First, generate a `lcov.info` file with
|
||||
```shell
|
||||
cargo xtask coverage
|
||||
nox -s coverage
|
||||
```
|
||||
You can install an IDE plugin to view the coverage. For example, if you use VSCode:
|
||||
- Add the [coverage-gutters](https://marketplace.visualstudio.com/items?itemName=ryanluker.vscode-coverage-gutters) plugin.
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
[package]
|
||||
name = "xtask"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[[bin]]
|
||||
name = "xtask"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.51"
|
||||
|
||||
# Clap 3 requires MSRV 1.54
|
||||
structopt = { version = "0.3", default-features = false }
|
||||
clap = { version = "2" }
|
|
@ -1,23 +0,0 @@
|
|||
## Commands to test PyO3.
|
||||
|
||||
To run these commands, you should be in PyO3's root directory, and run (for example) `cargo xtask ci`.
|
||||
|
||||
```
|
||||
USAGE:
|
||||
xtask.exe <SUBCOMMAND>
|
||||
|
||||
FLAGS:
|
||||
-h, --help Prints help information
|
||||
-V, --version Prints version information
|
||||
|
||||
SUBCOMMANDS:
|
||||
ci Runs everything
|
||||
clippy Runs `clippy`, denying all warnings
|
||||
coverage Runs `cargo llvm-cov` for the PyO3 codebase
|
||||
default Only runs the fast things (this is used if no command is specified)
|
||||
doc Attempts to render the documentation
|
||||
fmt Checks Rust and Python code formatting with `rustfmt` and `black`
|
||||
help Prints this message or the help of the given subcommand(s)
|
||||
test Runs various variations on `cargo test`
|
||||
test-py Runs the tests in examples/ and pytests/
|
||||
```
|
216
xtask/src/cli.rs
216
xtask/src/cli.rs
|
@ -1,216 +0,0 @@
|
|||
use crate::utils::*;
|
||||
use anyhow::{ensure, Result};
|
||||
use std::io;
|
||||
use std::process::{Command, Output};
|
||||
use std::time::Instant;
|
||||
use structopt::StructOpt;
|
||||
|
||||
pub const MSRV: &str = "1.56";
|
||||
|
||||
#[derive(StructOpt)]
|
||||
pub enum Subcommand {
|
||||
/// Only runs the fast things (this is used if no command is specified)
|
||||
Default,
|
||||
/// Runs everything
|
||||
Ci,
|
||||
/// Checks Rust and Python code formatting with `rustfmt` and `black`
|
||||
Fmt,
|
||||
/// Runs `clippy`, denying all warnings.
|
||||
Clippy,
|
||||
/// Attempts to render the documentation.
|
||||
Doc(DocOpts),
|
||||
/// Runs various variations on `cargo test`
|
||||
Test,
|
||||
/// Runs the tests in examples/ and pytests/
|
||||
TestPy,
|
||||
}
|
||||
|
||||
impl Default for Subcommand {
|
||||
fn default() -> Self {
|
||||
Self::Default
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(StructOpt)]
|
||||
pub struct DocOpts {
|
||||
/// Whether to run the docs using nightly rustdoc
|
||||
#[structopt(long)]
|
||||
pub stable: bool,
|
||||
/// Whether to open the docs after rendering.
|
||||
#[structopt(long)]
|
||||
pub open: bool,
|
||||
/// Whether to show the private and hidden API.
|
||||
#[structopt(long)]
|
||||
pub internal: bool,
|
||||
}
|
||||
|
||||
impl Default for DocOpts {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
stable: true,
|
||||
open: false,
|
||||
internal: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Subcommand {
|
||||
pub fn execute(self) -> Result<()> {
|
||||
print_metadata()?;
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
match self {
|
||||
Subcommand::Default => {
|
||||
crate::fmt::rust::run()?;
|
||||
crate::clippy::run()?;
|
||||
crate::test::run()?;
|
||||
crate::doc::run(DocOpts::default())?;
|
||||
}
|
||||
Subcommand::Ci => {
|
||||
let installed = Installed::new()?;
|
||||
crate::fmt::rust::run()?;
|
||||
if installed.black {
|
||||
crate::fmt::python::run()?;
|
||||
} else {
|
||||
Installed::warn_black()
|
||||
};
|
||||
crate::clippy::run()?;
|
||||
crate::test::run()?;
|
||||
crate::doc::run(DocOpts::default())?;
|
||||
if installed.nox {
|
||||
crate::pytests::run(None)?;
|
||||
} else {
|
||||
Installed::warn_nox()
|
||||
};
|
||||
installed.assert()?
|
||||
}
|
||||
|
||||
Subcommand::Doc(opts) => crate::doc::run(opts)?,
|
||||
Subcommand::Fmt => {
|
||||
crate::fmt::rust::run()?;
|
||||
crate::fmt::python::run()?;
|
||||
}
|
||||
Subcommand::Clippy => crate::clippy::run()?,
|
||||
Subcommand::TestPy => crate::pytests::run(None)?,
|
||||
Subcommand::Test => crate::test::run()?,
|
||||
};
|
||||
|
||||
let dt = start.elapsed().as_secs();
|
||||
let minutes = dt / 60;
|
||||
let seconds = dt % 60;
|
||||
println!("\nxtask finished in {}m {}s.", minutes, seconds);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Run a command as a child process, inheriting stdin, stdout and stderr.
|
||||
pub fn run(command: &mut Command) -> Result<()> {
|
||||
let command_str = format!("{:?}", command);
|
||||
let github_actions = std::env::var_os("GITHUB_ACTIONS").is_some();
|
||||
if github_actions {
|
||||
println!("::group::Running: {}", command_str);
|
||||
} else {
|
||||
println!("Running: {}", command_str);
|
||||
}
|
||||
|
||||
let status = command.spawn()?.wait()?;
|
||||
|
||||
ensure! {
|
||||
status.success(),
|
||||
"process did not run successfully ({exit}): {command}",
|
||||
exit = match status.code() {
|
||||
Some(code) => format!("exit code {}", code),
|
||||
None => "terminated by signal".into(),
|
||||
},
|
||||
command = command_str,
|
||||
};
|
||||
|
||||
if github_actions {
|
||||
println!("::endgroup::")
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Like `run`, but does not inherit stdin, stdout and stderr.
|
||||
pub fn run_with_output(command: &mut Command) -> Result<Output> {
|
||||
let command_str = format!("{:?}", command);
|
||||
|
||||
println!("Running: {}", command_str);
|
||||
|
||||
let output = command.output()?;
|
||||
|
||||
ensure! {
|
||||
output.status.success(),
|
||||
"process did not run successfully ({exit}): {command}:\n{stderr}",
|
||||
exit = match output.status.code() {
|
||||
Some(code) => format!("exit code {}", code),
|
||||
None => "terminated by signal".into(),
|
||||
},
|
||||
command = command_str,
|
||||
stderr = String::from_utf8_lossy(&output.stderr)
|
||||
};
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Installed {
|
||||
pub nox: bool,
|
||||
pub black: bool,
|
||||
}
|
||||
|
||||
impl Installed {
|
||||
pub fn new() -> anyhow::Result<Self> {
|
||||
Ok(Self {
|
||||
nox: Self::nox()?,
|
||||
black: Self::black()?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn nox() -> anyhow::Result<bool> {
|
||||
let output = std::process::Command::new("nox").arg("--version").output();
|
||||
match output {
|
||||
Ok(_) => Ok(true),
|
||||
Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(false),
|
||||
Err(other) => Err(other.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn warn_nox() {
|
||||
eprintln!("Skipping: formatting Python code, because `nox` was not found");
|
||||
}
|
||||
|
||||
pub fn black() -> anyhow::Result<bool> {
|
||||
let output = std::process::Command::new("black")
|
||||
.arg("--version")
|
||||
.output();
|
||||
match output {
|
||||
Ok(_) => Ok(true),
|
||||
Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(false),
|
||||
Err(other) => Err(other.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn warn_black() {
|
||||
eprintln!("Skipping: Python code formatting, because `black` was not found.");
|
||||
}
|
||||
|
||||
pub fn assert(&self) -> anyhow::Result<()> {
|
||||
if self.nox && self.black {
|
||||
Ok(())
|
||||
} else {
|
||||
let mut err =
|
||||
String::from("\n\nxtask was unable to run all tests due to some missing programs:");
|
||||
if !self.black {
|
||||
err.push_str("\n`black` was not installed. (`pip install black`)");
|
||||
}
|
||||
if !self.nox {
|
||||
err.push_str("\n`nox` was not installed. (`pip install nox`)");
|
||||
}
|
||||
|
||||
Err(anyhow::anyhow!(err))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
use crate::cli;
|
||||
use std::process::Command;
|
||||
|
||||
pub fn run() -> anyhow::Result<()> {
|
||||
cli::run(
|
||||
Command::new("cargo")
|
||||
.arg("clippy")
|
||||
.arg("--features=full")
|
||||
.arg("--all-targets")
|
||||
.arg("--workspace")
|
||||
.arg("--")
|
||||
.arg("-Dwarnings"),
|
||||
)?;
|
||||
cli::run(
|
||||
Command::new("cargo")
|
||||
.arg("clippy")
|
||||
.arg("--all-targets")
|
||||
.arg("--workspace")
|
||||
.arg("--features=abi3,full")
|
||||
.arg("--")
|
||||
.arg("-Dwarnings"),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
use crate::cli;
|
||||
use crate::cli::DocOpts;
|
||||
use std::process::Command;
|
||||
//--cfg docsrs --Z unstable-options --document-hidden-items
|
||||
|
||||
pub fn run(opts: DocOpts) -> anyhow::Result<()> {
|
||||
let mut flags = Vec::new();
|
||||
|
||||
if !opts.stable {
|
||||
flags.push("--cfg docsrs");
|
||||
}
|
||||
if opts.internal {
|
||||
flags.push("--Z unstable-options");
|
||||
flags.push("--document-hidden-items");
|
||||
}
|
||||
flags.push("-Dwarnings");
|
||||
|
||||
std::env::set_var("RUSTDOCFLAGS", flags.join(" "));
|
||||
cli::run(
|
||||
Command::new(concat!(env!("CARGO_HOME"), "/bin/cargo"))
|
||||
.args(if opts.stable { None } else { Some("+nightly") })
|
||||
.arg("doc")
|
||||
.arg("--lib")
|
||||
.arg("--no-default-features")
|
||||
.arg("--features=full")
|
||||
.arg("--no-deps")
|
||||
.arg("--workspace")
|
||||
.args(if opts.internal {
|
||||
&["--document-private-items"][..]
|
||||
} else {
|
||||
&["--exclude=pyo3-macros", "--exclude=pyo3-macros-backend"][..]
|
||||
})
|
||||
.args(if opts.stable {
|
||||
&[][..]
|
||||
} else {
|
||||
&["-Z", "unstable-options", "-Z", "rustdoc-scrape-examples"][..]
|
||||
})
|
||||
.args(if opts.open { Some("--open") } else { None }),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
pub mod rust {
|
||||
use crate::cli;
|
||||
use std::process::Command;
|
||||
pub fn run() -> anyhow::Result<()> {
|
||||
cli::run(
|
||||
Command::new("cargo")
|
||||
.arg("fmt")
|
||||
.arg("--all")
|
||||
.arg("--")
|
||||
.arg("--check"),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub mod python {
|
||||
use crate::cli;
|
||||
use std::process::Command;
|
||||
pub fn run() -> anyhow::Result<()> {
|
||||
cli::run(Command::new("black").arg(".").arg("--check"))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
use clap::ErrorKind::MissingArgumentOrSubcommand;
|
||||
use structopt::StructOpt;
|
||||
|
||||
pub mod cli;
|
||||
pub mod clippy;
|
||||
pub mod doc;
|
||||
pub mod fmt;
|
||||
pub mod pytests;
|
||||
pub mod test;
|
||||
pub mod utils;
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
// Avoid spewing backtraces all over the command line
|
||||
// For some reason this is automatically enabled on nightly compilers...
|
||||
std::env::set_var("RUST_LIB_BACKTRACE", "0");
|
||||
|
||||
match cli::Subcommand::from_args_safe() {
|
||||
Ok(c) => c.execute()?,
|
||||
Err(e) if e.kind == MissingArgumentOrSubcommand => cli::Subcommand::default().execute()?,
|
||||
Err(e) => return Err(e.into()),
|
||||
}
|
||||
Ok(())
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
use crate::cli;
|
||||
use anyhow::Result;
|
||||
use std::{path::Path, process::Command};
|
||||
|
||||
pub fn run<'a>(env: impl IntoIterator<Item = (&'a String, &'a String)> + Copy) -> Result<()> {
|
||||
cli::run(
|
||||
Command::new("nox")
|
||||
.arg("--non-interactive")
|
||||
.arg("-f")
|
||||
.arg(Path::new("pytests").join("noxfile.py"))
|
||||
.envs(env),
|
||||
)?;
|
||||
|
||||
for entry in std::fs::read_dir("examples")? {
|
||||
let path = entry?.path();
|
||||
if path.is_dir() && path.join("noxfile.py").exists() {
|
||||
cli::run(
|
||||
Command::new("nox")
|
||||
.arg("--non-interactive")
|
||||
.arg("-f")
|
||||
.arg(path.join("noxfile.py"))
|
||||
.envs(env),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
use crate::cli::{self, MSRV};
|
||||
use std::process::Command;
|
||||
|
||||
pub fn run() -> anyhow::Result<()> {
|
||||
cli::run(
|
||||
Command::new("cargo")
|
||||
.arg("test")
|
||||
.arg("--lib")
|
||||
.arg("--no-default-features")
|
||||
.arg("--tests")
|
||||
.arg("--quiet"),
|
||||
)?;
|
||||
|
||||
cli::run(
|
||||
Command::new("cargo")
|
||||
.arg("test")
|
||||
.arg("--no-default-features")
|
||||
.arg("--features=full")
|
||||
.arg("--quiet"),
|
||||
)?;
|
||||
|
||||
cli::run(
|
||||
Command::new("cargo")
|
||||
.arg("test")
|
||||
.arg("--no-default-features")
|
||||
.arg("--features=abi3,full")
|
||||
.arg("--quiet"),
|
||||
)?;
|
||||
|
||||
// If the MSRV toolchain is not installed, this will install it
|
||||
cli::run(
|
||||
Command::new("rustup")
|
||||
.arg("toolchain")
|
||||
.arg("install")
|
||||
.arg(MSRV),
|
||||
)?;
|
||||
|
||||
// Test MSRV
|
||||
cli::run(
|
||||
Command::new(concat!(env!("CARGO_HOME"), "/bin/cargo"))
|
||||
.arg(format!("+{}", MSRV))
|
||||
.arg("test")
|
||||
.arg("--no-default-features")
|
||||
.arg("--features=full,auto-initialize")
|
||||
.arg("--quiet"),
|
||||
)?;
|
||||
|
||||
// If the nightly toolchain is not installed, this will install it
|
||||
cli::run(
|
||||
Command::new("rustup")
|
||||
.arg("toolchain")
|
||||
.arg("install")
|
||||
.arg("nightly"),
|
||||
)?;
|
||||
|
||||
cli::run(
|
||||
Command::new(concat!(env!("CARGO_HOME"), "/bin/cargo"))
|
||||
.arg("+nightly")
|
||||
.arg("test")
|
||||
.arg("--no-default-features")
|
||||
.arg("--features=full,nightly")
|
||||
.arg("--quiet"),
|
||||
)?;
|
||||
|
||||
cli::run(
|
||||
Command::new("cargo")
|
||||
.arg("test")
|
||||
.arg("--manifest-path=pyo3-ffi/Cargo.toml")
|
||||
.arg("--quiet"),
|
||||
)?;
|
||||
|
||||
cli::run(
|
||||
Command::new("cargo")
|
||||
.arg("test")
|
||||
.arg("--no-default-features")
|
||||
.arg("--manifest-path=pyo3-build-config/Cargo.toml")
|
||||
.arg("--quiet"),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
use anyhow::ensure;
|
||||
use std::process::Command;
|
||||
|
||||
pub fn get_output(command: &mut Command) -> anyhow::Result<std::process::Output> {
|
||||
let output = command.output()?;
|
||||
ensure! {
|
||||
output.status.success(),
|
||||
"process did not run successfully ({exit}): {command:?}",
|
||||
exit = match output.status.code() {
|
||||
Some(code) => format!("exit code {}", code),
|
||||
None => "terminated by signal".into(),
|
||||
},
|
||||
command = command,
|
||||
};
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
pub fn print_metadata() -> anyhow::Result<()> {
|
||||
let rustc_output = std::process::Command::new("rustc")
|
||||
.arg("--version")
|
||||
.arg("--verbose")
|
||||
.output()?;
|
||||
let rustc_version = core::str::from_utf8(&rustc_output.stdout).unwrap();
|
||||
println!("Metadata: \n\n{}", rustc_version);
|
||||
|
||||
let py_output = std::process::Command::new("python")
|
||||
.arg("--version")
|
||||
.arg("-V")
|
||||
.output()?;
|
||||
let py_version = core::str::from_utf8(&py_output.stdout).unwrap();
|
||||
println!("{}", py_version);
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue