Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
- Minimize `unwrap()` in non-test code — use proper error handling
- Prefer `#[cfg_attr(..., ignore = "reason")]` over `#[cfg(...)]` to skip tests — use `#[cfg]` on tests only when the code cannot compile under the condition (e.g., references types/functions that don't exist on other platforms)
- Install toolchain before running tests: `rustup toolchain install "$(< rust-toolchain)" && rustup component add --toolchain "$(< rust-toolchain)" rustfmt clippy`
- Run `FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh` to validate changes. If a test fails with a hint about `RUSTFLAGS` and `--cfg pdu_test_skip_*`, follow the hint and rerun with the suggested flags.
- Run `FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh` to validate changes. If a test fails with a hint about `TEST_SKIP`, follow the hint and rerun with the suggested variable.
- **ALWAYS run the full test suite** (`FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh`) before committing, regardless of how trivial the change seems — this includes documentation-only changes, comment edits, config changes, and refactors. The test suite checks formatting, linting, building, tests, and docs across multiple feature combinations; any type of change can break any of these checks.
- Set `PDU_NO_FAIL_FAST=true` to run all checks instead of stopping at the first failure — this lets you see which checks pass and which fail
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
- Minimize `unwrap()` in non-test code — use proper error handling
- Prefer `#[cfg_attr(..., ignore = "reason")]` over `#[cfg(...)]` to skip tests — use `#[cfg]` on tests only when the code cannot compile under the condition (e.g., references types/functions that don't exist on other platforms)
- Install toolchain before running tests: `rustup toolchain install "$(< rust-toolchain)" && rustup component add --toolchain "$(< rust-toolchain)" rustfmt clippy`
- Run `FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh` to validate changes. If a test fails with a hint about `RUSTFLAGS` and `--cfg pdu_test_skip_*`, follow the hint and rerun with the suggested flags.
- Run `FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh` to validate changes. If a test fails with a hint about `TEST_SKIP`, follow the hint and rerun with the suggested variable.
- **ALWAYS run the full test suite** (`FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh`) before committing, regardless of how trivial the change seems — this includes documentation-only changes, comment edits, config changes, and refactors. The test suite checks formatting, linting, building, tests, and docs across multiple feature combinations; any type of change can break any of these checks.
- Set `PDU_NO_FAIL_FAST=true` to run all checks instead of stopping at the first failure — this lets you see which checks pass and which fail
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
- Minimize `unwrap()` in non-test code — use proper error handling
- Prefer `#[cfg_attr(..., ignore = "reason")]` over `#[cfg(...)]` to skip tests — use `#[cfg]` on tests only when the code cannot compile under the condition (e.g., references types/functions that don't exist on other platforms)
- Install toolchain before running tests: `rustup toolchain install "$(< rust-toolchain)" && rustup component add --toolchain "$(< rust-toolchain)" rustfmt clippy`
- Run `FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh` to validate changes. If a test fails with a hint about `RUSTFLAGS` and `--cfg pdu_test_skip_*`, follow the hint and rerun with the suggested flags.
- Run `FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh` to validate changes. If a test fails with a hint about `TEST_SKIP`, follow the hint and rerun with the suggested variable.
- **ALWAYS run the full test suite** (`FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh`) before committing, regardless of how trivial the change seems — this includes documentation-only changes, comment edits, config changes, and refactors. The test suite checks formatting, linting, building, tests, and docs across multiple feature combinations; any type of change can break any of these checks.
- Set `PDU_NO_FAIL_FAST=true` to run all checks instead of stopping at the first failure — this lets you see which checks pass and which fail
- `gh` (GitHub CLI) is not installed — do not attempt to use it
16 changes: 4 additions & 12 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ pub enum RuntimeError {

### Conditional Test Skipping: `#[cfg]` vs `#[cfg_attr(..., ignore)]`

When a test cannot run under certain conditions (e.g., wrong platform, running as root), prefer `#[cfg_attr(..., ignore)]` over `#[cfg(...)]` to skip it. This way the test is still compiled on all configurations — catching type errors and regressions early — but simply skipped at runtime.
When a test cannot run under certain conditions (e.g., wrong platform), prefer `#[cfg_attr(..., ignore)]` over `#[cfg(...)]` to skip it. This way the test is still compiled on all configurations — catching type errors and regressions early — but simply skipped at runtime.

Use `#[cfg]` on tests **only** when the code cannot compile under the condition — for example, when the test references types, functions, or trait methods that are gated behind `#[cfg]` and do not exist on other platforms or feature sets.

Expand All @@ -231,18 +231,10 @@ fn unix_path_logic() { /* uses hardcoded unix paths but no unix-only types */ }
#[cfg(unix)]
#[test]
fn block_size() { /* uses GetBlockSize which only exists on unix */ }

// Good — test compiles with the flag, skipped at runtime
#[test]
#[cfg_attr(pdu_test_skip_some_test, ignore = "pdu_test_skip_some_test is set")]
fn some_test() { /* ... */ }

// Bad — excludes the test from compilation entirely when it could still compile
#[cfg(not(pdu_test_skip_some_test))]
#[test]
fn some_test() { /* ... */ }
```

For tests that need to be skipped based on the runtime environment (e.g., running as root), use `TEST_SKIP='test_name'` instead of custom `cfg` flags. This avoids forcing a full recompilation just to skip a test.

### Using `pipe-trait`

This codebase uses the [`pipe-trait`](https://docs.rs/pipe-trait) crate extensively. The `Pipe` trait enables method-chaining through unary functions, keeping code in a natural left-to-right reading order. Import it as `use pipe_trait::Pipe;`.
Expand Down Expand Up @@ -380,4 +372,4 @@ FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh
> Always run the full test suite before committing, even for seemingly trivial changes such as documentation edits, comment changes, or config updates. Any change can break formatting, linting, building, tests, or doc generation across the different feature combinations.

> [!NOTE]
> Some tests may fail with a hint about `RUSTFLAGS` and `--cfg pdu_test_skip_*` flags. Follow the hint and rerun with the suggested flags.
> Some tests may fail with a hint about `TEST_SKIP`. Follow the hint and rerun with the suggested variable.
3 changes: 0 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,3 @@ maplit = "1.0.2"
normalize-path = "0.2.1"
pretty_assertions = "1.4.1"
rand = "0.10.0"

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(pdu_test_skip_fs_errors)'] }
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ Environment Variables
| `TEST` | `true` or `false` | `true` | Whether to run `cargo test` |
| `BUILD_FLAGS` | string | _(empty)_ | Space-separated list of flags for `cargo build` |
| `TEST_FLAGS` | string | _(empty)_ | Space-separated list of flags for `cargo test` |
| `TEST_SKIP` | string | _(empty)_ | Space-separated list of test names to skip |

</details>

Expand Down
2 changes: 1 addition & 1 deletion template/ai-instructions/shared.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
- Minimize `unwrap()` in non-test code — use proper error handling
- Prefer `#[cfg_attr(..., ignore = "reason")]` over `#[cfg(...)]` to skip tests — use `#[cfg]` on tests only when the code cannot compile under the condition (e.g., references types/functions that don't exist on other platforms)
- Install toolchain before running tests: `rustup toolchain install "$(< rust-toolchain)" && rustup component add --toolchain "$(< rust-toolchain)" rustfmt clippy`
- Run `FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh` to validate changes. If a test fails with a hint about `RUSTFLAGS` and `--cfg pdu_test_skip_*`, follow the hint and rerun with the suggested flags.
- Run `FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh` to validate changes. If a test fails with a hint about `TEST_SKIP`, follow the hint and rerun with the suggested variable.
- **ALWAYS run the full test suite** (`FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh`) before committing, regardless of how trivial the change seems — this includes documentation-only changes, comment edits, config changes, and refactors. The test suite checks formatting, linting, building, tests, and docs across multiple feature combinations; any type of change can break any of these checks.
- Set `PDU_NO_FAIL_FAST=true` to run all checks instead of stopping at the first failure — this lets you see which checks pass and which fail
11 changes: 10 additions & 1 deletion test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,19 @@ run_if() (
unit() (
read -ra build_flags <<<"${BUILD_FLAGS:-}"
read -ra test_flags <<<"${TEST_FLAGS:-}"
read -ra test_skip <<<"${TEST_SKIP:-}"
skip_args=()
for name in ${test_skip[@]+"${test_skip[@]}"}; do
skip_args+=(--skip "$name")
done
run_if "${LINT:-true}" cargo clippy "$@" -- -D warnings
run_if "${DOC:-false}" cargo doc "$@"
run_if "${BUILD:-true}" cargo build ${build_flags[@]+"${build_flags[@]}"} "$@"
run_if "${TEST:-true}" cargo test ${test_flags[@]+"${test_flags[@]}"} "$@"
if [[ ${#skip_args[@]} -gt 0 ]]; then
run_if "${TEST:-true}" cargo test ${test_flags[@]+"${test_flags[@]}"} "$@" -- "${skip_args[@]}"
else
run_if "${TEST:-true}" cargo test ${test_flags[@]+"${test_flags[@]}"} "$@"
fi
)

run_if "${FMT:-true}" cargo fmt -- --check
Expand Down
3 changes: 1 addition & 2 deletions tests/cli_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,12 @@ fn max_depth_0() {

#[cfg(unix)]
#[test]
#[cfg_attr(pdu_test_skip_fs_errors, ignore = "pdu_test_skip_fs_errors is set")]
fn fs_errors() {
if unsafe { libc::geteuid() } == 0 {
panic!(
"{}\n{}",
"error: This test must not be run as root because running with elevated privileges would affect its accuracy.",
"hint: Either run this test as a non-root user or set `RUSTFLAGS='--cfg pdu_test_skip_fs_errors'` to skip this test.",
"hint: Either run this test as a non-root user or rerun via `TEST_SKIP='fs_errors' ./test.sh` to skip this test.",
);
}

Expand Down
Loading