• Operand
  • ./bin/ganged/upon.

gram: op

> ./lib/source.ex

Lenses
(coming soon!)


# 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
  def any(base) do
    base |> Path.absname |> File.ls!
    |> Enum.filter(& File.exists?(base <> &1 <> "/.git"))
  end

  def nodes(base, address \\ nil) do
    index = Git.new(base) |> Git.ls_files() |> elem(1) |> String.trim |> String.split("\n")
    case address do
      "~" <> a -> index |> Enum.filter(fn n -> String.contains?(n, a) end)
      "" <> a -> index |> Enum.find(fn n -> n == a end)
      _ -> index
    end |> Enum.map(& %Source.Node{
      base: base, label: "main", address: &1,
    })
  end

  def changes(base) do
    log = Git.new(base) |> Git.log([
      "--format=format:%h %G? (%ai) %aN: %s %d",
      "--abbrev-commit",
      "--date=relative",
    ]) |> elem(1) |> String.trim |> String.split("\n")

    # parse!
    log |> Enum.map(fn ln ->
      [hash, _signed, "("<>day, clock, zone | message ] = ln |> String.split(" ")
      [ _composer | message ] = message |> Enum.join(" ") |> String.split(":")
      message =  (message |> Enum.join(":"))
      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

      [ hash, day, clock, zone, labels, message ]
    end)
  end

  def measure(base, address, branch \\ "main") do
    case Git.new(base) |> Git.cat_file(["blob", "#{branch}:#{address}"]) do
      {:error, response } -> response.message |> IO.inspect(label: "Error reading node")
      {:ok, blob } -> blob
    end
  end

end

# more graph flags:
  # https://mermaid.js.org/syntax/gitgraph.html
    # "--graph",
  # colors:
    # "--format=format:%C(red)%h %G?%C(reset) %C(cyan)(%ai)%C(reset) %C(yellow)%aN:%C(reset) %s %C(blue)%d%C(reset)",
      # "--all",
  # def graph(base) do
  # end