wssweep
A zero-config whitespace doctor. Run it on any repo and it instantly finds —
and with --fix, cleans — the whitespace problems that pollute diffs and break
across platforms: trailing whitespace, mixed CRLF/LF line endings, a missing
final newline, extra trailing blank lines, a UTF-8 BOM, lone CRs, and tabs mixed
with spaces in indentation.
pipx run wssweep
# config.yml (1)
# - mixed-eol mixed line endings (CRLF×3, LF×1)
#
# src/app.js (2)
# - missing-final-newline no newline at end of file
# 14: trailing-whitespace trailing whitespace
#
# ✖ 3 whitespace issues in 2 files (missing-final-newline=1, mixed-eol=1, trailing-whitespace=1)
pipx run wssweep --fix # clean them in place
No config file, no framework. Exits non-zero when it finds issues, so it drops
straight into CI. Pure standard library. Also on npm (npx wssweep) — the two
builds produce byte-for-byte identical output and identical fixes.
Why another whitespace tool?
Because today this takes three or four tools wired together:
- editorconfig-checker reports, but needs you to author an
.editorconfigfirst, and it can't fix anything. - pre-commit's
trailing-whitespace/end-of-file-fixer/mixed-line-endinghooks do fix — but only inside the pre-commit framework, and they're three separate hooks. Nobody runs them ad-hoc on a fresh checkout. - prettier fixes whitespace only as a side effect of reformatting all your code, is language-aware, and won't touch files it can't parse.
- dos2unix only does line endings.
wssweep is the one command — pip/npx, zero config — that reports all
seven whitespace smells at once with line numbers and optionally fixes them in
place, with a clean CI exit code, identical on Python and Node.
What it checks
| check | what | --fix |
|---|---|---|
trailing-whitespace |
space/tab at end of a line | trims it |
mixed-eol |
a file containing both CRLF and LF | normalizes to LF |
lone-cr |
a bare CR (old-Mac line ending) | normalizes |
missing-final-newline |
non-empty file not ending in a newline | appends one |
trailing-blank-lines |
extra blank line(s) at end of file | collapses to one |
utf8-bom |
a leading UTF-8 BOM | strips it |
mixed-indentation |
tabs and spaces in one indent | report-only (needs your tab width) |
Opinionated, zero-config defaults: a consistently-CRLF file is fine (only
mixed endings are flagged), .bat/.cmd keep CRLF when fixed, and Markdown's
two-trailing-spaces hard line break is preserved (trailing-whitespace is skipped
in .md).
Usage
wssweep # scan the current directory
wssweep src/ docs/ # scan specific paths
wssweep --fix # fix in place (atomic; only files that change)
wssweep --crlf --fix # normalize endings to CRLF instead of LF
wssweep --skip=mixed-indentation # turn off a check
wssweep --exclude='*.min.js' # skip paths by glob (repeatable)
wssweep --json # machine output (byte-identical both builds)
.git, node_modules, dist, build, vendor, .venv and friends are
skipped by default, as are binary files (detected by extension + a NUL-byte /
non-UTF-8 content check) and files over 5 MB. --all overrides those skips.
Exit codes: 0 clean · 1 issues found · 2 error. (--fix exits 0 once
everything fixable is fixed; a leftover mixed-indentation keeps it 1.)
How it works
It reads every file as raw bytes and scans a byte-faithful (latin-1) view, so
it never mangles encodings and the Python and Node builds agree to the byte: line
endings are classified from the bytes (never splitlines, which over-splits),
"whitespace" means exactly space and tab (never \s, which differs across
languages), and --fix writes raw bytes atomically (temp file + rename),
touching only files that actually change and preserving file modes. Fixing is
idempotent — run it twice, the second run does nothing.
Install
pip install wssweep # or pipx run wssweep
npm i -g wssweep # Node build, identical behaviour
Python ≥ 3.8 or Node ≥ 18. No dependencies.
License
MIT
Release files for wssweep 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| wssweep-0.1.0.tar.gz | 13.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wssweep-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size:25.4 kB
Release files / wssweep-0.1.0.tar.gz
| Download URL | wssweep-0.1.0.tar.gz |
|---|---|
| Size | 13.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
587cede635bc43f91d69628ecfb3117037152b496265e5e59b8f27b09c63c597
|
|
BLAKE2b-256 checksum How to use checksums |
af2aa0a12a27dfb9ef19440016e678095f15e31d6b8a6406b1ae04f7c1d3f8e0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.7
|
Release files / wssweep-0.1.0-py3-none-any.whl
| Download URL | wssweep-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
51b15adc3c3162e6cdd516cff8e9affc13a25a2cd3e7984ca7740c8917f1a025
|
|
BLAKE2b-256 checksum How to use checksums |
804157735a5bd7dae6e6d39e635c20d0f18604b20211ccbacb517536da8a595d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.7
|