Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
4036c8f
feat(man): add man page generation using clap_mangen
claude Mar 27, 2026
35dbf94
refactor(man): rename EXTRA section to EXAMPLES and extract render fu…
claude Mar 28, 2026
1fa57cc
fix(man): clean up EXAMPLES section formatting
claude Mar 28, 2026
ed7181b
refactor(man): replace clap_mangen with custom roff implementation
claude Mar 28, 2026
8cca41e
refactor(man): remove cli-man feature, gate on cli instead
claude Mar 28, 2026
bdd1451
feat: generate rendered man page
KSXGitHub Mar 28, 2026
5c77ef2
feat(man): add check/generate CLI with roff and man subcommands
claude Mar 28, 2026
8ac426b
fix(man): always ignore man sync test instead of feature-gating
claude Mar 28, 2026
a9facf0
style(man): fix minor code style issues
claude Mar 28, 2026
debfc02
feat(man): re-enable man sync test with runtime dependency check
claude Mar 28, 2026
434c0bc
chore: update `pdu.1.man`
KSXGitHub Mar 28, 2026
9814ffd
feat(man): use groff directly for deterministic man page rendering
claude Mar 28, 2026
3aea3d5
chore: update `pdu.1.man`
KSXGitHub Mar 28, 2026
cf9c581
fix(man): ignore man sync test on non-Linux platforms
claude Mar 28, 2026
ae6b848
refactor(man): write files directly in generate subcommand
claude Mar 28, 2026
0d707e5
fix(man): fix groff UTF-8 handling and strip ANSI escapes
claude Mar 28, 2026
c5b9190
chore: update `pdu.1.man`
KSXGitHub Mar 28, 2026
2f8d907
fix(man): strip grotty backspace overstrikes from groff output
claude Mar 28, 2026
6980273
chore: update `pdu.1.man`
KSXGitHub Mar 28, 2026
e5eae1d
fix(man): suppress groff formatting via grotty flags and GROFF_NO_SGR
claude Mar 28, 2026
b12de32
fix(man): simplify groff invocation to match working command
claude Mar 28, 2026
a785d0a
chore: update `pdu.1.man`
KSXGitHub Mar 28, 2026
8d881d0
chore(git): pull
KSXGitHub Mar 28, 2026
527a375
chore(git): revert incorrect simplification
KSXGitHub Mar 28, 2026
0ba4adf
fix(man): match exact groff invocation used to generate pdu.1.man
claude Mar 28, 2026
7a16661
refactor(man): simplify to just pdu.1 roff file
claude Mar 28, 2026
c2bb61e
fix(man): add man page to bin PKGBUILD source and checksums
claude Mar 28, 2026
bf60d05
refactor: reduce closure
KSXGitHub Mar 28, 2026
509924a
refactor: break a line
KSXGitHub Mar 28, 2026
d0d11f3
refactor: invert `if`
KSXGitHub Mar 28, 2026
2486e7e
feat(man): replace possible values list with flag-value pairs
claude Mar 28, 2026
aa3059b
feat(man): bidirectional conflicts with user-facing wording
claude Mar 28, 2026
0c633ff
fix(man): indent conflict paragraph under its option
claude Mar 28, 2026
b708c40
docs: remove unnecessary comment
KSXGitHub Mar 28, 2026
1d325a3
fix(man): use plain space to join value placeholders; use cfg_attr fo…
Copilot Mar 28, 2026
81bcade
refactor: functional style, some micro optimizations
KSXGitHub Mar 28, 2026
58af45b
refactor: use `Vec::from_iter`
KSXGitHub Mar 28, 2026
2a99e36
chore(git): merge from master
KSXGitHub Mar 28, 2026
d901315
refactor: more functional
KSXGitHub Mar 28, 2026
2641238
fix(man): escape default values in roff and fix .TH field order
claude Mar 28, 2026
cb4dbb6
fix(man): remove empty date field from .TH header
claude Mar 28, 2026
918f7cb
fix(man): add ellipsis for multi-value positional arguments
claude Mar 28, 2026
d52a240
style(man): rename misleading closure parameter from `arg` to `alias`
claude Mar 28, 2026
4f3978a
fix(man): exclude hidden args from conflict map
claude Mar 28, 2026
f22810c
fix(man): clear need_paragraph unconditionally on non-empty lines
claude Mar 28, 2026
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
10 changes: 10 additions & 0 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,16 @@ jobs:
asset_name: completion.elv
asset_content_type: text/plain

