defmodule Mix.Tasks.Ptc.UpdateSpecChecksums do @moduledoc """ Regenerates the spec checksums file for drift detection. Reads the current PTC-Lisp specification and generates hashes for each section, storing them in `priv/spec/checksums.ex`. ## Usage mix ptc.update_spec_checksums ## Output Updates `priv/spec/checksums.ex` with current section hashes. """ use Mix.Task @shortdoc "Regenerate spec section checksums" alias PtcRunner.Lisp.SpecValidator @checksums_path "priv/spec/checksums.ex" @impl Mix.Task def run(_args) do case SpecValidator.section_hashes() do {:ok, hashes} -> case write_checksums(hashes) do :ok -> Mix.shell().info("") Mix.shell().info("✓ Updated #{@checksums_path}") Mix.shell().info(" #{map_size(hashes)} sections") Mix.shell().info("") {:error, reason} -> Mix.shell().error("Error: #{reason}") System.halt(1) end {:error, reason} -> Mix.shell().error("Error: #{reason}") System.halt(1) end end defp write_checksums(hashes) do content = format_checksums(hashes) case File.write(@checksums_path, content) do :ok -> :ok {:error, reason} -> {:error, "Could not write checksums file: #{reason}"} end end defp format_checksums(hashes) do header = "# Section hashes for spec drift detection\n# Generated by: mix ptc.update_spec_checksums\n\n%{\n" entries = hashes |> Enum.sort() |> Enum.map_join(fn {section, hash} -> " \"#{section}\" => \"#{hash}\",\n" end) footer = "}\n" header <> entries <> footer end end