diff options
| -rw-r--r-- | config/description.exs | 14 | ||||
| -rw-r--r-- | lib/pleroma/application.ex | 1 | ||||
| -rw-r--r-- | lib/pleroma/docs/generator.ex | 31 | ||||
| -rw-r--r-- | lib/pleroma/docs/json.ex | 21 | ||||
| -rw-r--r-- | lib/pleroma/docs/markdown.ex | 5 | ||||
| -rw-r--r-- | lib/pleroma/web/admin_api/controllers/config_controller.ex | 4 | ||||
| -rw-r--r-- | test/docs/generator_test.exs | 12 | 
7 files changed, 47 insertions, 41 deletions
diff --git a/config/description.exs b/config/description.exs index 3b78a6613..84dcdb87e 100644 --- a/config/description.exs +++ b/config/description.exs @@ -23,18 +23,14 @@ config :pleroma, :config_description, [          key: :uploader,          type: :module,          description: "Module which will be used for uploads", -        suggestions: [Pleroma.Uploaders.Local, Pleroma.Uploaders.S3] +        suggestions: {:list_behaviour_implementations, Pleroma.Uploaders.Uploader}        },        %{          key: :filters,          type: {:list, :module},          description:            "List of filter modules for uploads. Module names are shortened (removed leading `Pleroma.Upload.Filter.` part), but on adding custom module you need to use full name.", -        suggestions: -          Generator.list_modules_in_dir( -            "lib/pleroma/upload/filter", -            "Elixir.Pleroma.Upload.Filter." -          ) +        suggestions: {:list_behaviour_implementations, Pleroma.Upload.Filter}        },        %{          key: :link_name, @@ -1405,11 +1401,7 @@ config :pleroma, :config_description, [          type: [:module, {:list, :module}],          description:            "A list of MRF policies enabled. Module names are shortened (removed leading `Pleroma.Web.ActivityPub.MRF.` part), but on adding custom module you need to use full name.", -        suggestions: -          Generator.list_modules_in_dir( -            "lib/pleroma/web/activity_pub/mrf", -            "Elixir.Pleroma.Web.ActivityPub.MRF." -          ) +        suggestions: {:list_behaviour_implementations, Pleroma.Web.ActivityPub.MRF}        },        %{          key: :transparency, diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 84f3aa82d..b68a373a4 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -42,6 +42,7 @@ defmodule Pleroma.Application do      Pleroma.ApplicationRequirements.verify!()      setup_instrumenters()      load_custom_modules() +    Pleroma.Docs.JSON.compile()      adapter = Application.get_env(:tesla, :adapter) diff --git a/lib/pleroma/docs/generator.ex b/lib/pleroma/docs/generator.ex index e0fc8cd02..a671a6278 100644 --- a/lib/pleroma/docs/generator.ex +++ b/lib/pleroma/docs/generator.ex @@ -6,16 +6,21 @@ defmodule Pleroma.Docs.Generator do      implementation.process(descriptions)    end -  @spec list_modules_in_dir(String.t(), String.t()) :: [module()] -  def list_modules_in_dir(dir, start) do -    with {:ok, files} <- File.ls(dir) do -      files -      |> Enum.filter(&String.ends_with?(&1, ".ex")) -      |> Enum.map(fn filename -> -        module = filename |> String.trim_trailing(".ex") |> Macro.camelize() -        String.to_atom(start <> module) -      end) -    end +  @spec list_behaviour_implementations(behaviour :: module()) :: [module()] +  def list_behaviour_implementations(behaviour) do +    :code.all_loaded() +    |> Enum.filter(fn {module, _} -> +      # This shouldn't be needed as all modules are expected to have module_info/1, +      # but in test enviroments some transient modules `:elixir_compiler_XX` +      # are loaded for some reason (where XX is a random integer). +      if function_exported?(module, :module_info, 1) do +        module.module_info(:attributes) +        |> Keyword.get_values(:behaviour) +        |> List.flatten() +        |> Enum.member?(behaviour) +      end +    end) +    |> Enum.map(fn {module, _} -> module end)    end    @doc """ @@ -87,6 +92,12 @@ defmodule Pleroma.Docs.Generator do        else: string    end +  defp format_suggestions({:list_behaviour_implementations, behaviour}) do +    behaviour +    |> list_behaviour_implementations() +    |> format_suggestions() +  end +    defp format_suggestions([]), do: []    defp format_suggestions([suggestion | tail]) do diff --git a/lib/pleroma/docs/json.ex b/lib/pleroma/docs/json.ex index d1cf1f487..feeb4320e 100644 --- a/lib/pleroma/docs/json.ex +++ b/lib/pleroma/docs/json.ex @@ -1,5 +1,19 @@  defmodule Pleroma.Docs.JSON do    @behaviour Pleroma.Docs.Generator +  @external_resource "config/description.exs" +  @raw_config Pleroma.Config.Loader.read("config/description.exs") +  @raw_descriptions @raw_config[:pleroma][:config_description] +  @term __MODULE__.Compiled + +  @spec compile :: :ok +  def compile do +    :persistent_term.put(@term, Pleroma.Docs.Generator.convert_to_strings(@raw_descriptions)) +  end + +  @spec compiled_descriptions :: Map.t() +  def compiled_descriptions do +    :persistent_term.get(@term) +  end    @spec process(keyword()) :: {:ok, String.t()}    def process(descriptions) do @@ -13,11 +27,4 @@ defmodule Pleroma.Docs.JSON do        {:ok, path}      end    end - -  def compile do -    with config <- Pleroma.Config.Loader.read("config/description.exs") do -      config[:pleroma][:config_description] -      |> Pleroma.Docs.Generator.convert_to_strings() -    end -  end  end diff --git a/lib/pleroma/docs/markdown.ex b/lib/pleroma/docs/markdown.ex index 68b106499..da3f20f43 100644 --- a/lib/pleroma/docs/markdown.ex +++ b/lib/pleroma/docs/markdown.ex @@ -68,6 +68,11 @@ defmodule Pleroma.Docs.Markdown do      IO.write(file, "  #{list_mark}`#{inspect(suggestion)}`\n")    end +  defp print_suggestions(file, {:list_behaviour_implementations, behaviour}) do +    suggestions = Pleroma.Docs.Generator.list_behaviour_implementations(behaviour) +    print_suggestions(file, suggestions) +  end +    defp print_suggestions(_file, nil), do: nil    defp print_suggestions(_file, ""), do: nil diff --git a/lib/pleroma/web/admin_api/controllers/config_controller.ex b/lib/pleroma/web/admin_api/controllers/config_controller.ex index 7f60470cb..0df13007f 100644 --- a/lib/pleroma/web/admin_api/controllers/config_controller.ex +++ b/lib/pleroma/web/admin_api/controllers/config_controller.ex @@ -9,8 +9,6 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do    alias Pleroma.ConfigDB    alias Pleroma.Plugs.OAuthScopesPlug -  @descriptions Pleroma.Docs.JSON.compile() -    plug(Pleroma.Web.ApiSpec.CastAndValidate)    plug(OAuthScopesPlug, %{scopes: ["write"], admin: true} when action == :update) @@ -25,7 +23,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do    defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.ConfigOperation    def descriptions(conn, _params) do -    descriptions = Enum.filter(@descriptions, &whitelisted_config?/1) +    descriptions = Enum.filter(Pleroma.Docs.JSON.compiled_descriptions(), &whitelisted_config?/1)      json(conn, descriptions)    end diff --git a/test/docs/generator_test.exs b/test/docs/generator_test.exs index 9c9f4357b..b32918a69 100644 --- a/test/docs/generator_test.exs +++ b/test/docs/generator_test.exs @@ -13,21 +13,13 @@ defmodule Pleroma.Docs.GeneratorTest do            key: :uploader,            type: :module,            description: "", -          suggestions: -            Generator.list_modules_in_dir( -              "lib/pleroma/upload/filter", -              "Elixir.Pleroma.Upload.Filter." -            ) +          suggestions: {:list_behaviour_implementations, Pleroma.Upload.Filter}          },          %{            key: :filters,            type: {:list, :module},            description: "", -          suggestions: -            Generator.list_modules_in_dir( -              "lib/pleroma/web/activity_pub/mrf", -              "Elixir.Pleroma.Web.ActivityPub.MRF." -            ) +          suggestions: {:list_behaviour_implementations, Pleroma.Web.ActivityPub.MRF}          },          %{            key: Pleroma.Upload,  | 