- name: Upload Man Page
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create_release.outputs.upload_url }}
asset_path: ./exports/pdu.1
asset_name: pdu.1
asset_content_type: text/plain
Comment thread
KSXGitHub marked this conversation as resolved.

upload_release_assets:
name: Upload Release Assets

Expand Down
17 changes: 17 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ name = "pdu-completions"
path = "cli/completions.rs"
required-features = ["cli-completions"]

[[bin]]
name = "pdu-man-page"
path = "cli/man_page.rs"
required-features = ["cli-man"]

Comment thread
KSXGitHub marked this conversation as resolved.
[[bin]]
name = "pdu-usage-md"
path = "cli/usage_md.rs"
Expand All @@ -59,12 +64,14 @@ default = ["cli"]
json = ["serde/derive", "serde_json"]
cli = ["clap/derive", "clap_complete", "clap-utilities", "json"]
cli-completions = ["cli"]
cli-man = ["cli", "clap_mangen"]
ai-instructions = ["clap/derive"]

[dependencies]
assert-cmp = "0.3.0"
clap = { version = "4.5.60", optional = true }
clap_complete = { version = "4.5.66", optional = true }
clap_mangen = { version = "0.2.27", optional = true }
clap-utilities = { version = "0.3.0", optional = true }
dashmap = "6.1.0"
derive_more = { version = "2.1.1", features = ["full"] }
Expand Down
15 changes: 15 additions & 0 deletions cli/man_page.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use parallel_disk_usage::man_page::render_man_page;
use std::process::ExitCode;

fn main() -> ExitCode {
match render_man_page() {
Ok(content) => {
print!("{content}");
ExitCode::SUCCESS
}
Err(error) => {
eprintln!("error: {error}");
ExitCode::FAILURE
}
}
}
136 changes: 136 additions & 0 deletions exports/pdu.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH pdu 1 "pdu 0.21.1"
Comment thread
KSXGitHub marked this conversation as resolved.
Outdated
.SH NAME
pdu \- Summarize disk usage of the set of files, recursively for directories.
.SH SYNOPSIS
\fBpdu\fR [\fB\-\-json\-input\fR] [\fB\-\-json\-output\fR] [\fB\-b\fR|\fB\-\-bytes\-format\fR] [\fB\-H\fR|\fB\-\-deduplicate\-hardlinks\fR] [\fB\-x\fR|\fB\-\-one\-file\-system\fR] [\fB\-\-top\-down\fR] [\fB\-\-align\-right\fR] [\fB\-q\fR|\fB\-\-quantity\fR] [\fB\-d\fR|\fB\-\-max\-depth\fR] [\fB\-w\fR|\fB\-\-total\-width\fR] [\fB\-\-column\-width\fR] [\fB\-m\fR|\fB\-\-min\-ratio\fR] [\fB\-\-no\-sort\fR] [\fB\-s\fR|\fB\-\-silent\-errors\fR] [\fB\-p\fR|\fB\-\-progress\fR] [\fB\-\-threads\fR] [\fB\-\-omit\-json\-shared\-details\fR] [\fB\-\-omit\-json\-shared\-summary\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fIFILES\fR]
.SH DESCRIPTION
Summarize disk usage of the set of files, recursively for directories.
.PP
Copyright: Apache\-2.0 © 2021 Hoàng Văn Khải <https://github.com/KSXGitHub/>
Sponsor: https://github.com/sponsors/KSXGitHub
.SH OPTIONS
.TP
\fB\-\-json\-input\fR
Read JSON data from stdin
.TP
\fB\-\-json\-output\fR
Print JSON data instead of an ASCII chart
.TP
\fB\-b\fR, \fB\-\-bytes\-format\fR \fI<BYTES_FORMAT>\fR [default: metric]
How to display the numbers of bytes
.br

