From 6ec3bc17fa596413e72d38ef9077f5963d345a99 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Mon, 26 Jun 2023 05:36:52 -0400 Subject: [PATCH] feat: extension priority --- lib/mix/tasks/tableau.build.ex | 1 + lib/tableau/extension.ex | 11 +++++++-- test/mix/tasks/tableau.build_test.exs | 35 +++++++++++++++++++++------ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/lib/mix/tasks/tableau.build.ex b/lib/mix/tasks/tableau.build.ex index 5235bfe..ae34098 100644 --- a/lib/mix/tasks/tableau.build.ex +++ b/lib/mix/tasks/tableau.build.ex @@ -49,5 +49,6 @@ defmodule Mix.Tasks.Tableau.Build do match?({:ok, :pre_build}, Tableau.Extension.type(mod)) do mod end + |> Enum.sort_by(& &1.__tableau_extension_priority__()) end end diff --git a/lib/tableau/extension.ex b/lib/tableau/extension.ex index 868f437..bb95800 100644 --- a/lib/tableau/extension.ex +++ b/lib/tableau/extension.ex @@ -4,13 +4,19 @@ defmodule Tableau.Extension do An extension can be used to generate other kinds of content. + ## Types + There are currently the following extension types: - `:pre_build` - executed before tableau builds your site and writes anything to disk. + ## Priority + + Extensions can be assigned a numeric priority for used with sorting. + ```elixir defmodule MySite.PostsExtension do - use Tableau.Extension, type: :pre_build + use Tableau.Extension, type: :pre_build, priority: 300 def run(_site) do posts = Path.wildcard("_posts/**/*.md") @@ -37,11 +43,12 @@ defmodule Tableau.Extension do @callback run(map()) :: :ok | :error defmacro __using__(opts) do - opts = Keyword.validate!(opts, [:type]) + opts = Keyword.validate!(opts, [:type, :priority]) prelude = quote do def __tableau_extension_type__, do: unquote(opts)[:type] + def __tableau_extension_priority__, do: unquote(opts)[:priority] || 0 end postlude = diff --git a/test/mix/tasks/tableau.build_test.exs b/test/mix/tasks/tableau.build_test.exs index b1c1233..667bd80 100644 --- a/test/mix/tasks/tableau.build_test.exs +++ b/test/mix/tasks/tableau.build_test.exs @@ -1,16 +1,17 @@ defmodule Mix.Tasks.Tableau.LogExtension do - use Tableau.Extension, type: :pre_build + use Tableau.Extension, type: :pre_build, priority: 200 def run(_site) do - IO.puts("hi!") + IO.inspect(System.monotonic_time(), label: "second") :ok end end defmodule Mix.Tasks.Tableau.FailExtension do - use Tableau.Extension, type: :pre_build + use Tableau.Extension, type: :pre_build, priority: 100 def run(_site) do + IO.inspect(System.monotonic_time(), label: "first") :error end end @@ -109,11 +110,29 @@ defmodule Mix.Tasks.Tableau.BuildTest do @tag :tmp_dir test "renders all pages", %{tmp_dir: out} do - assert capture_io(fn -> - assert capture_log(fn -> - _documents = Build.run(["--out", out]) - end) =~ "FailExtension failed to run" - end) =~ "hi!" + {log, io} = + with_io(fn -> + {_, log} = + with_log(fn -> + _documents = Build.run(["--out", out]) + end) + + log + end) + + assert [{"first", first}, {"second", second}] = + io + |> String.split("\n", trim: true) + |> Enum.map(fn line -> + [order, time] = + Regex.run(~r/^(first|second): (.*)$/, line, capture: :all_but_first) + + {order, String.to_integer(time)} + end) + + assert first < second + + assert log =~ "FailExtension failed to run" assert File.exists?(Path.join(out, "/index.html")) assert File.exists?(Path.join(out, "/about/index.html"))