diff --git a/Cargo.lock b/Cargo.lock index 06a6ea8d..a9f3a1cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + [[package]] name = "anyhow" version = "1.0.44" @@ -170,6 +179,16 @@ dependencies = [ "clap", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if", + "lazy_static", +] + [[package]] name = "difflib" version = "0.4.0" @@ -215,6 +234,12 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "funty" version = "1.1.0" @@ -238,6 +263,19 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +[[package]] +name = "globset" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + [[package]] name = "hashbrown" version = "0.11.2" @@ -262,6 +300,24 @@ dependencies = [ "libc", ] +[[package]] +name = "ignore" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" +dependencies = [ + "crossbeam-utils", + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + [[package]] name = "indexmap" version = "1.7.0" @@ -306,6 +362,15 @@ version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + [[package]] name = "memchr" version = "2.4.1" @@ -334,6 +399,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" + [[package]] name = "ordered-float" version = "2.8.0" @@ -489,12 +560,29 @@ dependencies = [ "redox_syscall", ] +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + [[package]] name = "regex-automata" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + [[package]] name = "remove_dir_all" version = "0.5.3" @@ -532,6 +620,15 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "semver" version = "1.0.4" @@ -631,6 +728,15 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thread_local" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +dependencies = [ + "once_cell", +] + [[package]] name = "unicode-segmentation" version = "1.8.0" @@ -670,6 +776,17 @@ dependencies = [ "libc", ] +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" @@ -719,6 +836,7 @@ version = "0.1.0" dependencies = [ "anyhow", "clap", + "ignore", "shell-words", ] diff --git a/Cargo.toml b/Cargo.toml index e22b3b61..08b2d477 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,9 @@ license = "MIT" keywords = ["cli"] categories = ["command-line-utilities", "filesystem"] +[badges] +maintenance = { status = "actively-developed" } + [workspace] members = ["xtask/"] diff --git a/shell.nix b/shell.nix index dcee1a30..2b081fc2 100644 --- a/shell.nix +++ b/shell.nix @@ -1,9 +1,11 @@ let - rust = import (builtins.fetchTarball "https://github.com/oxalica/rust-overlay/archive/ad311f5bb5c5ef475985f1e0f264e831470a8510.tar.gz"); + rust = import (builtins.fetchTarball + "https://github.com/oxalica/rust-overlay/archive/ad311f5bb5c5ef475985f1e0f264e831470a8510.tar.gz"); pkgs = import { overlays = [ rust ]; }; - pkgs-latest = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/b4692e4197869c42c46d77e31af7e687e1892f55.tar.gz") {}; -in -pkgs.mkShell { + pkgs-latest = import (fetchTarball + "https://github.com/NixOS/nixpkgs/archive/b4692e4197869c42c46d77e31af7e687e1892f55.tar.gz") + { }; +in pkgs.mkShell { buildInputs = [ # Rust pkgs.rust-bin.stable.latest.default @@ -21,6 +23,7 @@ pkgs.mkShell { # Tools pkgs-latest.cargo-audit pkgs-latest.mandoc + pkgs-latest.nixfmt pkgs-latest.nodePackages.markdownlint-cli pkgs-latest.python3Packages.black pkgs-latest.python3Packages.mypy diff --git a/src/shell.rs b/src/shell.rs index ba3f6a23..6199a049 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -321,16 +321,7 @@ mod tests { let mut source = Xonsh(&opts).render().unwrap(); source.push('\n'); - let tempdir = tempfile::tempdir().unwrap(); - let tempdir = tempdir.path().to_str().unwrap(); - - Command::new("pylint") - .args(&["--from-stdin", "zoxide"]) - .env("HOME", tempdir) - .write_stdin(source) - .assert() - .success() - .stderr(""); + Command::new("pylint").args(&["--from-stdin", "zoxide"]).write_stdin(source).assert().success().stderr(""); } #[rstest] diff --git a/tests/completion.rs b/tests/completions.rs similarity index 96% rename from tests/completion.rs rename to tests/completions.rs index 5e5c2883..56975d8e 100644 --- a/tests/completion.rs +++ b/tests/completions.rs @@ -1,4 +1,4 @@ -//! Syntax checking for auto-generated shell completions. +//! Test clap generated completions. #![cfg(feature = "nix")] use assert_cmd::Command; diff --git a/tests/man.rs b/tests/man.rs deleted file mode 100644 index faf1e64e..00000000 --- a/tests/man.rs +++ /dev/null @@ -1,28 +0,0 @@ -//! Syntax checking for manpages. -#![cfg(feature = "nix")] - -use assert_cmd::Command; - -use std::fs; - -#[test] -fn mandoc_lint() { - let paths = fs::read_dir("man") - .unwrap() - .filter_map(|entry| { - let path = entry.unwrap().path(); - if path.is_file() && path.extension() == Some("1".as_ref()) { - Some(path.to_str().unwrap().to_string()) - } else { - None - } - }) - .collect::>(); - Command::new("mandoc") - .args(&["-man", "-Wall", "-Tlint", "--"]) - .args(&paths) - .assert() - .success() - .stdout("") - .stderr(""); -} diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 773ca7d8..68523405 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -7,4 +7,5 @@ publish = false [dependencies] anyhow = "1.0.32" clap = "=3.0.0-beta.4" +ignore = "0.4.18" shell-words = "1.0.0" diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 90b5a083..6de70d47 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,5 +1,6 @@ use anyhow::{bail, Context, Result}; use clap::Clap; +use ignore::Walk; use std::env; use std::ffi::OsStr; @@ -9,15 +10,16 @@ use std::process::{self, Command}; fn main() -> Result<()> { let nix_enabled = enable_nix(); + let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let dir = dir.parent().with_context(|| format!("could not find workspace root: {}", dir.display()))?; + env::set_current_dir(dir).with_context(|| format!("could not set current directory: {}", dir.display()))?; + let app = App::parse(); match app { - App::Audit => run_audit(&[] as &[&str])?, - App::Check => run_check(&[] as &[&str])?, - App::Clippy => run_clippy(&[] as &[&str])?, App::CI => run_ci(nix_enabled)?, - App::Fmt => run_fmt(&[] as &[&str])?, - App::Markdownlint => run_markdownlint()?, - App::Test { name } => run_test(nix_enabled, &[name])?, + App::Fmt { check } => run_fmt(nix_enabled, check)?, + App::Lint => run_lint(nix_enabled)?, + App::Test { name } => run_tests(nix_enabled, &name)?, } Ok(()) @@ -25,12 +27,12 @@ fn main() -> Result<()> { #[derive(Clap)] enum App { - Audit, - Check, CI, - Clippy, - Fmt, - Markdownlint, + Fmt { + #[clap(long)] + check: bool, + }, + Lint, Test { #[clap(default_value = "")] name: String, @@ -52,44 +54,76 @@ impl CommandExt for &mut Command { } } -fn run_audit>(args: &[S]) -> Result<()> { - Command::new("cargo").args(&["audit", "--deny=warnings"]).args(args)._run() -} +fn run_ci(nix_enabled: bool) -> Result<()> { + let color: &[&str] = if is_ci() { &["--color=always"] } else { &[] }; + Command::new("cargo").args(&["check", "--all-features"]).args(color)._run()?; -fn run_check>(args: &[S]) -> Result<()> { - Command::new("cargo").args(&["check", "--all-features", "--all-targets", "--workspace"]).args(args)._run() + run_fmt(nix_enabled, true)?; + run_lint(nix_enabled)?; + run_tests(nix_enabled, "") } -fn run_clippy>(args: &[S]) -> Result<()> { - Command::new("cargo").args(&["clippy", "--all-features", "--all-targets"]).args(args)._run() -} +fn run_fmt(nix_enabled: bool, check: bool) -> Result<()> { + // Run cargo-fmt. + let color: &[&str] = if is_ci() { &["--color=always"] } else { &[] }; + let check_args: &[&str] = if check { &["--check", "--files-with-diff"] } else { &[] }; + Command::new("cargo").args(&["fmt", "--all", "--"]).args(color).args(check_args)._run()?; -fn run_ci(nix_enabled: bool) -> Result<()> { - let color = if env::var_os("CI").is_some() { "--color=always" } else { "--color=auto" }; - run_fmt(&["--check", color, "--files-with-diff"])?; - run_check(&[color])?; - run_clippy(&[color])?; - run_test(nix_enabled, &[color, "--no-fail-fast"])?; + // Run nixfmt. if nix_enabled { - run_audit(&[] as &[&str])?; // FIXME: add "color" when cargo-audit 0.15.3 is released - run_markdownlint()?; + for result in Walk::new("./") { + let entry = result.unwrap(); + let path = entry.path(); + if path.is_file() && path.extension() == Some(OsStr::new("nix")) { + let check_args: &[&str] = if check { &["--check"] } else { &[] }; + Command::new("nixfmt").args(check_args).arg("--").arg(path)._run()?; + } + } } + Ok(()) } -fn run_fmt>(rustfmt_args: &[S]) -> Result<()> { - Command::new("cargo").args(&["fmt", "--all", "--"]).args(rustfmt_args)._run() +fn run_lint(nix_enabled: bool) -> Result<()> { + // Run cargo-clippy. + let color: &[&str] = if is_ci() { &["--color=always"] } else { &[] }; + Command::new("cargo").args(&["clippy", "--all-features", "--all-targets"]).args(color)._run()?; + + if nix_enabled { + // Run cargo-audit. + let color: &[&str] = if is_ci() { &["--color=always"] } else { &[] }; + Command::new("cargo").args(&["audit", "--deny=warnings"]).args(color)._run()?; + + // Run markdownlint. + for result in Walk::new("./") { + let entry = result.unwrap(); + let path = entry.path(); + if path.is_file() && path.extension() == Some(OsStr::new("md")) { + Command::new("markdownlint").arg(path)._run()?; + } + } + + // Run mandoc with linting enabled. + for result in Walk::new("./man/") { + let entry = result.unwrap(); + let path = entry.path(); + if path.is_file() && path.extension() == Some(OsStr::new("1")) { + Command::new("mandoc").args(&["-man", "-Wall", "-Tlint", "--"]).arg(path)._run()?; + } + } + } + + Ok(()) } -fn run_markdownlint() -> Result<()> { - Command::new("markdownlint").args(&["--ignore-path=.gitignore", "."])._run() +fn run_tests(nix_enabled: bool, name: &str) -> Result<()> { + let color: &[&str] = if is_ci() { &["--color=always"] } else { &[] }; + let features: &[&str] = if nix_enabled { &["--all-features"] } else { &[] }; + Command::new("cargo").args(&["test", "--no-fail-fast", "--workspace"]).args(color).args(features).arg(name)._run() } -fn run_test>(nix_enabled: bool, args: &[S]) -> Result<()> { - Command::new("cargo") - .args(&["test", "--workspace", if nix_enabled { "--features=nix" } else { "" }]) - .args(args) - ._run() +fn is_ci() -> bool { + env::var_os("CI").is_some() } fn enable_nix() -> bool {