.br
\fIPossible values:\fR
.RS 14
.IP \(bu 2
plain: Display plain number of bytes without units
.IP \(bu 2
metric: Use metric scale, i.e. 1K = 1000B, 1M = 1000K, and so on
.IP \(bu 2
binary: Use binary scale, i.e. 1K = 1024B, 1M = 1024K, and so on
.RE
.TP
\fB\-H\fR, \fB\-\-deduplicate\-hardlinks\fR
Detect and subtract the sizes of hardlinks from their parent directory totals
.TP
\fB\-x\fR, \fB\-\-one\-file\-system\fR
Skip directories on different filesystems
.TP
\fB\-\-top\-down\fR
Print the tree top\-down instead of bottom\-up
.TP
\fB\-\-align\-right\fR
Set the root of the bars to the right
.TP
\fB\-q\fR, \fB\-\-quantity\fR \fI<QUANTITY>\fR [default: block\-size]
Aspect of the files/directories to be measured
.br

.br
\fIPossible values:\fR
.RS 14
.IP \(bu 2
apparent\-size: Measure apparent sizes
.IP \(bu 2
block\-size: Measure block sizes (block\-count * 512B)
.IP \(bu 2
block\-count: Count numbers of blocks
.RE
.TP
\fB\-d\fR, \fB\-\-max\-depth\fR \fI<MAX_DEPTH>\fR [default: 10]
Maximum depth to display the data. Could be either "inf" or a positive integer
.TP
\fB\-w\fR, \fB\-\-total\-width\fR \fI<TOTAL_WIDTH>\fR
Width of the visualization
.TP
\fB\-\-column\-width\fR \fI<TREE_WIDTH>\fR\fI \fR\fI<BAR_WIDTH>\fR
Maximum widths of the tree column and width of the bar column
.TP
\fB\-m\fR, \fB\-\-min\-ratio\fR \fI<MIN_RATIO>\fR [default: 0.01]
Minimal size proportion required to appear
.TP
\fB\-\-no\-sort\fR
Do not sort the branches in the tree
.TP
\fB\-s\fR, \fB\-\-silent\-errors\fR
Prevent filesystem error messages from appearing in stderr
.TP
\fB\-p\fR, \fB\-\-progress\fR
Report progress being made at the expense of performance
.TP
\fB\-\-threads\fR \fI<THREADS>\fR [default: auto]
Set the maximum number of threads to spawn. Could be either "auto", "max", or a positive integer
.TP
\fB\-\-omit\-json\-shared\-details\fR
Do not output `.shared.details` in the JSON output
.TP
\fB\-\-omit\-json\-shared\-summary\fR
Do not output `.shared.summary` in the JSON output
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help (see a summary with \*(Aq\-h\*(Aq)
.TP
\fB\-V\fR, \fB\-\-version\fR
Print version
.TP
[\fIFILES\fR]
List of files and/or directories
.SH EXAMPLES
Examples:
Comment thread
KSXGitHub marked this conversation as resolved.
Outdated
Show disk usage chart of current working directory
$ pdu

Show disk usage chart of a single file or directory
$ pdu path/to/file/or/directory

Compare disk usages of multiple files and/or directories
$ pdu file.txt dir/

Show chart in apparent sizes instead of block sizes
$ pdu \-\-quantity=apparent\-size

Detect and subtract the sizes of hardlinks from their parent nodes
$ pdu \-\-deduplicate\-hardlinks

Show sizes in plain numbers instead of metric units
$ pdu \-\-bytes\-format=plain

Show sizes in base 2¹⁰ units (binary) instead of base 10³ units (metric)
$ pdu \-\-bytes\-format=binary

Show disk usage chart of all entries regardless of size
$ pdu \-\-min\-ratio=0

Only show disk usage chart of entries whose size is at least 5% of total
$ pdu \-\-min\-ratio=0.05

Show disk usage data as JSON instead of chart
$ pdu \-\-min\-ratio=0 \-\-max\-depth=inf \-\-json\-output | jq

Visualize existing JSON representation of disk usage data
$ pdu \-\-json\-input < disk\-usage.json
Comment thread
KSXGitHub marked this conversation as resolved.
Outdated
.SH VERSION
v0.21.1
1 change: 1 addition & 0 deletions generate-completions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ gen elvish completion.elv
./run.sh pdu --help | sed 's/[[:space:]]*$//' > exports/long.help
./run.sh pdu -h | sed 's/[[:space:]]*$//' > exports/short.help
./run.sh pdu-usage-md > USAGE.md
./run.sh pdu-man-page > exports/pdu.1
2 changes: 1 addition & 1 deletion run.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#! /bin/bash
set -o errexit -o pipefail -o nounset
exec cargo run --bin="$1" --features cli-completions,ai-instructions -- "${@:2}"
exec cargo run --bin="$1" --features cli-completions,cli-man,ai-instructions -- "${@:2}"
Comment thread
KSXGitHub marked this conversation as resolved.
Outdated
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub use serde_json;
pub mod app;
#[cfg(feature = "cli")]
pub mod args;
#[cfg(feature = "cli-man")]
pub mod man_page;
#[cfg(feature = "cli")]
pub mod runtime_error;
#[cfg(feature = "cli")]
Expand Down
15 changes: 15 additions & 0 deletions src/man_page.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use crate::args::Args;
use clap::CommandFactory;
use clap_mangen::Man;
use std::io;

/// Renders the man page for `pdu` as a string.
pub fn render_man_page() -> io::Result<String> {
let command = Args::command();
let man = Man::new(command);
let mut buffer = Vec::new();
man.render(&mut buffer)?;
let content = String::from_utf8(buffer)
.map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;
Ok(content.replace("\n.SH EXTRA\n", "\n.SH EXAMPLES\n"))
}
1 change: 1 addition & 0 deletions template/parallel-disk-usage-bin/PKGBUILD
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ package() {
install -Dm644 "completion.$pkgver.bash" "$pkgdir/usr/share/bash-completion/completions/pdu"
install -Dm644 "completion.$pkgver.fish" "$pkgdir/usr/share/fish/completions/pdu.fish"
install -Dm644 "completion.$pkgver.zsh" "$pkgdir/usr/share/zsh/site-functions/_pdu"
install -Dm644 "pdu.$pkgver.1" "$pkgdir/usr/share/man/man1/pdu.1"
}
1 change: 1 addition & 0 deletions template/parallel-disk-usage/PKGBUILD
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ package() {
install -Dm644 exports/completion.bash "$pkgdir/usr/share/bash-completion/completions/pdu"
install -Dm644 exports/completion.fish "$pkgdir/usr/share/fish/completions/pdu.fish"
install -Dm644 exports/completion.zsh "$pkgdir/usr/share/zsh/site-functions/_pdu"
install -Dm644 exports/pdu.1 "$pkgdir/usr/share/man/man1/pdu.1"
}
1 change: 1 addition & 0 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ unit --no-default-features "$@"
unit --all-features "$@"
unit --features cli "$@"
unit --features cli-completions "$@"
unit --features cli-man "$@"
unit --features ai-instructions "$@"

if [[ -f "$failure_marker" ]]; then
Expand Down
20 changes: 20 additions & 0 deletions tests/sync_man_page.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//! The following test checks whether the man page file is outdated.
//!
//! If the test fails, run `./generate-completions.sh` on the root of the repo to update the man page.

// Since the CLI in Windows looks a little different, and I am way too lazy to make two versions
// of man page files, the following test would only run in UNIX-like environment.
#![cfg(unix)]
#![cfg(feature = "cli-man")]

use parallel_disk_usage::man_page::render_man_page;

#[test]
fn man_page() {
let received = render_man_page().expect("render man page");
let expected = include_str!("../exports/pdu.1");
assert!(
received == expected,
Comment thread
KSXGitHub marked this conversation as resolved.
Comment thread
KSXGitHub marked this conversation as resolved.
"man page is outdated, run ./generate-completions.sh to update it",
);
}
Loading