aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/description.exs14
-rw-r--r--lib/pleroma/application.ex1
-rw-r--r--lib/pleroma/docs/generator.ex31
-rw-r--r--lib/pleroma/docs/json.ex21
-rw-r--r--lib/pleroma/docs/markdown.ex5
-rw-r--r--lib/pleroma/web/admin_api/controllers/config_controller.ex4
-rw-r--r--test/docs/generator_test.exs12
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,