Packages

fnord

0.9.24

AI code archaeology

Current section

Files

Jump to
fnord lib store project entry metadata.ex
Raw

lib/store/project/entry/metadata.ex

defmodule Store.Project.Entry.Metadata do
defstruct [:store_path, :source_file]
@filename "metadata.json"
@behaviour Store.Project.EntryFile
@impl Store.Project.EntryFile
def new(entry_path, source_file) do
%__MODULE__{
store_path: Path.join(entry_path, @filename),
source_file: source_file
}
end
@impl Store.Project.EntryFile
def exists?(file), do: file |> store_path() |> File.exists?()
@impl Store.Project.EntryFile
def store_path(file), do: file.store_path
@impl Store.Project.EntryFile
def read(file) do
file.store_path
|> File.read()
|> case do
{:ok, contents} -> SafeJson.decode(contents)
error -> error
end
end
@impl Store.Project.EntryFile
def write(file, data \\ %{}) do
data = if is_map(data), do: data, else: %{}
rel_path = Map.get(data, :rel_path) || Map.get(data, "rel_path")
# Callers that know the content hash upfront (git mode passes the blob
# SHA straight through from ls-tree) should set `hash:` in `data`.
# Otherwise we fall back to hashing the working-tree file so this
# function remains usable from test / tooling call sites that bypass
# the Source-aware save pipeline.
hash = Map.get(data, :hash) || Map.get(data, "hash") || mkhash(file.source_file)
%{
file: rel_path || file.source_file,
timestamp: DateTime.utc_now(),
hash: hash
}
|> SafeJson.encode()
|> case do
{:ok, json} -> File.write(file.store_path, json)
error -> error
end
end
defp mkhash(file) do
:crypto.hash(:sha256, File.read!(file))
|> Base.encode16(case: :lower)
end
end