1 //! Support library for `cargo xtask` command.
3 //! See https://github.com/matklad/cargo-xtask/
17 path::{Path, PathBuf},
20 use walkdir::{DirEntry, WalkDir};
21 use xshell::{cmd, pushd, pushenv};
23 use crate::codegen::Mode;
25 pub use anyhow::{bail, Context as _, Result};
27 pub fn project_root() -> PathBuf {
29 &env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| env!("CARGO_MANIFEST_DIR").to_owned()),
37 pub fn rust_files(path: &Path) -> impl Iterator<Item = PathBuf> {
38 let iter = WalkDir::new(path);
41 .filter_entry(|e| !is_hidden(e))
43 .filter(|e| !e.file_type().is_dir())
44 .map(|e| e.into_path())
45 .filter(|path| path.extension().map(|it| it == "rs").unwrap_or(false));
47 fn is_hidden(entry: &DirEntry) -> bool {
48 entry.file_name().to_str().map(|s| s.starts_with('.')).unwrap_or(false)
52 pub fn run_rustfmt(mode: Mode) -> Result<()> {
53 let _dir = pushd(project_root())?;
54 let _e = pushenv("RUSTUP_TOOLCHAIN", "stable");
56 let check = match mode {
57 Mode::Overwrite => &[][..],
58 Mode::Verify => &["--", "--check"],
60 cmd!("cargo fmt {check...}").run()?;
64 fn ensure_rustfmt() -> Result<()> {
65 let out = cmd!("rustfmt --version").read()?;
66 if !out.contains("stable") {
68 "Failed to run rustfmt from toolchain 'stable'. \
69 Please run `rustup component add rustfmt --toolchain stable` to install it.",
75 pub fn run_clippy() -> Result<()> {
76 if cmd!("cargo clippy --version").read().is_err() {
78 "Failed run cargo clippy. \
79 Please run `rustup component add clippy` to install it.",
84 -A clippy::collapsible_if
85 -A clippy::needless_pass_by_value
86 -A clippy::nonminimal_bool
87 -A clippy::redundant_pattern_matching
89 .split_ascii_whitespace();
90 cmd!("cargo clippy --all-features --all-targets -- {allowed_lints...}").run()?;
94 pub fn run_fuzzer() -> Result<()> {
95 let _d = pushd("./crates/syntax")?;
96 let _e = pushenv("RUSTUP_TOOLCHAIN", "nightly");
97 if cmd!("cargo fuzz --help").read().is_err() {
98 cmd!("cargo install cargo-fuzz").run()?;
101 // Expecting nightly rustc
102 let out = cmd!("rustc --version").read()?;
103 if !out.contains("nightly") {
104 bail!("fuzz tests require nightly rustc")
107 cmd!("cargo fuzz run parser").run()?;
111 fn date_iso() -> Result<String> {
112 let res = cmd!("date --iso --utc").read()?;
116 fn is_release_tag(tag: &str) -> bool {
117 tag.len() == "2020-02-24".len() && tag.starts_with(|c: char| c.is_ascii_digit())