feat(xatu): set CLI exit statuses
This commit is contained in:
@@ -41,6 +41,17 @@ rust_test(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
sh_test(
|
||||||
|
name = "xatu_cli_test",
|
||||||
|
srcs = ["xatu_cli_test.sh"],
|
||||||
|
data = [
|
||||||
|
":xatu",
|
||||||
|
"testdata/clean.nix",
|
||||||
|
"testdata/invalid.nix",
|
||||||
|
"testdata/lint_findings.nix",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
rust_binary(
|
rust_binary(
|
||||||
name = "xatu",
|
name = "xatu",
|
||||||
crate_name = "xatu_cli",
|
crate_name = "xatu_cli",
|
||||||
|
|||||||
38
src/xatu/xatu_cli_test.sh
Executable file
38
src/xatu/xatu_cli_test.sh
Executable file
@@ -0,0 +1,38 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
xatu="$TEST_SRCDIR/$TEST_WORKSPACE/src/xatu/xatu"
|
||||||
|
fixture="$TEST_SRCDIR/$TEST_WORKSPACE/src/xatu/testdata"
|
||||||
|
tmp="${TEST_TMPDIR:-$(mktemp -d)}"
|
||||||
|
|
||||||
|
run_xatu() {
|
||||||
|
local name="$1"
|
||||||
|
local expected_status="$2"
|
||||||
|
shift 2
|
||||||
|
|
||||||
|
set +e
|
||||||
|
"$xatu" "$@" >"$tmp/$name.stdout" 2>"$tmp/$name.stderr"
|
||||||
|
local actual_status="$?"
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [[ "$actual_status" != "$expected_status" ]]; then
|
||||||
|
echo "expected $name to exit $expected_status, got $actual_status" >&2
|
||||||
|
echo "stdout:" >&2
|
||||||
|
cat "$tmp/$name.stdout" >&2
|
||||||
|
echo "stderr:" >&2
|
||||||
|
cat "$tmp/$name.stderr" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cp "$fixture/clean.nix" "$tmp/clean.nix"
|
||||||
|
cp "$fixture/invalid.nix" "$tmp/invalid.nix"
|
||||||
|
cp "$fixture/lint_findings.nix" "$tmp/lint_findings.nix"
|
||||||
|
mkdir -p "$tmp/project/testdata"
|
||||||
|
cp "$fixture/invalid.nix" "$tmp/project/testdata/invalid.nix"
|
||||||
|
|
||||||
|
run_xatu clean 0 "$tmp/clean.nix"
|
||||||
|
run_xatu findings 1 "$tmp/lint_findings.nix"
|
||||||
|
run_xatu fatal 2 "$tmp/invalid.nix"
|
||||||
|
run_xatu ignores_testdata_by_default 0 "$tmp/project"
|
||||||
|
run_xatu checks_explicit_testdata_path 2 "$tmp/project/testdata/invalid.nix"
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use status::ResultExt;
|
use status::ResultExt;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use xatu::SourceFile;
|
use std::process::ExitCode;
|
||||||
|
use xatu::{Report, SourceFile};
|
||||||
|
|
||||||
fn is_nix_file(path: &Path) -> bool {
|
fn is_nix_file(path: &Path) -> bool {
|
||||||
path.extension().is_some_and(|extension| extension == "nix")
|
path.extension().is_some_and(|extension| extension == "nix")
|
||||||
@@ -28,11 +29,18 @@ fn is_excluded_dir(path: &Path) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn collect_source_files(path: &Path) -> status::Result<Vec<SourceFile>> {
|
fn collect_source_files(path: &Path) -> status::Result<Vec<SourceFile>> {
|
||||||
|
collect_source_files_with_exclusions(path, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn collect_source_files_with_exclusions(
|
||||||
|
path: &Path,
|
||||||
|
exclude_current_dir: bool,
|
||||||
|
) -> status::Result<Vec<SourceFile>> {
|
||||||
let metadata = std::fs::symlink_metadata(path)
|
let metadata = std::fs::symlink_metadata(path)
|
||||||
.with_context(|| format!("failed to read metadata for {}", path.display()))?;
|
.with_context(|| format!("failed to read metadata for {}", path.display()))?;
|
||||||
|
|
||||||
if metadata.file_type().is_dir() {
|
if metadata.file_type().is_dir() {
|
||||||
if is_excluded_dir(path) {
|
if exclude_current_dir && is_excluded_dir(path) {
|
||||||
return Ok(Vec::new());
|
return Ok(Vec::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +51,7 @@ fn collect_source_files(path: &Path) -> status::Result<Vec<SourceFile>> {
|
|||||||
{
|
{
|
||||||
let entry =
|
let entry =
|
||||||
entry.with_context(|| format!("failed to read entry in {}", path.display()))?;
|
entry.with_context(|| format!("failed to read entry in {}", path.display()))?;
|
||||||
files.extend(collect_source_files(&entry.path())?);
|
files.extend(collect_source_files_with_exclusions(&entry.path(), true)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(files);
|
return Ok(files);
|
||||||
@@ -66,9 +74,7 @@ struct Args {
|
|||||||
paths: Vec<PathBuf>,
|
paths: Vec<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> status::Result<()> {
|
fn analyze(args: Args) -> status::Result<Report> {
|
||||||
let args = Args::parse();
|
|
||||||
|
|
||||||
let paths: Vec<PathBuf> = args
|
let paths: Vec<PathBuf> = args
|
||||||
.paths
|
.paths
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -83,8 +89,22 @@ fn main() -> status::Result<()> {
|
|||||||
.flatten()
|
.flatten()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let report = xatu::future_sight(files)?;
|
xatu::future_sight(files)
|
||||||
print!("{report}");
|
}
|
||||||
|
|
||||||
Ok(())
|
fn main() -> ExitCode {
|
||||||
|
match analyze(Args::parse()) {
|
||||||
|
Ok(report) if report.is_clean() => {
|
||||||
|
println!("No findings.");
|
||||||
|
ExitCode::SUCCESS
|
||||||
|
}
|
||||||
|
Ok(report) => {
|
||||||
|
print!("{report}");
|
||||||
|
ExitCode::from(1)
|
||||||
|
}
|
||||||
|
Err(error) => {
|
||||||
|
eprintln!("{error}");
|
||||||
|
ExitCode::from(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user