• Operand
  • license? go ahead.

gram: op

> ./lib/op/issue.ex

Lenses
(coming soon!)


defmodule Op.Issue do
  defstruct [
    :key,
    :composer,
    :name,
    :addresses,
    :body,
    :labels,
    :day,
    :summary,
    :public,
    :sequence,
    :id,
  ]

  # @enforce_keys [
  #   :key,
  #   :body,
  #   :day,
  #   :id,
  # ]

  def address, do: "priv/issue/*.md"

  def read(node = [_,_,_]), do: read(node, 0)
  def read([clock, key, node], sequence) do
    {:ok, angles, body} = node |> YamlFrontMatter.parse_file
    #"issue/2024-06-21.nushell.macro.md"

    links = for address <- (angles["addresses"] || []) do case address do
      %{ "hub" => %{ "org" => o, "base" => b, "number" => n } } ->
        "* [//ghub:#{o}/#{b}##{n}](https://github.com/#{o}/#{b}/issues/#{n})"
      _ -> nil
    end end # |> IO.inspect(label: "links")

    _measures = for address <- (angles["addresses"] || []) do case address do
      %{ "hub" => %{ org: o, base: b, number: n } } ->
          ["github.com", (nu "http get 'https://api.github.com/#{o}/#{b}/issues/#{n}'")]
      _ -> []
    end end

    struct!(__MODULE__, %{
      key: key, id: key, sequence: sequence,
      day: clock, body: body, public: true, summary: (links |> Enum.join("\n")),
    } |> Map.merge(
      for {key, shape} <- angles, into: %{}, do: { key |> String.to_atom, shape }
    ))
  end

  def summarize(issue) do
    if (issue.summary |> String.length > 0), do: issue.summary, else: issue.body
  end

  def nu _code do
    [ null: nil ]
  end

  defmodule NotFoundError, do: defexception [:message, plug_status: 404]

  def address(), do: "priv/issue/*.md"
  def query() do query(true) end
  def query(require_public) do
    Application.app_dir(:op, address())
    |> Path.wildcard
    |> Enum.map(&parse/1)
    |> Enum.sort_by(&hd/1)
    |> Enum.reverse
    |> Enum.map(&read/1)
    |> Enum.filter(& if require_public, do: &1.public, else: true)
    |> Enum.with_index
    |> Enum.map(fn {node, n} -> %{node | sequence: n} end)
  end

  def query_by_key!(key) do
    Enum.find(query(), &(&1.key == key)) ||
      raise NotFoundError, "no page uses key `#{key}`."
  end

  def query_by_label!(label) do
    case Enum.filter(query(), &(label in &1.labels)) do
      [] -> raise NotFoundError, "No pages are labeled `#{label}`."
      pages -> pages
    end
  end

  def parse(node) do
    [clock, key] = node
    |> Path.rootname
    |> Path.split
    |> List.last
    |> String.split(".", parts: 2)
    [clock, key, node]
  end

end