Skip to content
Changelog
Edit
On this page

#Changelog

#0.6.0

The documentation joins the unified site at https://smmh.dev/dirstat/, and the project describes itself consistently in its README, package documentation and manifest.

#Features

  • Documentation joins the unified site at https://smmh.dev/dirstat/, and the project describes itself consistently. The README, the docs landing page, the Go package comment and the project manifest now carry one definition of what dirstat is, and the docs site's internal cross-links resolve.

#Fixes

  • Correct version reporting. Released binaries reported a fallback version instead of the released one, because the linker's -X target named a symbol that did not exist.

#0.5.0

New --formats canonical mode: merges alias formats (mjs/js, h/c, hpp/cpp) and names extensionless scripts by their shebang interpreter.

Context

Downstream aggregation over many projects wants per-language totals, not per-spelling totals: mjs and js are one language, h belongs with c, and an extensionless script with #!/usr/bin/env -S uv run python is Python, not text/plain. The default stays raw, so existing JSON consumers see byte-identical output; canonical is opt-in via --formats or the config key.

#Features

  • Canonical format names. New --formats canonical (default raw) merges alias formats into one group -- mjs/cjs into js, h into c, hpp into cpp, text/x-python into py -- and names an extensionless script by its shebang interpreter, so a file starting with #!/usr/bin/env -S uv run python counts under py instead of text/plain. Also settable as the formats key in a --config file; raw output is unchanged.

#0.4.0

The strictcli v0.33.0 declaration regime: declared presence on every flag and argument, and a helped record per closed-set value.

Context

strictcli v0.33.0 makes presence a declaration rather than an inference and replaces bare choice values with records. dirstat's one command is read_only, so the release's other headline rule -- no framework-picked value on a command that writes -- reaches nothing here and every defaulted flag keeps its default.

Two declarations changed shape: --stats replaces Default(nil), the value-shaped spelling of optionality the framework now refuses, with Optional(), and the positional argument drops the removed ArgRequired(bool) form for ArgDefault alone. The eight closed-set flags declare one record per value with its own help, so --help and the generated flag table describe what each value does.

The scan payload is unchanged field for field, which is what the regenerated golden documents show: the only diff in them is the framework envelope's own interface_version and its new writes member.

#Breaking

  • **Breaking: machine output is now the strictcli envelope, entered with --json.** The --output table|json flag is gone; dirstat scan --json writes exactly one document to stdout — the framework envelope, whose payload member is the scan document. The document itself is unchanged except that it no longer restates dirstat_version: the envelope carries it as app_version. The command declares the payload's JSON Schema, so a deviating document fails the run instead of reaching a consumer.
  • **The machine envelope moves to interface_version 2 and gains a writes member, and --dump-schema writes schema version 2.** The scan payload is unchanged, field for field. A consumer that reads payload is unaffected; one that pins interface_version sees 2, and writes is always null here because scan writes nothing. In the dumped schema every flag and argument entry carries its presence, values publish a JSON Schema fragment under value_schema, and each choices entry carries its own help.

#Features

  • **--help describes every closed-set value, and states each flag's presence.** --method, --ignored, --hidden, --type, --sort-order, --show, --singletons and --style now render as a block with one line per value and what it does, replacing the one-line [choices: a, b] form, and every flag and the positional argument ends its line with exactly one of [required], [optional] or [default: <value>].

#0.3.0

Text/binary classification is correct again: unknown extensions are content-sniffed, empty files count as text, MIME format names stay readable, plus 17 new text extensions and a documentation site

Context

Scans of mixed trees were silently wrong. Hybrid mode treated any extension missing from the built-in text list as a binary verdict, so GDScript, Godot scenes and resources, go.mod/go.sum and text lockfiles reported no lines of code at all and were tabulated as binary; a zero-byte file was counted as binary for the same structural reason. Both defects are fixed at the classifier: a map miss now falls through to a content sniff (the extension still names the group, the content decides the class), and a zero-byte file is text under every method. The extension list also gained 17 entries so the common cases never pay for a sniff -- lock is deliberately left out, because it is TOML text for some tools and binary for others and must be judged per file.

