A high-performance CLI tool for removing trailing whitespace from text files. Built in Rust with a focus on safety, atomicity, and zero external dependencies.
Note: This is a learning project created to study Rust, file system operations, and safe system programming practices.
- Atomic writes - Uses write-sync-rename pattern to prevent data corruption
- Permission preservation - Maintains original file permissions after processing
- Symlink protection - Ignores symlinks to prevent security issues
- Binary file detection - Automatically skips non-UTF-8 files
- Recursive processing - Process entire directory trees
- Zero dependencies - Only uses Rust standard library
# Clone the repository
git clone https://github.com/raul3k/rtrim.git
cd rtrim
# Build and install
make installPREFIX=~/.local/bin make installmake uninstall# Display help
rtrim --help
# Process a single file
rtrim --file path/to/file.txt
# Process a folder recursively
rtrim --folder path/to/folder- Reads the file content into memory
- Validates UTF-8 encoding (skips binary files)
- Removes trailing whitespace from each line
- Writes to a unique temporary file
- Syncs to disk (
fsync) - Atomically renames temp file to original
This ensures that even during a power failure, you won't end up with a corrupted file.
When processing folders recursively, the following are automatically skipped:
| Category | Directories |
|---|---|
| Version Control | .git, .svn, .hg |
| Dependencies | node_modules, target, __pycache__ |
| Virtual Environments | .venv, venv |
| IDEs | .idea, .vscode |
| Hidden | Any directory starting with . |
cargo testrtrim/
├── src/
│ └── main.rs # Main source code with unit tests
├── Cargo.toml # Rust package manifest
├── Makefile # Build and install automation
├── LICENSE # MIT License
└── README.md
- Algorithm complexity: O(N) where N is the file size
- Memory usage: Pre-allocates based on original file size
- Temporary files: Format
.{filename}.{pid}.{timestamp}.tmp - Supported platforms: Unix-like systems (Linux, macOS)
MIT License - see LICENSE for details.
This project uses Conventional Commits.
Format: <type>(<scope>): <description>
Types: feat, fix, docs, style, refactor, test, chore
Examples:
feat: add recursive folder processingfix(parser): handle empty filesdocs: update installation instructions
Git hooks are automatically configured on the first cargo build.
This project was built to learn:
- Rust ownership and borrowing
- File system operations in Rust
- Atomic file operations (write-sync-rename pattern)
- Unix file permissions and metadata
- Symlink security considerations
- Unit and integration testing in Rust
- CLI argument parsing without external crates