]> git.lizzy.rs Git - rust.git/blob - xtask/src/lib.rs
babec2dbd000f66f1f7b51edf67d15f71474b763
[rust.git] / xtask / src / lib.rs
1 //! Support library for `cargo xtask` command.
2 //!
3 //! See https://github.com/matklad/cargo-xtask/
4
5 pub mod codegen;
6 mod ast_src;
7
8 pub mod install;
9 pub mod release;
10 pub mod dist;
11 pub mod pre_commit;
12 pub mod metrics;
13 pub mod pre_cache;
14
15 use std::{
16     env,
17     path::{Path, PathBuf},
18 };
19
20 use walkdir::{DirEntry, WalkDir};
21 use xshell::{cmd, pushd, pushenv};
22
23 use crate::codegen::Mode;
24
25 pub use anyhow::{bail, Context as _, Result};
26
27 pub fn project_root() -> PathBuf {
28     Path::new(
29         &env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| env!("CARGO_MANIFEST_DIR").to_owned()),
30     )
31     .ancestors()
32     .nth(1)
33     .unwrap()
34     .to_path_buf()
35 }
36
37 pub fn rust_files(path: &Path) -> impl Iterator<Item = PathBuf> {
38     let iter = WalkDir::new(path);
39     return iter
40         .into_iter()
41         .filter_entry(|e| !is_hidden(e))
42         .map(|e| e.unwrap())
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));
46
47     fn is_hidden(entry: &DirEntry) -> bool {
48         entry.file_name().to_str().map(|s| s.starts_with('.')).unwrap_or(false)
49     }
50 }
51
52 pub fn run_rustfmt(mode: Mode) -> Result<()> {
53     let _dir = pushd(project_root())?;
54     let _e = pushenv("RUSTUP_TOOLCHAIN", "stable");
55     ensure_rustfmt()?;
56     let check = match mode {
57         Mode::Overwrite => &[][..],
58         Mode::Verify => &["--", "--check"],
59     };
60     cmd!("cargo fmt {check...}").run()?;
61     Ok(())
62 }
63
64 fn ensure_rustfmt() -> Result<()> {
65     let out = cmd!("rustfmt --version").read()?;
66     if !out.contains("stable") {
67         bail!(
68             "Failed to run rustfmt from toolchain 'stable'. \
69              Please run `rustup component add rustfmt --toolchain stable` to install it.",
70         )
71     }
72     Ok(())
73 }
74
75 pub fn run_clippy() -> Result<()> {
76     if cmd!("cargo clippy --version").read().is_err() {
77         bail!(
78             "Failed run cargo clippy. \
79             Please run `rustup component add clippy` to install it.",
80         )
81     }
82
83     let allowed_lints = "
84         -A clippy::collapsible_if
85         -A clippy::needless_pass_by_value
86         -A clippy::nonminimal_bool
87         -A clippy::redundant_pattern_matching
88     "
89     .split_ascii_whitespace();
90     cmd!("cargo clippy --all-features --all-targets -- {allowed_lints...}").run()?;
91     Ok(())
92 }
93
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()?;
99     };
100
101     // Expecting nightly rustc
102     let out = cmd!("rustc --version").read()?;
103     if !out.contains("nightly") {
104         bail!("fuzz tests require nightly rustc")
105     }
106
107     cmd!("cargo fuzz run parser").run()?;
108     Ok(())
109 }
110
111 fn date_iso() -> Result<String> {
112     let res = cmd!("date --iso --utc").read()?;
113     Ok(res)
114 }
115
116 fn is_release_tag(tag: &str) -> bool {
117     tag.len() == "2020-02-24".len() && tag.starts_with(|c: char| c.is_ascii_digit())
118 }