Svelixir. Hash
(svelixir v0.11.0)
Copy Markdown
Content hashing for manifest file entries.
For .ex/.exs, normalisation is Code.string_to_quoted!/2 |> Macro.to_string/1: the parser discards comments and the printer
canonicalises whitespace, so reindentation and an added
# credo:disable-for-next-line produce the SAME hash. That is the guarantee
the whole design exists for.
Sourceror is the wrong tool and was measured: Sourceror.to_string/1
reproduces comments verbatim (they live in leading_comments/
trailing_comments metadata), and Sourceror.Comments.extract_comments/1
also fails, because removing a comment node removes its previous_eol_count
and changes blank-line rendering. Hashing the AST term directly
(:erlang.term_to_binary/1, :erlang.phash2/1, inspect/1) is likewise
wrong: line: metadata SHIFTS when comments are added. The
comment-insensitivity comes from Macro.to_string/1 discarding metadata, not
from the parser.
The normalised string is a HASH INPUT ONLY
It is not guaranteed to be valid Elixir — a string literal containing both
interpolation and a \r escape is rendered with a raw carriage return that
will not re-parse — and Macro.to_string/1 is not idempotent. Never write it
to disk, never re-parse it, never re-normalise it.
Known MVP limitations
Non-Elixir files stay comment-SENSITIVE: a # added by user in a
compose.yaml DOES change its hash. Semantics-preserving literal rewrites
collide for Elixir files (0x1F vs 31, ?a vs 97, 1_000_000 vs
1000000, heredoc vs escaped string). An empty file and a comments-only file
share a hash.
Whitespace inside a multi-line sigil or heredoc is literal content, not
layout — a sigil keeps its interior verbatim and a heredoc measures its
interior against the closing delimiter — so reindenting a ~w(...) block, an
~H template or an indented code sample inside a @moduledoc DOES change the
hash. mix format preserves those interiors; a manual or editor block
reindent does not.
This module must NOT share a normaliser with Svelixir.Baseline, which
requires the opposite semantics.
Summary
Functions
Returns "sha256:" followed by 64 lowercase hex characters.
Normalises file bytes for hashing, dispatching strictly on the extension.