New subcommands

This commit is contained in:
Ajeet D'Souza 2021-10-11 04:23:30 +05:30
parent 34cf7af5c0
commit 180d5043a9
8 changed files with 204 additions and 82 deletions

118
Cargo.lock generated
View File

@ -2,6 +2,15 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 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]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.44" version = "1.0.44"
@ -170,6 +179,16 @@ dependencies = [
"clap", "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]] [[package]]
name = "difflib" name = "difflib"
version = "0.4.0" version = "0.4.0"
@ -215,6 +234,12 @@ version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]] [[package]]
name = "funty" name = "funty"
version = "1.1.0" version = "1.1.0"
@ -238,6 +263,19 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" 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]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.11.2" version = "0.11.2"
@ -262,6 +300,24 @@ dependencies = [
"libc", "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]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.7.0" version = "1.7.0"
@ -306,6 +362,15 @@ version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" 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]] [[package]]
name = "memchr" name = "memchr"
version = "2.4.1" version = "2.4.1"
@ -334,6 +399,12 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "once_cell"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]] [[package]]
name = "ordered-float" name = "ordered-float"
version = "2.8.0" version = "2.8.0"
@ -489,12 +560,29 @@ dependencies = [
"redox_syscall", "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]] [[package]]
name = "regex-automata" name = "regex-automata"
version = "0.1.10" version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]] [[package]]
name = "remove_dir_all" name = "remove_dir_all"
version = "0.5.3" version = "0.5.3"
@ -532,6 +620,15 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 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]] [[package]]
name = "semver" name = "semver"
version = "1.0.4" version = "1.0.4"
@ -631,6 +728,15 @@ dependencies = [
"unicode-width", "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]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.8.0" version = "1.8.0"
@ -670,6 +776,17 @@ dependencies = [
"libc", "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]] [[package]]
name = "wasi" name = "wasi"
version = "0.10.2+wasi-snapshot-preview1" version = "0.10.2+wasi-snapshot-preview1"
@ -719,6 +836,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
"ignore",
"shell-words", "shell-words",
] ]

View File

@ -9,6 +9,9 @@ license = "MIT"
keywords = ["cli"] keywords = ["cli"]
categories = ["command-line-utilities", "filesystem"] categories = ["command-line-utilities", "filesystem"]
[badges]
maintenance = { status = "actively-developed" }
[workspace] [workspace]
members = ["xtask/"] members = ["xtask/"]

View File

