# A generic module able to read change-logged sources; # can be rendered as machine-compilable code, # essay pages, or in numerous unique schemas. defmodule Source do @cache false @local true def any(bases) do loci(bases) |> Enum.map(&Path.basename/1) end def loci(bases) do bases |> Enum.filter(& File.exists?( Path.join([&1, ".git"]) )) end def nodes(base, address \\ ~r/.*/) do case Git.new(base) |> Git.ls_files() do {:ok, nodes } -> nodes |> String.trim |> String.split("\n") |> Enum.filter(& &1 =~ address) |> Enum.map(& %Source.Node{ base: base, label: "main", address: &1, }) _ -> [] end end def changes(base) do log = Git.new(base) |> Git.log([ "--format=format:%h (%ai) %aN: %s", ]) |> elem(1) |> String.trim |> String.split("\n") # parse! log |> Enum.map(fn ln -> [hash, "("<>day, clock, zone, _composer | message ] = ln |> String.split(" ") zone = zone |> String.replace(~r/\)$/, "") # composer = composer |> String.replace(~r/:$/, "") message = message |> Enum.join(" ") ## Oh no! Parens inside a changelog mess up labels. # [message, labels] = if (message |> String.ends_with?(")")) do # [ message | [labels] ] = message |> String.split("(") # [message, labels |> String.trim_trailing(")") |> String.split(",") |> Enum.map(&String.trim/1) ] # else [message, labels] end labels = [] [ hash, day, clock, zone, labels, message ] end) end def changes_by_day(base) do changes(base) |> Enum.group_by(fn [_, day | _] -> day end) |> Enum.sort(:desc) end def measure(base, address, branch \\ "main") do [ base, address] |> Path.join cond do @cache -> "Oh no! Please encode a cache!" @local -> [ base, address] |> Path.join |> File.read! true -> case base |> Git.new |> Git.cat_file(["blob", "#{branch}:#{address}"]) do {:error, response } -> response.message |> IO.inspect(label: "Error reading node") {:ok, blob } -> blob end end end end