# Auto-Generated Man Pages This document explains how man pages are automatically generated from the CLI definitions using `clap` and `clap_mangen`. ## Overview Starting from version 1.50.0+, socktop uses **clap** for CLI parsing and **clap_mangen** to automatically generate man pages at build time. This approach has several advantages: ✅ Man pages are always in sync with the actual CLI ✅ Single source of truth (CLI definitions) ✅ No manual maintenance of separate man page files ✅ Generated during `cargo build` automatically ✅ Can be installed alongside binaries ## How It Works ### 1. CLI Definitions Both `socktop` and `socktop_agent` use clap's derive macros to define their CLI: - **`socktop/src/cli.rs`** - Client CLI definition - **`socktop_agent/src/cli.rs`** - Agent CLI definition These files use clap's attributes to specify: - Arguments and options - Help text and descriptions - Value names and types - Environment variable support - Hidden options (for testing) ### 2. Build-Time Generation Each crate has a `build.rs` script that: 1. Includes the CLI definition file 2. Uses `clap_mangen` to generate the man page 3. Saves it to `$OUT_DIR/man/*.1` The generation happens automatically during: ```bash cargo build cargo build --release cargo install ``` ### 3. Generated Man Pages Location After building, man pages are located at: ``` target/debug/build/socktop-*/out/man/socktop.1 target/debug/build/socktop_agent-*/out/man/socktop_agent.1 # Or for release builds: target/release/build/socktop-*/out/man/socktop.1 target/release/build/socktop_agent-*/out/man/socktop_agent.1 ``` ## Installation Options ### Option 1: Use the Installation Script (Recommended) The `scripts/install-with-man.sh` script builds the binaries, extracts the generated man pages, and installs everything: ```bash # User installation (no sudo) ./scripts/install-with-man.sh # System-wide installation (requires sudo) sudo ./scripts/install-with-man.sh --system # Only install man pages (after building) ./scripts/install-with-man.sh --man-only ``` This script: - Builds the project in release mode - Extracts generated man pages from `OUT_DIR` - Installs binaries to `~/.cargo/bin` or `/usr/local/bin` - Installs man pages to `~/.local/share/man/man1` or `/usr/local/share/man/man1` ### Option 2: Manual Installation After Build ```bash # Build the project cargo build --release # Find generated man pages SOCKTOP_MAN=$(find target/release/build/socktop-*/out/man/socktop.1 | head -1) AGENT_MAN=$(find target/release/build/socktop_agent-*/out/man/socktop_agent.1 | head -1) # Install to user directory mkdir -p ~/.local/share/man/man1 cp "$SOCKTOP_MAN" ~/.local/share/man/man1/ cp "$AGENT_MAN" ~/.local/share/man/man1/ # Or install system-wide sudo mkdir -p /usr/local/share/man/man1 sudo cp "$SOCKTOP_MAN" /usr/local/share/man/man1/ sudo cp "$AGENT_MAN" /usr/local/share/man/man1/ sudo mandb # Update man database ``` ### Option 3: View Without Installing You can view the generated man pages directly: ```bash # After building man -l $(find target/release/build/socktop-*/out/man/socktop.1 | head -1) man -l $(find target/release/build/socktop_agent-*/out/man/socktop_agent.1 | head -1) ``` ## Viewing Installed Man Pages After installation: ```bash man socktop man socktop_agent ``` If `man socktop` doesn't work after user installation, add to your shell rc: ```bash # For bash echo 'export MANPATH="$HOME/.local/share/man:$MANPATH"' >> ~/.bashrc source ~/.bashrc # For zsh echo 'export MANPATH="$HOME/.local/share/man:$MANPATH"' >> ~/.zshrc source ~/.zshrc ``` ## Updating CLI and Man Pages When you need to update the CLI or man pages: 1. **Edit the CLI definition** in `src/cli.rs`: ```rust /// Your new option description #[arg(short = 'x', long = "example")] pub example: bool, ``` 2. **Rebuild** to regenerate man pages: ```bash cargo build --release ``` 3. **Reinstall** man pages: ```bash ./scripts/install-with-man.sh --man-only ``` The man pages will automatically reflect your changes! ## CLI Definition Format ### Basic Structure ```rust use clap::Parser; #[derive(Parser, Debug)] #[command( name = "myapp", version, author, about = "Short description", long_about = "Longer description that appears in man page and --help" )] pub struct Cli { /// Short description of this option /// /// Longer description that appears in the man page. /// Can span multiple lines. #[arg(short = 't', long = "thing", value_name = "VALUE")] pub thing: Option, /// Boolean flag #[arg(long)] pub flag: bool, /// Hidden option (won't appear in man page or --help) #[arg(long, hide = true)] pub secret: bool, } ``` ### Environment Variable Support ```rust /// Port to listen on /// /// Can also be set via MYAPP_PORT environment variable. #[arg(short = 'p', long = "port", env = "MYAPP_PORT")] pub port: Option, ``` ### Value Parsing ```rust /// Custom parser #[arg(long, value_parser = parse_custom)] pub custom: Option, fn parse_custom(s: &str) -> Result { // Custom validation logic Ok(s.to_string()) } ``` ## Advantages Over Manual Man Pages | Feature | Auto-Generated | Manual | |---------|---------------|--------| | Always in sync with CLI | ✅ Yes | ❌ Manual updates required | | Single source of truth | ✅ Yes | ❌ Duplicated info | | Maintenance effort | ✅ Low | ❌ High | | Consistency | ✅ Guaranteed | ❌ Can drift | | Generated at build time | ✅ Yes | ❌ Separate process | | Works with `--help` | ✅ Same source | ❌ Separate | | Rich formatting | ⚠️ Good | ✅ Full control | ## Comparison with Manual Man Pages The project also includes manually written man pages in `docs/man/` for comparison and as templates. These are more detailed and include additional sections like: - EXAMPLES with complex scenarios - SECURITY CONSIDERATIONS - PLATFORM NOTES - Systemd integration guides - Troubleshooting tips The auto-generated man pages from clap are excellent for: - Options and arguments - Basic descriptions - Version and author info - Environment variables But may be limited for: - Complex examples - Extensive narrative documentation - Custom formatting - Additional reference sections ## Best Practices 1. **Write good doc comments** in `cli.rs` - they become man page content 2. **Use `long_about`** for detailed descriptions 3. **Specify `value_name`** for clarity (e.g., ``, ``) 4. **Document environment variables** in the option description 5. **Use `hide = true`** for internal/test options 6. **Keep descriptions concise** but informative 7. **Rebuild after CLI changes** to update man pages ## Testing Man Page Generation ```bash # Clean build to ensure regeneration cargo clean # Build and check for man page warning cargo build --release 2>&1 | grep "Man page generated" # View the generated man page man -l $(find target/release/build/socktop-*/out/man/socktop.1 | head -1) # Check for errors lexgrog $(find target/release/build/socktop-*/out/man/socktop.1 | head -1) ``` ## Troubleshooting ### Man page not generated **Solution:** Check that `build.rs` ran successfully: ```bash cargo clean cargo build -vv 2>&1 | grep build.rs ``` ### Can't find generated man page **Solution:** Look in the correct build output: ```bash find target -name "socktop.1" -type f ``` ### Man page content is outdated **Solution:** Clean and rebuild: ```bash cargo clean cargo build --release ``` ### MANPATH not working **Solution:** Verify the path is correct: ```bash echo $MANPATH man -w # Show current man paths ``` ## Future Enhancements Potential improvements: - [ ] Add more detailed examples section using clap's `after_help` - [ ] Generate shell completions alongside man pages - [ ] Create a custom man page template with additional sections - [ ] Package man pages in release artifacts - [ ] Auto-install man pages during `cargo install` ## See Also - [clap documentation](https://docs.rs/clap/) - [clap_mangen documentation](https://docs.rs/clap_mangen/) - [Manual man pages](man/README.md) - The original manually written versions - [Quick Reference](QUICK_REFERENCE.md) - Command cheat sheet