@ -1,9 +1,11 @@
let 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 <nixpkgs> { overlays = [ rust ]; }; pkgs = import <nixpkgs> { overlays = [ rust ]; };
pkgs-latest = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/b4692e4197869c42c46d77e31af7e687e1892f55.tar.gz") {}; pkgs-latest = import (fetchTarball
in "https://github.com/NixOS/nixpkgs/archive/b4692e4197869c42c46d77e31af7e687e1892f55.tar.gz")
pkgs.mkShell { { };
in pkgs.mkShell {
buildInputs = [ buildInputs = [
# Rust # Rust
pkgs.rust-bin.stable.latest.default pkgs.rust-bin.stable.latest.default
@ -21,6 +23,7 @@ pkgs.mkShell {
# Tools # Tools
pkgs-latest.cargo-audit pkgs-latest.cargo-audit
pkgs-latest.mandoc pkgs-latest.mandoc
pkgs-latest.nixfmt
pkgs-latest.nodePackages.markdownlint-cli pkgs-latest.nodePackages.markdownlint-cli
pkgs-latest.python3Packages.black pkgs-latest.python3Packages.black
pkgs-latest.python3Packages.mypy pkgs-latest.python3Packages.mypy

View File

@ -321,16 +321,7 @@ mod tests {
let mut source = Xonsh(&opts).render().unwrap(); let mut source = Xonsh(&opts).render().unwrap();
source.push('\n'); source.push('\n');
let tempdir = tempfile::tempdir().unwrap(); Command::new("pylint").args(&["--from-stdin", "zoxide"]).write_stdin(source).assert().success().stderr("");
let tempdir = tempdir.path().to_str().unwrap();
Command::new("pylint")
.args(&["--from-stdin", "zoxide"])
.env("HOME", tempdir)
.write_stdin(source)
.assert()
.success()
.stderr("");
} }
#[rstest] #[rstest]

View File

@ -1,4 +1,4 @@
//! Syntax checking for auto-generated shell completions. //! Test clap generated completions.
#![cfg(feature = "nix")] #![cfg(feature = "nix")]
use assert_cmd::Command; use assert_cmd::Command;

View File

@ -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::<Vec<_>>();
Command::new("mandoc")
.args(&["-man", "-Wall", "-Tlint", "--"])
.args(&paths)
.assert()
.success()
.stdout("")
.stderr("");
}

View File

@ -7,4 +7,5 @@ publish = false
[dependencies] [dependencies]
anyhow = "1.0.32" anyhow = "1.0.32"
clap = "=3.0.0-beta.4" clap = "=3.0.0-beta.4"
ignore = "0.4.18"
shell-words = "1.0.0" shell-words = "1.0.0"

View File

@ -1,5 +1,6 @@
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
use clap::Clap; use clap::Clap;
use ignore::Walk;
use std::env; use std::env;
use std::ffi::OsStr; use std::ffi::OsStr;
@ -9,15 +10,16 @@ use std::process::{self, Command};
fn main() -> Result<()> { fn main() -> Result<()> {
let nix_enabled = enable_nix(); 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(); let app = App::parse();
match app { 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::CI => run_ci(nix_enabled)?,
App::Fmt => run_fmt(&[] as &[&str])?, App::Fmt { check } => run_fmt(nix_enabled, check)?,
App::Markdownlint => run_markdownlint()?, App::Lint => run_lint(nix_enabled)?,
App::Test { name } => run_test(nix_enabled, &[name])?, App::Test { name } => run_tests(nix_enabled, &name)?,
} }
Ok(()) Ok(())
@ -25,12 +27,12 @@ fn main() -> Result<()> {
#[derive(Clap)] #[derive(Clap)]
enum App { enum App {
Audit,
Check,
CI, CI,
Clippy, Fmt {
Fmt, #[clap(long)]
Markdownlint, check: bool,
},
Lint,
Test { Test {
#[clap(default_value = "")] #[clap(default_value = "")]
name: String, name: String,
@ -52,44 +54,76 @@ impl CommandExt for &mut Command {
} }
} }
fn run_audit<S: AsRef<OsStr>>(args: &[S]) -> Result<()> {
Command::new("cargo").args(&["audit", "--deny=warnings"]).args(args)._run()
}
fn run_check<S: AsRef<OsStr>>(args: &[S]) -> Result<()> {
Command::new("cargo").args(&["check", "--all-features", "--all-targets", "--workspace"]).args(args)._run()
}
fn run_clippy<S: AsRef<OsStr>>(args: &[S]) -> Result<()> {
Command::new("cargo").args(&["clippy", "--all-features", "--all-targets"]).args(args)._run()
}
fn run_ci(nix_enabled: bool) -> Result<()> { fn run_ci(nix_enabled: bool) -> Result<()> {
let color = if env::var_os("CI").is_some() { "--color=always" } else { "--color=auto" }; let color: &[&str] = if is_ci() { &["--color=always"] } else { &[] };
run_fmt(&["--check", color, "--files-with-diff"])?; Command::new("cargo").args(&["check", "--all-features"]).args(color)._run()?;
run_check(&[color])?;
run_clippy(&[color])?; run_fmt(nix_enabled, true)?;
run_test(nix_enabled, &[color, "--no-fail-fast"])?; run_lint(nix_enabled)?;
run_tests(nix_enabled, "")
}
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()?;
// Run nixfmt.
if nix_enabled { if nix_enabled {
run_audit(&[] as &[&str])?; // FIXME: add "color" when cargo-audit 0.15.3 is released for result in Walk::new("./") {
run_markdownlint()?; 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(()) Ok(())
} }
fn run_fmt<S: AsRef<OsStr>>(rustfmt_args: &[S]) -> Result<()> { fn run_lint(nix_enabled: bool) -> Result<()> {
Command::new("cargo").args(&["fmt", "--all", "--"]).args(rustfmt_args)._run() // 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<()> { fn run_tests(nix_enabled: bool, name: &str) -> Result<()> {
Command::new("markdownlint").args(&["--ignore-path=.gitignore", "."])._run() 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<S: AsRef<OsStr>>(nix_enabled: bool, args: &[S]) -> Result<()> { fn is_ci() -> bool {
Command::new("cargo") env::var_os("CI").is_some()
.args(&["test", "--workspace", if nix_enabled { "--features=nix" } else { "" }])
.args(args)
._run()
} }
fn enable_nix() -> bool { fn enable_nix() -> bool {