The third fix is presentational but cost the same trust: two distinct application/* groups both rendered as applicat.. in a squeezed Format column, so the top of a large scan was unreadable without --output json. MIME names now truncate from the left, keeping the subtype.

This release also carries the previously unreleased documentation work: the Embedded Data page, generated tables of text extensions and default excludes, a schema-driven CLI reference, and a complete API reference.

#Features

  • Effect classification. Every command now declares its strictcli effect (dirstat scan is read_only), and the framework-provided --dry-run, --quiet and --verbose flags are available on every invocation.
  • 17 new text extensions. Godot's text formats (gd, gdshader, tscn, tres, godot, uid), Go's mod/sum, the shader languages (glsl, hlsl, wgsl, frag, vert) and astro/svx/prisma/odin are recognized as text without a content sniff.
  • Documentation site. A new Embedded Data page explains text/binary classification and lists every built-in text extension and default exclude as generated tables, the CLI reference is built straight from the command schema, and the specification's scan-config section is spelled out in full.

#Fixes

  • Correct text/binary classification. A file whose extension is missing from the built-in text list is now content-sniffed instead of being assumed binary, and a zero-byte file counts as text. Formats like GDScript, Godot scenes, go.mod/go.sum and text lockfiles stop reporting zero lines of code and no longer land in the Binary Files table.
  • Readable MIME format names in tables. When the Format column is squeezed, MIME-type group names keep their subtype (..n/x-sharedlib) instead of collapsing to an indistinguishable applicat.., so two different application/* groups can be told apart without switching to --output json.
  • API reference. The generated API Reference index is no longer empty and every package now carries a doc comment, so each internal package has a real reference page.

#0.2.1

Accurate error positions for config files truncated mid-value, via dependency updates.

Context

go-toml-edit v0.2.2 fixed ParseError positions for unexpected-EOF errors (previously reported as line 0, column 0), so dirstat's --config error messages are now accurate for every malformed-file shape. strictcli was bumped to v0.20.0 per the always-latest policy for internal dependencies; dirstat's CLI surface is unchanged (schema byte-identical), only the error for a pre-command --config token changed wording (strictcli's new reserved flag handling).

#Fixes

  • Config files truncated mid-value (e.g. an unclosed array at end of file) now report an accurate line/column error position instead of line 0, column 0.
  • Passing --config before the command (dirstat --config x scan) now reports --config is not available: this app does not use config files instead of unknown command '--config'. The scan --config flag is unaffected.

#0.2.0

Scan config files via --config, and curated default excludes (including .git) for fast out-of-the-box scans.

Context

Real-world use showed that scanning large project trees requires the same ~20 --exclude flags every time (node_modules, .git, caches, build output), so dirstat now ships a curated default exclude list and an explicit TOML config mechanism. The config file is never auto-discovered: it is used only when --config is passed, and setting a key both in the file and on the command line is a hard error rather than a silent override. Existing behavior (scan everything) is restored with exclude = [] or any explicit --exclude value.

#Breaking

  • Curated default excludes. --exclude now defaults to a built-in list (.git, node_modules, .venv, vendor, build, dist, target, zig-out, zig-pkg, .next, .svelte-kit, __pycache__, .mypy_cache, .ruff_cache, .pytest_cache, .hypothesis, .gradle, .idea, .wrangler, .vscode), so default scan results change: files under those directories are no longer counted. Restore the old scan-everything behavior with exclude = [] in a --config file or any explicit --exclude (which replaces the list entirely, e.g. --exclude "").

#Features

  • Scan config file. New --config <path> flag reads scan defaults (exclude, method, depth, ignored, hidden, type, stats, sort_by, sort_order) from a TOML file. The file is fully validated before scanning, never auto-discovered, and setting a key both in the file and on the command line is a hard error. The active config path is shown as the first summary line and as an additive config JSON field.

#0.1.0

Initial release: fast directory statistics with format grouping, size and LOC aggregates, colored tables, and stable JSON output.

Context

dirstat is a clean-slate Go redesign of an internal Python prototype. The rewrite eliminates all subprocesses (in-process gitignore matching and MIME sniffing), counts lines of code in parallel, and ships as a single static binary. JSON output is a stable consumer contract for downstream tooling.

#Features

  • New tool. dirstat scan summarizes the files under a directory grouped by format, with counts, sizes, and lines of code; supports ext/type/hybrid grouping, gitignore handling, hidden/exclude/depth filters, and multi-key sorting
  • Colored terminal tables with dark/light themes, unicode/ascii border styles, terminal-width adaptation, singleton collapsing, and a text/binary legend
  • Machine-readable JSON output (--output json) with a stable, additive-only schema
Search